From 966966dc0260077b9e607995e1930afa1a2ecc40 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 25 Sep 2020 13:19:39 -0400 Subject: audio_core: Remove unnecessary inclusions Same behavior, but removes header dependencies where they don't need to be. --- src/audio_core/audio_renderer.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/audio_core/audio_renderer.cpp') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 56dc892b1..a7e851bb8 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -3,16 +3,13 @@ // Refer to the license.txt file included. #include -#include "audio_core/algorithm/interpolate.h" + #include "audio_core/audio_out.h" #include "audio_core/audio_renderer.h" -#include "audio_core/codec.h" #include "audio_core/common.h" #include "audio_core/info_updater.h" #include "audio_core/voice_context.h" -#include "common/assert.h" #include "common/logging/log.h" -#include "core/core.h" #include "core/hle/kernel/writable_event.h" #include "core/memory.h" #include "core/settings.h" -- cgit v1.2.3 From be1954e04cb5a0c3a526f78ed5490a5e65310280 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 15 Oct 2020 14:49:45 -0400 Subject: core: Fix clang build Recent changes to the build system that made more warnings be flagged as errors caused building via clang to break. Fixes #4795 --- src/audio_core/audio_renderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/audio_core/audio_renderer.cpp') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index a7e851bb8..094bace9c 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -187,8 +187,8 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { const auto& in_params = final_mix.GetInParams(); std::vector mix_buffers(channel_count); for (std::size_t i = 0; i < channel_count; i++) { - mix_buffers[i] = - command_generator.GetMixBuffer(in_params.buffer_offset + buffer_offsets[i]); + mix_buffers[i] = command_generator.GetMixBuffer( + static_cast(in_params.buffer_offset) + buffer_offsets[i]); } for (std::size_t i = 0; i < BUFFER_SIZE; i++) { -- cgit v1.2.3 From 3d592972dc3fd61cc88771b889eff237e4e03e0f Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Oct 2020 19:07:39 -0700 Subject: Revert "core: Fix clang build" --- src/audio_core/audio_renderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/audio_core/audio_renderer.cpp') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 094bace9c..a7e851bb8 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -187,8 +187,8 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { const auto& in_params = final_mix.GetInParams(); std::vector mix_buffers(channel_count); for (std::size_t i = 0; i < channel_count; i++) { - mix_buffers[i] = command_generator.GetMixBuffer( - static_cast(in_params.buffer_offset) + buffer_offsets[i]); + mix_buffers[i] = + command_generator.GetMixBuffer(in_params.buffer_offset + buffer_offsets[i]); } for (std::size_t i = 0; i < BUFFER_SIZE; i++) { -- cgit v1.2.3 From 9a4beac95a0f88ec312a28d06da8270aa58736e3 Mon Sep 17 00:00:00 2001 From: Chloe Marcec Date: Tue, 17 Nov 2020 14:14:29 +1100 Subject: audren: Make use of nodiscard, rework downmixing, release all buffers Preliminary work for upmixing & general cleanup. Fixes basic issues in games such as Shovel Knight and slightly improves the LEGO games. Upmixing stitll needs to be implemented. Audio levels in a few games will be fixed as we now use the downmix coefficients when possible instead of supplying our own --- src/audio_core/audio_renderer.cpp | 110 +++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 25 deletions(-) (limited to 'src/audio_core/audio_renderer.cpp') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index a7e851bb8..03a133640 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include "audio_core/audio_out.h" @@ -14,6 +15,59 @@ #include "core/memory.h" #include "core/settings.h" +namespace { +[[nodiscard]] static constexpr s16 ClampToS16(s32 value) { + return static_cast(std::clamp(value, static_cast(std::numeric_limits::min()), + static_cast(std::numeric_limits::max()))); +} + +[[nodiscard]] static constexpr s16 Mix2To1(s16 l_channel, s16 r_channel) { + // Mix 50% from left and 50% from right channel + constexpr float l_mix_amount = 50.0f / 100.0f; + constexpr float r_mix_amount = 50.0f / 100.0f; + return ClampToS16(static_cast((static_cast(l_channel) * l_mix_amount) + + (static_cast(r_channel) * r_mix_amount))); +} + +[[nodiscard]] static constexpr std::tuple Mix6To2(s16 fl_channel, s16 fr_channel, + s16 fc_channel, + [[maybe_unused]] s16 lf_channel, + s16 bl_channel, s16 br_channel) { + // Front channels are mixed 36.94%, Center channels are mixed to be 26.12% & the back channels + // are mixed to be 36.94% + + constexpr float front_mix_amount = 36.94f / 100.0f; + constexpr float center_mix_amount = 26.12f / 100.0f; + constexpr float back_mix_amount = 36.94f / 100.0f; + + // Mix 50% from left and 50% from right channel + const auto left = front_mix_amount * static_cast(fl_channel) + + center_mix_amount * static_cast(fc_channel) + + back_mix_amount * static_cast(bl_channel); + + const auto right = front_mix_amount * static_cast(fr_channel) + + center_mix_amount * static_cast(fc_channel) + + back_mix_amount * static_cast(br_channel); + + return {ClampToS16(static_cast(left)), ClampToS16(static_cast(right))}; +} + +[[nodiscard]] static constexpr std::tuple Mix6To2WithCoefficients( + s16 fl_channel, s16 fr_channel, s16 fc_channel, s16 lf_channel, s16 bl_channel, s16 br_channel, + const std::array& coeff) { + const auto left = + static_cast(fl_channel) * coeff[0] + static_cast(fc_channel) * coeff[1] + + static_cast(lf_channel) * coeff[2] + static_cast(bl_channel) * coeff[0]; + + const auto right = + static_cast(fr_channel) * coeff[0] + static_cast(fc_channel) * coeff[1] + + static_cast(lf_channel) * coeff[2] + static_cast(br_channel) * coeff[0]; + + return {ClampToS16(static_cast(left)), ClampToS16(static_cast(right))}; +} + +} // namespace + namespace AudioCore { AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, AudioCommon::AudioRendererParameter params, @@ -62,10 +116,6 @@ Stream::State AudioRenderer::GetStreamState() const { return stream->GetState(); } -static constexpr s16 ClampToS16(s32 value) { - return static_cast(std::clamp(value, -32768, 32767)); -} - ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector& input_params, std::vector& output_params) { @@ -104,8 +154,8 @@ ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector& input_param } } - auto mix_result = info_updater.UpdateMixes(mix_context, worker_params.mix_buffer_count, - splitter_context, effect_context); + const auto mix_result = info_updater.UpdateMixes(mix_context, worker_params.mix_buffer_count, + splitter_context, effect_context); if (mix_result.IsError()) { LOG_ERROR(Audio, "Failed to update mix parameters"); @@ -194,20 +244,22 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { for (std::size_t i = 0; i < BUFFER_SIZE; i++) { if (channel_count == 1) { const auto sample = ClampToS16(mix_buffers[0][i]); - buffer[i * stream_channel_count + 0] = sample; - if (stream_channel_count > 1) { - buffer[i * stream_channel_count + 1] = sample; + + // Place sample in all channels + for (u32 channel = 0; channel < stream_channel_count; channel++) { + buffer[i * stream_channel_count + channel] = sample; } + if (stream_channel_count == 6) { - buffer[i * stream_channel_count + 2] = sample; - buffer[i * stream_channel_count + 4] = sample; - buffer[i * stream_channel_count + 5] = sample; + // Output stream has a LF channel, mute it! + buffer[i * stream_channel_count + 3] = 0; } + } else if (channel_count == 2) { const auto l_sample = ClampToS16(mix_buffers[0][i]); const auto r_sample = ClampToS16(mix_buffers[1][i]); if (stream_channel_count == 1) { - buffer[i * stream_channel_count + 0] = l_sample; + buffer[i * stream_channel_count + 0] = Mix2To1(l_sample, r_sample); } else if (stream_channel_count == 2) { buffer[i * stream_channel_count + 0] = l_sample; buffer[i * stream_channel_count + 1] = r_sample; @@ -215,8 +267,8 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { buffer[i * stream_channel_count + 0] = l_sample; buffer[i * stream_channel_count + 1] = r_sample; - buffer[i * stream_channel_count + 2] = - ClampToS16((static_cast(l_sample) + static_cast(r_sample)) / 2); + // Combine both left and right channels to the center channel + buffer[i * stream_channel_count + 2] = Mix2To1(l_sample, r_sample); buffer[i * stream_channel_count + 4] = l_sample; buffer[i * stream_channel_count + 5] = r_sample; @@ -231,17 +283,25 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { const auto br_sample = ClampToS16(mix_buffers[5][i]); if (stream_channel_count == 1) { - buffer[i * stream_channel_count + 0] = fc_sample; + // Games seem to ignore the center channel half the time, we use the front left + // and right channel for mixing as that's where majority of the audio goes + buffer[i * stream_channel_count + 0] = Mix2To1(fl_sample, fr_sample); } else if (stream_channel_count == 2) { - buffer[i * stream_channel_count + 0] = - static_cast(0.3694f * static_cast(fl_sample) + - 0.2612f * static_cast(fc_sample) + - 0.3694f * static_cast(bl_sample)); - buffer[i * stream_channel_count + 1] = - static_cast(0.3694f * static_cast(fr_sample) + - 0.2612f * static_cast(fc_sample) + - 0.3694f * static_cast(br_sample)); + // Mix all channels into 2 channels + if (sink_context.HasDownMixingCoefficients()) { + const auto [left, right] = Mix6To2WithCoefficients( + fl_sample, fr_sample, fc_sample, lf_sample, bl_sample, br_sample, + sink_context.GetDownmixCoefficients()); + buffer[i * stream_channel_count + 0] = left; + buffer[i * stream_channel_count + 1] = right; + } else { + const auto [left, right] = Mix6To2(fl_sample, fr_sample, fc_sample, + lf_sample, bl_sample, br_sample); + buffer[i * stream_channel_count + 0] = left; + buffer[i * stream_channel_count + 1] = right; + } } else if (stream_channel_count == 6) { + // Pass through buffer[i * stream_channel_count + 0] = fl_sample; buffer[i * stream_channel_count + 1] = fr_sample; buffer[i * stream_channel_count + 2] = fc_sample; @@ -259,7 +319,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { } void AudioRenderer::ReleaseAndQueueBuffers() { - const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream, 2)}; + const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream)}; for (const auto& tag : released_buffers) { QueueMixedBuffer(tag); } -- cgit v1.2.3 From 908d3c56793ee67dccd0d370b175c4937420053f Mon Sep 17 00:00:00 2001 From: Chloe Marcec Date: Tue, 17 Nov 2020 15:40:19 +1100 Subject: Addressed changes --- src/audio_core/audio_renderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/audio_core/audio_renderer.cpp') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 03a133640..e1ded84e0 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -17,8 +17,8 @@ namespace { [[nodiscard]] static constexpr s16 ClampToS16(s32 value) { - return static_cast(std::clamp(value, static_cast(std::numeric_limits::min()), - static_cast(std::numeric_limits::max()))); + return static_cast(std::clamp(value, s32{std::numeric_limits::min()}, + s32{std::numeric_limits::max()})); } [[nodiscard]] static constexpr s16 Mix2To1(s16 l_channel, s16 r_channel) { -- cgit v1.2.3 From d7019d8307bf8db1d985e3a537bd83289cf1a3de Mon Sep 17 00:00:00 2001 From: Chloe Marcec Date: Sat, 28 Nov 2020 23:25:28 +1100 Subject: audio_core: Remove temp_mix_buffer It's unused and doesn't need to be initialized --- src/audio_core/audio_renderer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/audio_core/audio_renderer.cpp') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index e1ded84e0..5f532ed31 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -79,8 +79,7 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory sink_context(params.sink_count), splitter_context(), voices(params.voice_count), memory{memory_}, command_generator(worker_params, voice_context, mix_context, splitter_context, effect_context, - memory), - temp_mix_buffer(AudioCommon::TOTAL_TEMP_MIX_SIZE) { + memory) { behavior_info.SetUserRevision(params.revision); splitter_context.Initialize(behavior_info, params.splitter_count, params.num_splitter_send_channels); -- cgit v1.2.3 From 1ea6bdef058a789e2771511f741bffcca73c3525 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 25 Nov 2020 15:21:03 -0500 Subject: audio_core: Make shadowing and unused parameters errors Moves the audio code closer to enabling warnings as errors in general. --- src/audio_core/audio_renderer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/audio_core/audio_renderer.cpp') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index e1ded84e0..75ab9ea0b 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -71,9 +71,9 @@ namespace { namespace AudioCore { AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, AudioCommon::AudioRendererParameter params, - std::shared_ptr buffer_event, + std::shared_ptr buffer_event_, std::size_t instance_number) - : worker_params{params}, buffer_event{buffer_event}, + : worker_params{params}, buffer_event{buffer_event_}, memory_pool_info(params.effect_count + params.voice_count * 4), voice_context(params.voice_count), effect_context(params.effect_count), mix_context(), sink_context(params.sink_count), splitter_context(), @@ -89,7 +89,7 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory stream = audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS, fmt::format("AudioRenderer-Instance{}", instance_number), - [=]() { buffer_event->Signal(); }); + [=]() { buffer_event_->Signal(); }); audio_out->StartStream(stream); QueueMixedBuffer(0); -- cgit v1.2.3 From 7d77a3f88f7a1e68d9846ca7c69cce051d1a33d2 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 28 Dec 2020 18:23:42 -0800 Subject: hle: service: Acquire and release a lock on requests. - This makes it such that we can safely access service members from CoreTiming thread. --- src/audio_core/audio_renderer.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src/audio_core/audio_renderer.cpp') diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 179560cd7..d2ce8c814 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -11,7 +11,6 @@ #include "audio_core/info_updater.h" #include "audio_core/voice_context.h" #include "common/logging/log.h" -#include "core/hle/kernel/writable_event.h" #include "core/memory.h" #include "core/settings.h" @@ -71,10 +70,9 @@ namespace { namespace AudioCore { AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, AudioCommon::AudioRendererParameter params, - std::shared_ptr buffer_event_, + Stream::ReleaseCallback&& release_callback, std::size_t instance_number) - : worker_params{params}, buffer_event{buffer_event_}, - memory_pool_info(params.effect_count + params.voice_count * 4), + : worker_params{params}, memory_pool_info(params.effect_count + params.voice_count * 4), voice_context(params.voice_count), effect_context(params.effect_count), mix_context(), sink_context(params.sink_count), splitter_context(), voices(params.voice_count), memory{memory_}, @@ -85,10 +83,9 @@ AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory params.num_splitter_send_channels); mix_context.Initialize(behavior_info, params.submix_count + 1, params.effect_count); audio_out = std::make_unique(); - stream = - audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS, - fmt::format("AudioRenderer-Instance{}", instance_number), - [=]() { buffer_event_->Signal(); }); + stream = audio_out->OpenStream( + core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS, + fmt::format("AudioRenderer-Instance{}", instance_number), std::move(release_callback)); audio_out->StartStream(stream); QueueMixedBuffer(0); -- cgit v1.2.3