summaryrefslogtreecommitdiffstats
path: root/src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/audio_core/renderer/command/mix/depop_for_mix_buffers.cpp64
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