|
|
|
#pragma comment(lib, "ole32") |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
#include <windows.h> |
|
#include <mmdeviceapi.h> |
|
#include <audioclient.h> |
|
#include <math.h> // for sine |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
int main() |
|
{ |
|
CoInitializeEx(nullptr, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
IMMDeviceEnumerator* deviceEnumerator; |
|
|
|
CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), reinterpret_cast<void**>(&deviceEnumerator)); |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
IMMDevice* audioDevice; |
|
|
|
deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &audioDevice); |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
IAudioClient3* audioClient; |
|
|
|
audioDevice->Activate(__uuidof(IAudioClient3), CLSCTX_INPROC_SERVER, nullptr, reinterpret_cast<void**>(&audioClient)); |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
REFERENCE_TIME defaultPeriod; |
|
REFERENCE_TIME minimumPeriod; |
|
|
|
audioClient->GetDevicePeriod(&defaultPeriod, &minimumPeriod); |
|
|
|
WAVEFORMATEX* mixFormat; |
|
|
|
audioClient->GetMixFormat(&mixFormat); |
|
|
|
audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, minimumPeriod, 0, mixFormat, nullptr); |
|
|
|
IAudioRenderClient* audioRenderClient; |
|
|
|
audioClient->GetService(__uuidof(IAudioRenderClient), reinterpret_cast<void**>(&audioRenderClient)); |
|
|
|
UINT32 bufferSize; |
|
|
|
audioClient->GetBufferSize(&bufferSize); |
|
|
|
HANDLE bufferReady = CreateEventA(nullptr, FALSE, FALSE, nullptr); |
|
|
|
audioClient->SetEventHandle(bufferReady); |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
double time = 0.0; |
|
|
|
audioClient->Start(); |
|
|
|
while (WaitForSingleObject(bufferReady, INFINITE) == WAIT_OBJECT_0) |
|
{ |
|
UINT32 bufferPadding; |
|
|
|
audioClient->GetCurrentPadding(&bufferPadding); |
|
|
|
UINT32 frameCount = bufferSize - bufferPadding; |
|
float* buffer; |
|
|
|
audioRenderClient->GetBuffer(frameCount, reinterpret_cast<BYTE**>(&buffer)); |
|
|
|
for (UINT32 frameIndex = 0; frameIndex < frameCount; frameIndex++) |
|
{ |
|
float amplitude = static_cast<float>(sin(time)); |
|
|
|
*buffer++ = amplitude; // left |
|
*buffer++ = amplitude; // right |
|
|
|
time += 0.05; |
|
} |
|
|
|
audioRenderClient->ReleaseBuffer(frameCount, 0); |
|
} |
|
|
|
audioClient->Stop(); |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
return 0; |
|
} |