spicetools/hooks/audio/backends/wasapi/audio_render_client.cpp

89 lines
2.3 KiB
C++

#include "audio_render_client.h"
#include "audio_client.h"
#include "wasapi_private.h"
const char CLASS_NAME[] = "WrappedIAudioRenderClient";
HRESULT STDMETHODCALLTYPE WrappedIAudioRenderClient::QueryInterface(REFIID riid, void **ppvObj) {
if (ppvObj == nullptr) {
return E_POINTER;
}
if (riid == IID_WrappedIAudioRenderClient ||
riid == IID_IAudioRenderClient)
{
this->AddRef();
*ppvObj = this;
return S_OK;
}
return pReal->QueryInterface(riid, ppvObj);
}
ULONG STDMETHODCALLTYPE WrappedIAudioRenderClient::AddRef() {
return pReal->AddRef();
}
ULONG STDMETHODCALLTYPE WrappedIAudioRenderClient::Release() {
// get reference count of underlying interface
ULONG refs = pReal != nullptr ? pReal->Release() : 0;
if (refs == 0) {
delete this;
}
return refs;
}
// IAudioRenderClient
HRESULT STDMETHODCALLTYPE WrappedIAudioRenderClient::GetBuffer(UINT32 NumFramesRequested, BYTE **ppData) {
static std::once_flag printed;
std::call_once(printed, []() {
log_misc("audio::wasapi", "WrappedIAudioRenderClient::GetBuffer");
});
if (this->client->backend) {
SAFE_CALL("AudioBackend", "on_get_buffer", this->client->backend->on_get_buffer(
NumFramesRequested,
ppData));
return S_OK;
}
// call original
HRESULT ret = pReal->GetBuffer(NumFramesRequested, ppData);
// store buffer reference
if (SUCCEEDED(ret)) {
this->audio_buffer = *ppData;
}
CHECK_RESULT(ret);
}
HRESULT STDMETHODCALLTYPE WrappedIAudioRenderClient::ReleaseBuffer(UINT32 NumFramesWritten, DWORD dwFlags) {
static std::once_flag printed;
std::call_once(printed, []() {
log_misc("audio::wasapi", "WrappedIAudioRenderClient::ReleaseBuffer");
});
if (this->client->backend) {
SAFE_CALL("AudioBackend", "on_release_buffer", this->client->backend->on_release_buffer(
NumFramesWritten,
dwFlags));
return S_OK;
}
// fix for audio pop effect
if (this->buffers_to_mute > 0 && this->client->frame_size > 0) {
// zero out = mute
memset(this->audio_buffer, 0, NumFramesWritten * this->client->frame_size);
this->buffers_to_mute--;
}
CHECK_RESULT(pReal->ReleaseBuffer(NumFramesWritten, dwFlags));
}