summaryrefslogtreecommitdiff
path: root/src/audio_core/delay_line.cpp
diff options
context:
space:
mode:
authorGravatar Chloe Marcec2021-02-11 18:46:20 +1100
committerGravatar bunnei2021-02-12 18:48:10 -0800
commit4a7fd91857a95dd9ba7c838384671b2a83e46e7d (patch)
tree77dc77e963c2ce5e386d747b76ba19bec89a92b6 /src/audio_core/delay_line.cpp
parentMerge pull request #5877 from ameerj/res-limit-usage (diff)
downloadyuzu-4a7fd91857a95dd9ba7c838384671b2a83e46e7d.tar.gz
yuzu-4a7fd91857a95dd9ba7c838384671b2a83e46e7d.tar.xz
yuzu-4a7fd91857a95dd9ba7c838384671b2a83e46e7d.zip
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.cpp103
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 000000000..c8bc6e23e
--- /dev/null
+++ b/src/audio_core/delay_line.cpp
@@ -0,0 +1,103 @@
1#include "audio_core/delay_line.h"
2
3namespace AudioCore {
4DelayLineBase::DelayLineBase() = default;
5DelayLineBase::~DelayLineBase() = default;
6
7void DelayLineBase::Initialize(s32 _max_delay, float* src_buffer) {
8 buffer = src_buffer;
9 buffer_end = buffer + _max_delay;
10 max_delay = _max_delay;
11 output = buffer;
12 SetDelay(_max_delay);
13 Clear();
14}
15
16void DelayLineBase::SetDelay(s32 new_delay) {
17 if (max_delay < new_delay) {
18 return;
19 }
20 delay = new_delay;
21 input = (buffer + ((output - buffer) + new_delay) % (max_delay + 1));
22}
23
24s32 DelayLineBase::GetDelay() const {
25 return delay;
26}
27
28s32 DelayLineBase::GetMaxDelay() const {
29 return max_delay;
30}
31
32f32 DelayLineBase::TapOut(s32 last_sample) {
33 float* ptr = input - (last_sample + 1);
34 if (ptr < buffer) {
35 ptr += (max_delay + 1);
36 }
37
38 return *ptr;
39}
40
41f32 DelayLineBase::Tick(f32 sample) {
42 *(input++) = sample;
43 const auto out_sample = *(output++);
44
45 if (buffer_end < input) {
46 input = buffer;
47 }
48
49 if (buffer_end < output) {
50 output = buffer;
51 }
52
53 return out_sample;
54}
55
56float* DelayLineBase::GetInput() {
57 return input;
58}
59
60const float* DelayLineBase::GetInput() const {
61 return input;
62}
63
64f32 DelayLineBase::GetOutputSample() const {
65 return *output;
66}
67
68void DelayLineBase::Clear() {
69 std::memset(buffer, 0, sizeof(float) * max_delay);
70}
71
72void DelayLineBase::Reset() {
73 buffer = nullptr;
74 buffer_end = nullptr;
75 max_delay = 0;
76 input = nullptr;
77 output = nullptr;
78 delay = 0;
79}
80
81DelayLineAllPass::DelayLineAllPass() = default;
82DelayLineAllPass::~DelayLineAllPass() = default;
83
84void DelayLineAllPass::Initialize(u32 delay, float _coeffcient, f32* src_buffer) {
85 DelayLineBase::Initialize(delay, src_buffer);
86 SetCoefficient(_coeffcient);
87}
88
89void DelayLineAllPass::SetCoefficient(float _coeffcient) {
90 coefficient = _coeffcient;
91}
92
93f32 DelayLineAllPass::Tick(f32 sample) {
94 const auto temp = sample - coefficient * *output;
95 return coefficient * temp + DelayLineBase::Tick(temp);
96}
97
98void DelayLineAllPass::Reset() {
99 coefficient = 0.0f;
100 DelayLineBase::Reset();
101}
102
103} // namespace AudioCore