Search code examples
sharedevent-drivenwasapiaudio-capture

WASAPI Capture shared event driven mode in WINDOWS SERVER 2016 and below


I am building an application to capture audio from the device using WASAPI Where all the API used support Windows vista and above devices.

Initially, I captured audio from the device with WASAPI Capture as shared timer driven mode where there will be a thread which will capture audio from the device for every 0 milliseconds. Where it worked in windows vista and above devices.

Since the above approach is not much efficient over CPU consumption and not every optimized, I tried to capture the audio from the device with WASAPI Capture as shared event driven mode where audio will be captured only when an event is triggered from the system when data is available. This approach did reduce the CPU consumption fully but is not working in Windows VISTA to Windows Server 2016 devices.

Initialization of audio client interface

Audio interface is initialized with shared mode and stream flag given is for AUDCLNT_STREAMFLAGS_EVENTCALLBACK since I am using event driven mode. GetExtensibleMixFormat method gives the default mixformat that is fetched using GetMixFormat() of windows.

int enginelatency = 20;

HRESULT hr = _AudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_LOOPBACK , enginelatency * 10000, 0, (WAVEFORMATEX*)mix_format_wasapicap_ptr->GetExtensibleMixFormat(), NULL);

Initializing the event

Where _AudioSamplesReadyEvent is a handle that is given to SetEventHandle method. This event will be triggered by the system when an audio buffer is ready to be processed by the client.

hr = _AudioClient->SetEventHandle(_AudioSamplesReadyEvent);

Though all the API's used are supported by Windows VISTA and above devices, not able to figure out why event is not triggered in Windows VISTA to Windows Server 2016 devices.

I have done error handling properly and not able to catch any errors. Also to note, I have used WASAPI capture code with minor changes by changing dataFlow used in GetDefaultAudioEndpoint to eRender so that I can capture the audio from the output device and not the mic, since eCapture captures the input device.

On debugging I found that in Windows Vista to Windows Server 2016 devices, when using eCapture event is triggering properly but when using eRender _AudioSamplesReadyEvent event is not getting triggered.

Any suggestions are appreciated.


Solution

  • As per the Initialize document, it is mentioned that EVENT callback will not work with loopback stream flag in Windows 10 below OS versions.

    enter image description here

    I used the Render client to trigger event to capture client where I initialize capture client with loopback flag and initialize render client with event callback.

    Once the render client event is triggered, I capture the audio buffer from the device using capture client.

    This is how we need to capture audio from output device in Windows 10 below OS.