Consider this code that captures audio from the default endpoint and displays how many frames are passed each second.
This works OK if it's not a RDP session (Remote Audio). If it is a RDP session, this code only works without the event.
If I use an event, then the audio lags. Each second only about half the samples are returned.
Is this a bug of the Remote Audio interface when using an event notification?
#include "stdafx.h"
int main()
{
int BS = 512;
CoInitialize(0);
CComPtr<IMMDeviceEnumerator> deviceEnumerator = 0;
auto hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID*)&deviceEnumerator);
if (!deviceEnumerator)
return 0;
CComPtr<IMMDevice> d;
deviceEnumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &d);
if (!d)
return 0;
CComPtr<IAudioClient> ac;
hr = d->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (LPVOID*)&ac);
auto Has = CreateEvent(0, 0, 0, 0);
WAVEFORMATEX* wf = 0;
ac->GetMixFormat(&wf);
unsigned long long a = BS;
a *= 1000;
a *= 10000;
a /= wf->nSamplesPerSec;
REFERENCE_TIME rt = a;
bool Ev = true;
DWORD flg = AUDCLNT_STREAMFLAGS_NOPERSIST;
flg |= AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM;
if (Ev)
flg |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
hr = ac->Initialize(AUDCLNT_SHAREMODE_SHARED, flg, rt, rt, (WAVEFORMATEX*)wf, 0);
CComPtr<IAudioCaptureClient> cap;
ac->GetService(__uuidof(IAudioCaptureClient), (void**)&cap);
ac->SetEventHandle(Has);
ac->Start();
UINT32 sz = 0;
ac->GetBufferSize(&sz);
auto t = GetTickCount64();
unsigned long long tfr = 0;
for (;;)
{
BYTE* pData = 0;
UINT32 framesAvailable = 0;
DWORD flags = 0;
if (Ev)
WaitForSingleObject(Has, INFINITE);
auto t2 = GetTickCount64();
hr = cap->GetBuffer(&pData, &framesAvailable, &flags, NULL, NULL);
if (FAILED(hr))
break;
if (!framesAvailable)
continue;
if (framesAvailable)
tfr += framesAvailable;
if ((t2 - t) >= 1000)
{
printf("%llu - %lli\r\n", (unsigned long long)(t2 - t), tfr);
tfr = 0;
t = t2;
}
cap->ReleaseBuffer(framesAvailable);
}
}
Michael