refactor: Bad attempt of fixing waveout

> tried to unify use of hooks::audio::FORMAT between backends
This commit is contained in:
[ ]
2023-09-26 05:20:02 +09:00
parent a0e44f9e4b
commit 5951a550bb
5 changed files with 40 additions and 17 deletions
@@ -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,
+1 -2
View File
@@ -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) {
+1 -1
View File
@@ -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;
+33 -14
View File
@@ -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)
{
}
+2
View File
@@ -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;