From 4a7fd91857a95dd9ba7c838384671b2a83e46e7d Mon Sep 17 00:00:00 2001 From: Chloe Marcec Date: Thu, 11 Feb 2021 18:46:20 +1100 Subject: audren: Implement I3dl2Reverb Most notable fix is the voices in Fire Emblem Three Houses --- src/audio_core/delay_line.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/audio_core/delay_line.cpp (limited to 'src/audio_core/delay_line.cpp') diff --git a/src/audio_core/delay_line.cpp b/src/audio_core/delay_line.cpp new file mode 100644 index 000000000..c8bc6e23e --- /dev/null +++ b/src/audio_core/delay_line.cpp @@ -0,0 +1,103 @@ +#include "audio_core/delay_line.h" + +namespace AudioCore { +DelayLineBase::DelayLineBase() = default; +DelayLineBase::~DelayLineBase() = default; + +void DelayLineBase::Initialize(s32 _max_delay, float* src_buffer) { + buffer = src_buffer; + buffer_end = buffer + _max_delay; + max_delay = _max_delay; + output = buffer; + SetDelay(_max_delay); + Clear(); +} + +void DelayLineBase::SetDelay(s32 new_delay) { + if (max_delay < new_delay) { + return; + } + delay = new_delay; + input = (buffer + ((output - buffer) + new_delay) % (max_delay + 1)); +} + +s32 DelayLineBase::GetDelay() const { + return delay; +} + +s32 DelayLineBase::GetMaxDelay() const { + return max_delay; +} + +f32 DelayLineBase::TapOut(s32 last_sample) { + float* ptr = input - (last_sample + 1); + if (ptr < buffer) { + ptr += (max_delay + 1); + } + + return *ptr; +} + +f32 DelayLineBase::Tick(f32 sample) { + *(input++) = sample; + const auto out_sample = *(output++); + + if (buffer_end < input) { + input = buffer; + } + + if (buffer_end < output) { + output = buffer; + } + + return out_sample; +} + +float* DelayLineBase::GetInput() { + return input; +} + +const float* DelayLineBase::GetInput() const { + return input; +} + +f32 DelayLineBase::GetOutputSample() const { + return *output; +} + +void DelayLineBase::Clear() { + std::memset(buffer, 0, sizeof(float) * max_delay); +} + +void DelayLineBase::Reset() { + buffer = nullptr; + buffer_end = nullptr; + max_delay = 0; + input = nullptr; + output = nullptr; + delay = 0; +} + +DelayLineAllPass::DelayLineAllPass() = default; +DelayLineAllPass::~DelayLineAllPass() = default; + +void DelayLineAllPass::Initialize(u32 delay, float _coeffcient, f32* src_buffer) { + DelayLineBase::Initialize(delay, src_buffer); + SetCoefficient(_coeffcient); +} + +void DelayLineAllPass::SetCoefficient(float _coeffcient) { + coefficient = _coeffcient; +} + +f32 DelayLineAllPass::Tick(f32 sample) { + const auto temp = sample - coefficient * *output; + return coefficient * temp + DelayLineBase::Tick(temp); +} + +void DelayLineAllPass::Reset() { + coefficient = 0.0f; + DelayLineBase::Reset(); +} + +} // namespace AudioCore -- cgit v1.2.3