refactor: Bad attempt of fixing waveout
> tried to unify use of hooks::audio::FORMAT between backends
This commit is contained in:
@@ -79,6 +79,9 @@ HRESULT STDMETHODCALLTYPE DummyIAudioClient::Initialize(
|
|||||||
log_info("audio::wasapi", "... hnsPeriodicity : {}", hnsPeriodicity);
|
log_info("audio::wasapi", "... hnsPeriodicity : {}", hnsPeriodicity);
|
||||||
print_format(pFormat);
|
print_format(pFormat);
|
||||||
|
|
||||||
|
log_info("audio::wasapi", "IAudioClient::Initialize forwarding format");
|
||||||
|
copy_wave_format(&hooks::audio::FORMAT, pFormat);
|
||||||
|
|
||||||
CHECK_RESULT(this->backend->on_initialize(
|
CHECK_RESULT(this->backend->on_initialize(
|
||||||
&ShareMode,
|
&ShareMode,
|
||||||
&StreamFlags,
|
&StreamFlags,
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ static SampleType convert_asio_sample_type(AsioSampleType type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsioBackend::AsioBackend() {
|
AsioBackend::AsioBackend() : format_(hooks::audio::FORMAT) {
|
||||||
this->asio_thread = std::thread([this]() {
|
this->asio_thread = std::thread([this]() {
|
||||||
std::unique_lock<std::mutex> lock_handle(this->asio_thread_state_lock);
|
std::unique_lock<std::mutex> lock_handle(this->asio_thread_state_lock);
|
||||||
|
|
||||||
@@ -750,7 +750,6 @@ HRESULT AsioBackend::on_initialize(
|
|||||||
{
|
{
|
||||||
AsioError result;
|
AsioError result;
|
||||||
|
|
||||||
copy_wave_format(&this->format_, pFormat);
|
|
||||||
memcpy(&this->last_checked_format, &this->format_, sizeof(this->format_));
|
memcpy(&this->last_checked_format, &this->format_, sizeof(this->format_));
|
||||||
|
|
||||||
if (!this->asio_thread_initialized) {
|
if (!this->asio_thread_initialized) {
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ private:
|
|||||||
SampleType asio_sample_type = SampleType::UNSUPPORTED;
|
SampleType asio_sample_type = SampleType::UNSUPPORTED;
|
||||||
|
|
||||||
std::atomic_bool started = false;
|
std::atomic_bool started = false;
|
||||||
WAVEFORMATEXTENSIBLE format_ {};
|
const WAVEFORMATEXTENSIBLE &format_;
|
||||||
WAVEFORMATEXTENSIBLE last_checked_format {};
|
WAVEFORMATEXTENSIBLE last_checked_format {};
|
||||||
|
|
||||||
//std::vector<BYTE> last_sound_buffer;
|
//std::vector<BYTE> last_sound_buffer;
|
||||||
|
|||||||
@@ -3,26 +3,34 @@
|
|||||||
#include "hooks/audio/audio.h"
|
#include "hooks/audio/audio.h"
|
||||||
#include "hooks/audio/backends/wasapi/audio_client.h"
|
#include "hooks/audio/backends/wasapi/audio_client.h"
|
||||||
#include "hooks/audio/backends/wasapi/defs.h"
|
#include "hooks/audio/backends/wasapi/defs.h"
|
||||||
|
#include "hooks/audio/util.h"
|
||||||
|
#include "hooks/audio/buffer.h"
|
||||||
|
|
||||||
static REFERENCE_TIME WASAPI_TARGET_REFTIME = TARGET_REFTIME;
|
static REFERENCE_TIME WASAPI_TARGET_REFTIME = TARGET_REFTIME;
|
||||||
|
|
||||||
HRESULT WaveOutBackend::init(uint32_t buffer_size) {
|
HRESULT WaveOutBackend::init(uint32_t buffer_size) {
|
||||||
auto &format = hooks::audio::FORMAT.Format;
|
MMRESULT ret;
|
||||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
|
||||||
|
|
||||||
log_info("audio::wave_out", "initializing waveOut backend with {} channels, {} Hz, {}-bit",
|
if (format_.Format.nSamplesPerSec == 0)
|
||||||
format.nChannels,
|
{
|
||||||
format.nSamplesPerSec,
|
log_warning("audio::wave_out", "format_ condition race");
|
||||||
format.wBitsPerSample);
|
return static_cast<HRESULT>(MMSYSERR_ERROR);
|
||||||
log_info("audio::wave_out", "... nBlockAlign : {} bytes", format.nBlockAlign);
|
}
|
||||||
log_info("audio::wave_out", "... nAvgBytesPerSec : {} bytes", format.nAvgBytesPerSec);
|
hooks::audio::FORMAT.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
|
log_info("audio::wave_out", "initializing waveOut backend with {} channels, {} Hz, {}-bit, {} format",
|
||||||
|
format_.Format.nChannels,
|
||||||
|
format_.Format.nSamplesPerSec,
|
||||||
|
format_.Format.wBitsPerSample,
|
||||||
|
format_.Format.wFormatTag);
|
||||||
|
log_info("audio::wave_out", "... nBlockAlign : {} bytes", format_.Format.nBlockAlign);
|
||||||
|
log_info("audio::wave_out", "... nAvgBytesPerSec : {} bytes", format_.Format.nAvgBytesPerSec);
|
||||||
log_info("audio::wave_out", "... buffer reftime : {} ms", WASAPI_TARGET_REFTIME / 10000.f);
|
log_info("audio::wave_out", "... buffer reftime : {} ms", WASAPI_TARGET_REFTIME / 10000.f);
|
||||||
log_info("audio::wave_out", "... buffer count : {} buffers", _countof(this->hdrs));
|
log_info("audio::wave_out", "... buffer count : {} buffers", _countof(this->hdrs));
|
||||||
|
|
||||||
MMRESULT ret = waveOutOpen(
|
ret = waveOutOpen(
|
||||||
&this->handle,
|
&this->handle,
|
||||||
WAVE_MAPPER,
|
WAVE_MAPPER,
|
||||||
reinterpret_cast<const WAVEFORMATEX *>(&hooks::audio::FORMAT.Format),
|
reinterpret_cast<const WAVEFORMATEX *>(&format_.Format),
|
||||||
reinterpret_cast<DWORD_PTR>(this->dispatcher_event),
|
reinterpret_cast<DWORD_PTR>(this->dispatcher_event),
|
||||||
reinterpret_cast<DWORD_PTR>(nullptr),
|
reinterpret_cast<DWORD_PTR>(nullptr),
|
||||||
CALLBACK_EVENT);
|
CALLBACK_EVENT);
|
||||||
@@ -35,6 +43,7 @@ HRESULT WaveOutBackend::init(uint32_t buffer_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// initialize buffers
|
// initialize buffers
|
||||||
|
log_info("audio::wave_out", "... device handle : {}", fmt::ptr(this->handle));
|
||||||
for (auto &hdr : this->hdrs) {
|
for (auto &hdr : this->hdrs) {
|
||||||
memset(&hdr, 0, sizeof(hdr));
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
hdr.lpData = new char[buffer_size] {};
|
hdr.lpData = new char[buffer_size] {};
|
||||||
@@ -70,7 +79,7 @@ HRESULT WaveOutBackend::init(uint32_t buffer_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const WAVEFORMATEXTENSIBLE &WaveOutBackend::format() const noexcept {
|
const WAVEFORMATEXTENSIBLE &WaveOutBackend::format() const noexcept {
|
||||||
return hooks::audio::FORMAT;
|
return format_;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WaveOutBackend::on_initialize(
|
HRESULT WaveOutBackend::on_initialize(
|
||||||
@@ -89,6 +98,8 @@ HRESULT WaveOutBackend::on_initialize(
|
|||||||
*hnsBufferDuration = WASAPI_TARGET_REFTIME;
|
*hnsBufferDuration = WASAPI_TARGET_REFTIME;
|
||||||
*hnsPeriodicity = WASAPI_TARGET_REFTIME;
|
*hnsPeriodicity = WASAPI_TARGET_REFTIME;
|
||||||
|
|
||||||
|
log_info("audio::wave_out", "on_initialize");
|
||||||
|
|
||||||
// this backend only supports stereo audio
|
// this backend only supports stereo audio
|
||||||
if (pFormat->nChannels > 2) {
|
if (pFormat->nChannels > 2) {
|
||||||
return AUDCLNT_E_UNSUPPORTED_FORMAT;
|
return AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||||
@@ -115,7 +126,7 @@ HRESULT WaveOutBackend::on_get_current_padding(std::optional<uint32_t> &padding_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frames = static_cast<uint32_t>(queued_bytes / hooks::audio::FORMAT.Format.nBlockAlign);
|
auto frames = static_cast<uint32_t>(queued_bytes / format_.Format.nBlockAlign);
|
||||||
//log_info("audio::wave_out", "queued_bytes = {}, frames = {}", queued_bytes, frames);
|
//log_info("audio::wave_out", "queued_bytes = {}, frames = {}", queued_bytes, frames);
|
||||||
|
|
||||||
padding_frames = frames;
|
padding_frames = frames;
|
||||||
@@ -136,6 +147,7 @@ HRESULT WaveOutBackend::on_is_format_supported(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//return waveOutOpen(nullptr, WAVE_MAPPER, reinterpret_cast<const WAVEFORMATEX *>(&format_.Format), NULL, NULL, WAVE_FORMAT_QUERY) == MMSYSERR_NOERROR ? S_OK : AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||||
return AUDCLNT_E_UNSUPPORTED_FORMAT;
|
return AUDCLNT_E_UNSUPPORTED_FORMAT;
|
||||||
}
|
}
|
||||||
HRESULT WaveOutBackend::on_get_mix_format(WAVEFORMATEX **pp_device_format) noexcept {
|
HRESULT WaveOutBackend::on_get_mix_format(WAVEFORMATEX **pp_device_format) noexcept {
|
||||||
@@ -166,17 +178,20 @@ HRESULT WaveOutBackend::on_set_event_handle(HANDLE *event_handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WaveOutBackend::on_get_buffer(uint32_t num_frames_requested, BYTE **ppData) {
|
HRESULT WaveOutBackend::on_get_buffer(uint32_t num_frames_requested, BYTE **ppData) {
|
||||||
auto buffer_size = hooks::audio::FORMAT.Format.nBlockAlign * num_frames_requested;
|
size_t buffer_size = format_.Format.nBlockAlign * num_frames_requested;
|
||||||
|
|
||||||
if (!this->initialized) {
|
if (!this->initialized) {
|
||||||
this->init(buffer_size);
|
this->init(buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t converted_size = required_buffer_size(num_frames_requested, format_.Format.nChannels, SampleType::SINT_16);
|
||||||
|
const size_t max_size = std::max(buffer_size, converted_size);
|
||||||
|
|
||||||
// wait for a free slot
|
// wait for a free slot
|
||||||
WaitForSingleObject(this->dispatcher_event, INFINITE);
|
WaitForSingleObject(this->dispatcher_event, INFINITE);
|
||||||
|
|
||||||
// allocate temporary sound buffer
|
// allocate temporary sound buffer
|
||||||
this->active_sound_buffer = reinterpret_cast<BYTE *>(CoTaskMemAlloc(buffer_size));
|
this->active_sound_buffer = reinterpret_cast<BYTE *>(CoTaskMemAlloc(max_size));
|
||||||
|
|
||||||
// hand the buffer to the callee
|
// hand the buffer to the callee
|
||||||
*ppData = this->active_sound_buffer;
|
*ppData = this->active_sound_buffer;
|
||||||
@@ -222,3 +237,7 @@ HRESULT WaveOutBackend::on_release_buffer(uint32_t num_frames_written, DWORD dwF
|
|||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
WaveOutBackend::WaveOutBackend() : format_(hooks::audio::FORMAT)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
struct WaveOutBackend final : AudioBackend {
|
struct WaveOutBackend final : AudioBackend {
|
||||||
public:
|
public:
|
||||||
|
explicit WaveOutBackend();
|
||||||
~WaveOutBackend() final = default;
|
~WaveOutBackend() final = default;
|
||||||
|
|
||||||
HRESULT init(uint32_t buffer_size);
|
HRESULT init(uint32_t buffer_size);
|
||||||
@@ -49,6 +50,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
WrappedIAudioClient *client;
|
WrappedIAudioClient *client;
|
||||||
|
|
||||||
|
const WAVEFORMATEXTENSIBLE &format_;
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
HANDLE relay_event = nullptr;
|
HANDLE relay_event = nullptr;
|
||||||
HANDLE dispatcher_event = nullptr;
|
HANDLE dispatcher_event = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user