diff options
author | Chloe Marcec <dmarcecguzman@gmail.com> | 2021-02-11 18:46:20 +1100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2021-02-12 18:48:10 -0800 |
commit | 4a7fd91857a95dd9ba7c838384671b2a83e46e7d (patch) | |
tree | 77dc77e963c2ce5e386d747b76ba19bec89a92b6 /src/audio_core/delay_line.cpp | |
parent | c86d770af945888c42e45eee2101ea7e0a39fd68 (diff) |
audren: Implement I3dl2Reverb
Most notable fix is the voices in Fire Emblem Three Houses
Diffstat (limited to 'src/audio_core/delay_line.cpp')
-rw-r--r-- | src/audio_core/delay_line.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/audio_core/delay_line.cpp b/src/audio_core/delay_line.cpp new file mode 100644 index 0000000000..c8bc6e23e5 --- /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 |