diff options
Diffstat (limited to 'src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp')
-rw-r--r-- | src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp b/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp new file mode 100644 index 000000000..c2bc10061 --- /dev/null +++ b/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp @@ -0,0 +1,64 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "audio_core/common/common.h" +#include "audio_core/renderer/adsp/command_list_processor.h" +#include "audio_core/renderer/command/mix/depop_for_mix_buffers.h" + +namespace AudioCore::AudioRenderer { +/** + * Apply depopping. Add the depopped sample to each incoming new sample, decaying it each time + * according to decay. + * + * @param output - Output buffer to be depopped. + * @param depop_sample - Depopped sample to apply to output samples. + * @param decay_ - Amount to decay the depopped sample for every output sample. + * @param sample_count - Samples to process. + * @return Final decayed depop sample. + */ +static s32 ApplyDepopMix(std::span<s32> output, const s32 depop_sample, + Common::FixedPoint<49, 15>& decay_, const u32 sample_count) { + auto sample{std::abs(depop_sample)}; + auto decay{decay_.to_raw()}; + + if (depop_sample <= 0) { + for (u32 i = 0; i < sample_count; i++) { + sample = static_cast<s32>((static_cast<s64>(sample) * decay) >> 15); + output[i] -= sample; + } + return -sample; + } else { + for (u32 i = 0; i < sample_count; i++) { + sample = static_cast<s32>((static_cast<s64>(sample) * decay) >> 15); + output[i] += sample; + } + return sample; + } +} + +void DepopForMixBuffersCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor& processor, + std::string& string) { + string += fmt::format("DepopForMixBuffersCommand\n\tinput {:02X} count {} decay {}\n", input, + count, decay.to_float()); +} + +void DepopForMixBuffersCommand::Process(const ADSP::CommandListProcessor& processor) { + auto end_index{std::min(processor.buffer_count, input + count)}; + std::span<s32> depop_buff{reinterpret_cast<s32*>(depop_buffer), end_index}; + + for (u32 index = input; index < end_index; index++) { + const auto depop_sample{depop_buff[index]}; + if (depop_sample != 0) { + auto input_buffer{processor.mix_buffers.subspan(index * processor.sample_count, + processor.sample_count)}; + depop_buff[index] = + ApplyDepopMix(input_buffer, depop_sample, decay, processor.sample_count); + } + } +} + +bool DepopForMixBuffersCommand::Verify(const ADSP::CommandListProcessor& processor) { + return true; +} + +} // namespace AudioCore::AudioRenderer |