#include #define COBJMACROS #include #include 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; }