Merge pull request #415 from GoaLitiuM/master

win-wasapi: Fix capture during silence
master
Jim 2015-04-15 10:32:14 -07:00
commit 48d5aeaae5
1 changed files with 48 additions and 0 deletions

View File

@ -22,6 +22,7 @@ class WASAPISource {
ComPtr<IMMDevice> device; ComPtr<IMMDevice> device;
ComPtr<IAudioClient> client; ComPtr<IAudioClient> client;
ComPtr<IAudioCaptureClient> capture; ComPtr<IAudioCaptureClient> capture;
ComPtr<IAudioRenderClient> render;
obs_source_t *source; obs_source_t *source;
string device_id; string device_id;
@ -56,6 +57,7 @@ class WASAPISource {
bool InitDevice(IMMDeviceEnumerator *enumerator); bool InitDevice(IMMDeviceEnumerator *enumerator);
void InitName(); void InitName();
void InitClient(); void InitClient();
void InitRender();
void InitFormat(WAVEFORMATEX *wfex); void InitFormat(WAVEFORMATEX *wfex);
void InitCapture(); void InitCapture();
void Initialize(); void Initialize();
@ -191,6 +193,51 @@ void WASAPISource::InitClient()
throw HRError("Failed to get initialize audio client", res); throw HRError("Failed to get initialize audio client", res);
} }
void WASAPISource::InitRender()
{
CoTaskMemPtr<WAVEFORMATEX> wfex;
HRESULT res;
LPBYTE buffer;
UINT32 frames;
ComPtr<IAudioClient> client;
res = device->Activate(__uuidof(IAudioClient), CLSCTX_ALL,
nullptr, (void**)client.Assign());
if (FAILED(res))
throw HRError("Failed to activate client context", res);
res = client->GetMixFormat(&wfex);
if (FAILED(res))
throw HRError("Failed to get mix format", res);
res = client->Initialize(
AUDCLNT_SHAREMODE_SHARED, 0,
BUFFER_TIME_100NS, 0, wfex, nullptr);
if (FAILED(res))
throw HRError("Failed to get initialize audio client", res);
/* Silent loopback fix. Prevents audio stream from stopping and */
/* messing up timestamps and other weird glitches during silence */
/* by playing a silent sample all over again. */
res = client->GetBufferSize(&frames);
if (FAILED(res))
throw HRError("Failed to get buffer size", res);
res = client->GetService(__uuidof(IAudioRenderClient),
(void**)render.Assign());
if (FAILED(res))
throw HRError("Failed to get render client", res);
res = render->GetBuffer(frames, &buffer);
if (FAILED(res))
throw HRError("Failed to get buffer", res);
memset(buffer, 0, frames*wfex->nBlockAlign);
render->ReleaseBuffer(frames, 0);
}
static speaker_layout ConvertSpeakerLayout(DWORD layout, WORD channels) static speaker_layout ConvertSpeakerLayout(DWORD layout, WORD channels)
{ {
switch (layout) { switch (layout) {
@ -263,6 +310,7 @@ void WASAPISource::Initialize()
device_name = GetDeviceName(device); device_name = GetDeviceName(device);
InitClient(); InitClient();
if (!isInputDevice) InitRender();
InitCapture(); InitCapture();
} }