summaryrefslogtreecommitdiffstats
path: root/src/audio_core/delay_line.cpp
blob: 2793ed8db63a4c51bdec448e75c1bd58441d01af (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#include <cstring>
#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) {
    const 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