commit
48d5aeaae5
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue