From 8d010b44c16766331aa92e1a45a03a4cef1466e0 Mon Sep 17 00:00:00 2001 From: kobewi Date: Fri, 28 Apr 2023 13:23:01 +0200 Subject: [PATCH] Add mono audio support to WASAPI --- drivers/wasapi/audio_driver_wasapi.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index f877f7866541..eeeb6ee689ef 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -480,6 +480,14 @@ Error AudioDriverWASAPI::init_output_device(bool p_reinit) { } switch (audio_output.channels) { + case 1: // Mono + case 3: // Surround 2.1 + case 5: // Surround 5.0 + case 7: // Surround 7.0 + // We will downmix as required. + channels = audio_output.channels + 1; + break; + case 2: // Stereo case 4: // Surround 3.1 case 6: // Surround 5.1 @@ -499,7 +507,7 @@ Error AudioDriverWASAPI::init_output_device(bool p_reinit) { input_position = 0; input_size = 0; - print_verbose("WASAPI: detected " + itos(channels) + " channels"); + print_verbose("WASAPI: detected " + itos(audio_output.channels) + " channels"); print_verbose("WASAPI: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); return OK; @@ -746,6 +754,19 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { for (unsigned int i = 0; i < write_frames * ad->channels; i++) { ad->write_sample(ad->audio_output.format_tag, ad->audio_output.bits_per_sample, buffer, i, ad->samples_in.write[write_ofs++]); } + } else if (ad->channels == ad->audio_output.channels + 1) { + // Pass all channels except the last two as-is, and then mix the last two + // together as one channel. E.g. stereo -> mono, or 3.1 -> 2.1. + unsigned int last_chan = ad->audio_output.channels - 1; + for (unsigned int i = 0; i < write_frames; i++) { + for (unsigned int j = 0; j < last_chan; j++) { + ad->write_sample(ad->audio_output.format_tag, ad->audio_output.bits_per_sample, buffer, i * ad->audio_output.channels + j, ad->samples_in.write[write_ofs++]); + } + int32_t l = ad->samples_in.write[write_ofs++]; + int32_t r = ad->samples_in.write[write_ofs++]; + int32_t c = (int32_t)(((int64_t)l + (int64_t)r) / 2); + ad->write_sample(ad->audio_output.format_tag, ad->audio_output.bits_per_sample, buffer, i * ad->audio_output.channels + last_chan, c); + } } else { for (unsigned int i = 0; i < write_frames; i++) { for (unsigned int j = 0; j < MIN(ad->channels, ad->audio_output.channels); j++) {