Files
ReMixer/winsoundcat.cpp

281 lines
7.2 KiB
C++

#include <iostream>
#define COBJMACROS
#include <mmdeviceapi.h>
#include <audioclient.h>
int enumerate_sound_devices()
{
// Initialize COM-interface subsystem
CoInitializeEx(NULL, 0);
IMMDeviceEnumerator *enu;
const GUID _CLSID_MMDeviceEnumerator = {0xbcde0395, 0xe52f, 0x467c, {0x8e,0x3d, 0xc4,0x57,0x92,0x91,0x69,0x2e}};
const GUID _IID_IMMDeviceEnumerator = {0xa95664d2, 0x9614, 0x4f35, {0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6}};
CoCreateInstance(_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, _IID_IMMDeviceEnumerator, (void**)&enu);
bool playback = true;
IMMDeviceCollection *dcoll;
EDataFlow mode = (playback) ? eRender : eCapture;
enu->EnumAudioEndpoints(mode, DEVICE_STATE_ACTIVE, &dcoll);
for (int i = 0; ; i++)
{
IMMDevice *dev;
if (0 != dcoll->Item(i, &dev))
break;
IPropertyStore *props;
dev->OpenPropertyStore(STGM_READ, &props);
PROPVARIANT name;
PropVariantInit(&name);
const PROPERTYKEY PKEY_Device_FriendlyName = {{0xa45c254e, 0xdf1c, 0x4efd, {0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0}}, 14};
props->GetValue(PKEY_Device_FriendlyName, &name);
const wchar_t *device_name = name.pwszVal;
wchar_t* device_id = NULL;
dev->GetId(&device_id);
IMMDevice *def_dev = NULL;
enu->GetDefaultAudioEndpoint(mode, eConsole, &def_dev);
def_dev->Release();
CoTaskMemFree(device_id);
PropVariantClear(&name);
dev->Release();
}
//IMMDeviceEnumerator_Release(enu);
dcoll->Release();
enu->Release();
return 0;
}
int open_shared_buffer()
{
bool playback = true;
IMMDeviceEnumerator *enu;
const GUID CLSID_MMDeviceEnumerator = {0xbcde0395, 0xe52f, 0x467c, {0x8e,0x3d, 0xc4,0x57,0x92,0x91,0x69,0x2e}};
const GUID IID_IMMDeviceEnumerator = {0xa95664d2, 0x9614, 0x4f35, {0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6}};
CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enu);
IMMDevice *dev;
wchar_t* device_id = NULL;
if (device_id == NULL)
{
EDataFlow mode = (playback) ? eRender : eCapture;
enu->GetDefaultAudioEndpoint(mode, eConsole, &dev);
} else {
enu->GetDevice(device_id, &dev);
}
IAudioClient* client;
const GUID IID_IAudioClient = {0x1cb9ad4c, 0xdbfa, 0x4c32, {0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2}};
dev->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client);
WAVEFORMATEX *wf;
client->GetMixFormat(&wf);
int buffer_length_msec = 500;
REFERENCE_TIME dur = buffer_length_msec * 1000 * 10;
AUDCLNT_SHAREMODE mode = AUDCLNT_SHAREMODE_SHARED;
int aflags = 0;
client->Initialize(mode, aflags, dur, dur, wf, NULL);
u_int buf_frames;
client->GetBufferSize(&buf_frames);
buffer_length_msec = buf_frames * 1000 / wf->nSamplesPerSec;
CoTaskMemFree(wf);
client->Release();
dev->Release();
enu->Release();
return 0;
}
int record_shared()
{
bool playback = true;
IMMDeviceEnumerator *enu;
const GUID CLSID_MMDeviceEnumerator = {0xbcde0395, 0xe52f, 0x467c, {0x8e,0x3d, 0xc4,0x57,0x92,0x91,0x69,0x2e}};
const GUID IID_IMMDeviceEnumerator = {0xa95664d2, 0x9614, 0x4f35, {0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6}};
CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enu);
IMMDevice *dev;
wchar_t* device_id = NULL;
if (device_id == NULL)
{
EDataFlow mode = (playback) ? eRender : eCapture;
enu->GetDefaultAudioEndpoint(mode, eConsole, &dev);
} else {
enu->GetDevice(device_id, &dev);
}
IAudioClient* client;
const GUID IID_IAudioClient = {0x1cb9ad4c, 0xdbfa, 0x4c32, {0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2}};
dev->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client);
WAVEFORMATEX *wf;
client->GetMixFormat(&wf);
int buffer_length_msec = 500;
REFERENCE_TIME dur = buffer_length_msec * 1000 * 10;
AUDCLNT_SHAREMODE mode = AUDCLNT_SHAREMODE_SHARED;
int aflags = 0;
client->Initialize(mode, aflags, dur, dur, wf, NULL);
u_int buf_frames;
client->GetBufferSize(&buf_frames);
buffer_length_msec = buf_frames * 1000 / wf->nSamplesPerSec;
IAudioCaptureClient* capt;
const GUID IID_IAudioCaptureClient = {0xc8adbd64, 0xe71e, 0x48a0, {0xa4,0xde, 0x18,0x5c,0x39,0x5c,0xd3,0x17}};
client->GetService(IID_IAudioCaptureClient, (void**)&capt);
client->Start();
for (;;)
{
u_char * data;
u_int nframes;
u_long flags;
int r = capt->GetBuffer(&data, &nframes, &flags, NULL, NULL);
if (r == AUDCLNT_S_BUFFER_EMPTY) {
// Buffer is empty. Wait for more data/
int period_ms = 100;
Sleep(period_ms);
continue;
} else if (r != 0) {
// error
}
capt->ReleaseBuffer(nframes);
}
CoTaskMemFree(wf);
client->Release();
dev->Release();
enu->Release();
return 0;
}
int play_shared()
{
bool playback = true;
IMMDeviceEnumerator *enu;
const GUID CLSID_MMDeviceEnumerator = {0xbcde0395, 0xe52f, 0x467c, {0x8e,0x3d, 0xc4,0x57,0x92,0x91,0x69,0x2e}};
const GUID IID_IMMDeviceEnumerator = {0xa95664d2, 0x9614, 0x4f35, {0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6}};
CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enu);
IMMDevice *dev;
wchar_t* device_id = NULL;
if (device_id == NULL)
{
EDataFlow mode = (playback) ? eRender : eCapture;
enu->GetDefaultAudioEndpoint(mode, eConsole, &dev);
} else {
enu->GetDevice(device_id, &dev);
}
IAudioClient* client;
const GUID IID_IAudioClient = {0x1cb9ad4c, 0xdbfa, 0x4c32, {0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2}};
dev->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client);
WAVEFORMATEX *wf;
client->GetMixFormat(&wf);
int buffer_length_msec = 500;
REFERENCE_TIME dur = buffer_length_msec * 1000 * 10;
AUDCLNT_SHAREMODE mode = AUDCLNT_SHAREMODE_SHARED;
int aflags = 0;
client->Initialize(mode, aflags, dur, dur, wf, NULL);
u_int buf_frames;
client->GetBufferSize(&buf_frames);
buffer_length_msec = buf_frames * 1000 / wf->nSamplesPerSec;
IAudioRenderClient *render;
const GUID IID_IAudioRenderClient = {0xf294acfc, 0x3146, 0x4483, {0xa7,0xbf, 0xad,0xdc,0xa7,0xc2,0x60,0xe2}};
client->GetService(IID_IAudioRenderClient, (void**)&render);
u_int filled;
client->GetCurrentPadding(&filled);
int n_free_frames = buf_frames - filled;
int started = 0;
if (!started)
{
client->Start();
started = 1;
}
u_char *data;
render->GetBuffer(n_free_frames, &data);
// Drain the audio buffer
for (;;)
{
u_int filled;
client->GetCurrentPadding(&filled);
if (filled == 0)
break;
}
render->ReleaseBuffer(n_free_frames, 0);
render->Release();
CoTaskMemFree(wf);
client->Release();
dev->Release();
enu->Release();
return 0;
}
int main()
{
enumerate_sound_devices();
open_shared_buffer();
play_shared();
std::cout << "Windows Program" << std::endl;
return 0;
}