2021-12-05 22:18:53 +01:00
|
|
|
// Copyright 2021 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
2021-02-11 09:17:50 +01:00
|
|
|
#include <cstring>
|
2021-02-11 08:46:20 +01:00
|
|
|
#include "audio_core/delay_line.h"
|
|
|
|
|
|
|
|
namespace AudioCore {
|
|
|
|
DelayLineBase::DelayLineBase() = default;
|
|
|
|
DelayLineBase::~DelayLineBase() = default;
|
|
|
|
|
2021-02-11 09:17:50 +01:00
|
|
|
void DelayLineBase::Initialize(s32 max_delay_, float* src_buffer) {
|
2021-02-11 08:46:20 +01:00
|
|
|
buffer = src_buffer;
|
2021-02-11 09:17:50 +01:00
|
|
|
buffer_end = buffer + max_delay_;
|
|
|
|
max_delay = max_delay_;
|
2021-02-11 08:46:20 +01:00
|
|
|
output = buffer;
|
2021-02-11 09:17:50 +01:00
|
|
|
SetDelay(max_delay_);
|
2021-02-11 08:46:20 +01:00
|
|
|
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) {
|
2021-02-11 09:17:50 +01:00
|
|
|
const float* ptr = input - (last_sample + 1);
|
2021-02-11 08:46:20 +01:00
|
|
|
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;
|
|
|
|
|
2021-02-11 09:17:50 +01:00
|
|
|
void DelayLineAllPass::Initialize(u32 delay_, float coeffcient_, f32* src_buffer) {
|
|
|
|
DelayLineBase::Initialize(delay_, src_buffer);
|
|
|
|
SetCoefficient(coeffcient_);
|
2021-02-11 08:46:20 +01:00
|
|
|
}
|
|
|
|
|
2021-02-11 09:17:50 +01:00
|
|
|
void DelayLineAllPass::SetCoefficient(float coeffcient_) {
|
|
|
|
coefficient = coeffcient_;
|
2021-02-11 08:46:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|