From 75f8ee434efcb190fac21386021f31d6cf8188c1 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Thu, 14 Jul 2022 02:33:15 +0200 Subject: [PATCH] early-access version 2833 --- README.md | 2 +- .../renderer/adsp/audio_renderer.cpp | 1 - .../renderer/command/sink/device.cpp | 17 ++--- src/audio_core/sink/cubeb_sink.cpp | 66 +++++++++++++----- src/audio_core/sink/sdl2_sink.cpp | 69 ++++++++++++++----- 5 files changed, 103 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 815ce8532..c512f9d49 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2832. +This is the source code for early-access 2833. ## Legal Notice diff --git a/src/audio_core/renderer/adsp/audio_renderer.cpp b/src/audio_core/renderer/adsp/audio_renderer.cpp index 53f32f8cd..3967ccfe6 100755 --- a/src/audio_core/renderer/adsp/audio_renderer.cpp +++ b/src/audio_core/renderer/adsp/audio_renderer.cpp @@ -130,7 +130,6 @@ void AudioRenderer::CreateSinkStreams() { std::string name{fmt::format("ADSP_RenderStream-{}", i)}; streams[i] = sink.AcquireSinkStream(system, channels, name, ::AudioCore::Sink::StreamType::Render); - streams[i]->SetSystemChannels(streams[i]->GetDeviceChannels()); } } diff --git a/src/audio_core/renderer/command/sink/device.cpp b/src/audio_core/renderer/command/sink/device.cpp index d7018cdfd..47e0c6722 100755 --- a/src/audio_core/renderer/command/sink/device.cpp +++ b/src/audio_core/renderer/command/sink/device.cpp @@ -24,16 +24,7 @@ void DeviceSinkCommand::Process(const ADSP::CommandListProcessor& processor) { constexpr s32 max = std::numeric_limits::max(); auto stream{processor.GetOutputSinkStream()}; - const auto num_out_channels{stream->GetDeviceChannels()}; - - auto system_channels{6U}; - for (u32 i = 0; i < inputs.size(); i++) { - if (inputs[i] == 0) { - system_channels = i; - break; - } - } - const auto num_in_channels{std::min(system_channels, stream->GetDeviceChannels())}; + stream->SetSystemChannels(input_count); Sink::SinkBuffer out_buffer{ .frames{TargetSampleCount}, @@ -42,13 +33,13 @@ void DeviceSinkCommand::Process(const ADSP::CommandListProcessor& processor) { .consumed{false}, }; - std::vector samples(out_buffer.frames * num_out_channels, 0); + std::vector samples(out_buffer.frames * input_count); - for (u32 channel = 0; channel < num_in_channels; channel++) { + for (u32 channel = 0; channel < input_count; channel++) { const auto offset{inputs[channel] * out_buffer.frames}; for (u32 index = 0; index < out_buffer.frames; index++) { - samples[index * num_out_channels + channel] = + samples[index * input_count + channel] = static_cast(std::clamp(sample_buffer[offset + index], min, max)); } } diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp index d80d1ed21..1ac62b3b9 100755 --- a/src/audio_core/sink/cubeb_sink.cpp +++ b/src/audio_core/sink/cubeb_sink.cpp @@ -181,36 +181,67 @@ public: queue.enqueue(buffer); queued_buffers++; } else { - static constexpr s32 min = std::numeric_limits::min(); - static constexpr s32 max = std::numeric_limits::max(); + constexpr s32 min{std::numeric_limits::min()}; + constexpr s32 max{std::numeric_limits::max()}; auto yuzu_volume{Settings::Volume()}; auto volume{system_volume * device_volume * yuzu_volume}; + if (system_channels == 6 && device_channels == 2) { - std::array down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f}; + // We're given 6 channels, but our device only outputs 2, so downmix. + constexpr std::array down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f}; + for (u32 read_index = 0, write_index = 0; read_index < samples.size(); read_index += system_channels, write_index += device_channels) { - const auto left_sample = - ((Common::FixedPoint<49, 15>(samples[read_index + 0]) * down_mix_coeff[0] + - samples[read_index + 2] * down_mix_coeff[1] + - samples[read_index + 3] * down_mix_coeff[2] + - samples[read_index + 4] * down_mix_coeff[3]) * + const auto left_sample{ + ((Common::FixedPoint<49, 15>( + samples[read_index + static_cast(Channels::FrontLeft)]) * + down_mix_coeff[0] + + samples[read_index + static_cast(Channels::Center)] * + down_mix_coeff[1] + + samples[read_index + static_cast(Channels::LFE)] * + down_mix_coeff[2] + + samples[read_index + static_cast(Channels::BackLeft)] * + down_mix_coeff[3]) * volume) - .to_int(); + .to_int()}; - const auto right_sample = - ((Common::FixedPoint<49, 15>(samples[read_index + 1]) * down_mix_coeff[0] + - samples[read_index + 2] * down_mix_coeff[1] + - samples[read_index + 3] * down_mix_coeff[2] + - samples[read_index + 5] * down_mix_coeff[3]) * + const auto right_sample{ + ((Common::FixedPoint<49, 15>( + samples[read_index + static_cast(Channels::FrontRight)]) * + down_mix_coeff[0] + + samples[read_index + static_cast(Channels::Center)] * + down_mix_coeff[1] + + samples[read_index + static_cast(Channels::LFE)] * + down_mix_coeff[2] + + samples[read_index + static_cast(Channels::BackRight)] * + down_mix_coeff[3]) * volume) - .to_int(); + .to_int()}; - samples[write_index + 0] = static_cast(std::clamp(left_sample, min, max)); - samples[write_index + 1] = static_cast(std::clamp(right_sample, min, max)); + samples[write_index + static_cast(Channels::FrontLeft)] = + static_cast(std::clamp(left_sample, min, max)); + samples[write_index + static_cast(Channels::FrontRight)] = + static_cast(std::clamp(right_sample, min, max)); } samples.resize(samples.size() / system_channels * device_channels); + + } else if (system_channels == 2 && device_channels == 6) { + // We need moar samples! Not all games will provide 6 channel audio. + // TODO: Implement some upmixing here. Currently just passthrough, with other + // channels left as silence. + std::vector new_samples(samples.size() / system_channels * device_channels, 0); + + for (u32 read_index = 0, write_index = 0; read_index < samples.size(); + read_index += system_channels, write_index += device_channels) { + new_samples[write_index + static_cast(Channels::FrontLeft)] = + samples[read_index + static_cast(Channels::FrontLeft)]; + new_samples[write_index + static_cast(Channels::FrontRight)] = + samples[read_index + static_cast(Channels::FrontRight)]; + } + samples = std::move(new_samples); + } else if (volume != 1.0f) { for (u32 i = 0; i < samples.size(); i++) { samples[i] = static_cast(std::clamp( @@ -499,7 +530,6 @@ CubebSink::CubebSink(std::string_view target_device_name) { } } - // TODO: Implement upmixing, not all games will provide 6 channel audio. cubeb_get_max_channel_count(ctx, &device_channels); device_channels = std::clamp(device_channels, 2U, 6U); } diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp index c28e6bdb9..cf86b2acb 100755 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl2_sink.cpp @@ -154,40 +154,71 @@ public: queue.enqueue(buffer); queued_buffers++; } else { - static constexpr s32 min = std::numeric_limits::min(); - static constexpr s32 max = std::numeric_limits::max(); + constexpr s32 min = std::numeric_limits::min(); + constexpr s32 max = std::numeric_limits::max(); auto yuzu_volume{Settings::Volume()}; auto volume{system_volume * device_volume * yuzu_volume}; + if (system_channels == 6 && device_channels == 2) { - std::array down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f}; + // We're given 6 channels, but our device only outputs 2, so downmix. + constexpr std::array down_mix_coeff{1.0f, 0.707f, 0.251f, 0.707f}; + for (u32 read_index = 0, write_index = 0; read_index < samples.size(); read_index += system_channels, write_index += device_channels) { - const auto left_sample = - ((Common::FixedPoint<49, 15>(samples[read_index + 0]) * down_mix_coeff[0] + - samples[read_index + 2] * down_mix_coeff[1] + - samples[read_index + 3] * down_mix_coeff[2] + - samples[read_index + 4] * down_mix_coeff[3]) * + const auto left_sample{ + ((Common::FixedPoint<49, 15>( + samples[read_index + static_cast(Channels::FrontLeft)]) * + down_mix_coeff[0] + + samples[read_index + static_cast(Channels::Center)] * + down_mix_coeff[1] + + samples[read_index + static_cast(Channels::LFE)] * + down_mix_coeff[2] + + samples[read_index + static_cast(Channels::BackLeft)] * + down_mix_coeff[3]) * volume) - .to_int(); + .to_int()}; - const auto right_sample = - ((Common::FixedPoint<49, 15>(samples[read_index + 1]) * down_mix_coeff[0] + - samples[read_index + 2] * down_mix_coeff[1] + - samples[read_index + 3] * down_mix_coeff[2] + - samples[read_index + 5] * down_mix_coeff[3]) * + const auto right_sample{ + ((Common::FixedPoint<49, 15>( + samples[read_index + static_cast(Channels::FrontRight)]) * + down_mix_coeff[0] + + samples[read_index + static_cast(Channels::Center)] * + down_mix_coeff[1] + + samples[read_index + static_cast(Channels::LFE)] * + down_mix_coeff[2] + + samples[read_index + static_cast(Channels::BackRight)] * + down_mix_coeff[3]) * volume) - .to_int(); + .to_int()}; - samples[write_index + 0] = static_cast(std::clamp(left_sample, min, max)); - samples[write_index + 1] = static_cast(std::clamp(right_sample, min, max)); + samples[write_index + static_cast(Channels::FrontLeft)] = + static_cast(std::clamp(left_sample, min, max)); + samples[write_index + static_cast(Channels::FrontRight)] = + static_cast(std::clamp(right_sample, min, max)); } samples.resize(samples.size() / system_channels * device_channels); + + } else if (system_channels == 2 && device_channels == 6) { + // We need moar samples! Not all games will provide 6 channel audio. + // TODO: Implement some upmixing here. Currently just passthrough, with other + // channels left as silence. + std::vector new_samples(samples.size() / system_channels * device_channels, 0); + + for (u32 read_index = 0, write_index = 0; read_index < samples.size(); + read_index += system_channels, write_index += device_channels) { + new_samples[write_index + static_cast(Channels::FrontLeft)] = + samples[read_index + static_cast(Channels::FrontLeft)]; + new_samples[write_index + static_cast(Channels::FrontRight)] = + samples[read_index + static_cast(Channels::FrontRight)]; + } + samples = std::move(new_samples); + } else if (volume != 1.0f) { for (u32 i = 0; i < samples.size(); i++) { - auto sample{Common::FixedPoint<49, 15>(samples[i]) * volume}; - samples[i] = static_cast(std::clamp(sample.to_int(), min, max)); + samples[i] = static_cast(std::clamp( + static_cast(static_cast(samples[i]) * volume), min, max)); } }