cubeb_sink: Don't discard other channels when performing downmixing

Previously, when performing downmixing, we would discard all channels except the left and right one.
This implementation respects them when mixing down to Stereo.
It is taken from this document: http://www.atsc.org/wp-content/uploads/2015/03/A52-201212-17.pdf.

Fixes Luigis Mansion 3 cutscene and Bayonetta audio.
This commit is contained in:
FearlessTobi 2020-02-24 18:34:00 +01:00 committed by bunnei
parent 84e9f9f395
commit 59d0d34dce

View file

@ -8,6 +8,7 @@
#include "audio_core/cubeb_sink.h" #include "audio_core/cubeb_sink.h"
#include "audio_core/stream.h" #include "audio_core/stream.h"
#include "audio_core/time_stretch.h" #include "audio_core/time_stretch.h"
#include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/ring_buffer.h" #include "common/ring_buffer.h"
#include "core/settings.h" #include "core/settings.h"
@ -65,12 +66,25 @@ public:
void EnqueueSamples(u32 source_num_channels, const std::vector<s16>& samples) override { void EnqueueSamples(u32 source_num_channels, const std::vector<s16>& samples) override {
if (source_num_channels > num_channels) { if (source_num_channels > num_channels) {
// Downsample 6 channels to 2 // Downsample 6 channels to 2
ASSERT_MSG(source_num_channels == 6, "Channel count must be 6");
std::vector<s16> buf; std::vector<s16> buf;
buf.reserve(samples.size() * num_channels / source_num_channels); buf.reserve(samples.size() * num_channels / source_num_channels);
for (std::size_t i = 0; i < samples.size(); i += source_num_channels) { for (std::size_t i = 0; i < samples.size(); i += source_num_channels) {
for (std::size_t ch = 0; ch < num_channels; ch++) { // Downmixing implementation taken from the ATSC standard
buf.push_back(samples[i + ch]); const s16 left{samples[i + 0]};
} const s16 right{samples[i + 1]};
const s16 center{samples[i + 2]};
const s16 surround_left{samples[i + 4]};
const s16 surround_right{samples[i + 5]};
// Not used in the ATSC reference implementation
[[maybe_unused]] const s16 low_frequency_effects { samples[i + 3] };
constexpr s32 clev{707}; // center mixing level coefficient
constexpr s32 slev{707}; // surround mixing level coefficient
buf.push_back(left + (clev * center / 1000) + (slev * surround_left / 1000));
buf.push_back(right + (clev * center / 1000) + (slev * surround_right / 1000));
} }
queue.Push(buf); queue.Push(buf);
return; return;