delay_line.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <cstring>
  4. #include "audio_core/delay_line.h"
  5. namespace AudioCore {
  6. DelayLineBase::DelayLineBase() = default;
  7. DelayLineBase::~DelayLineBase() = default;
  8. void DelayLineBase::Initialize(s32 max_delay_, float* src_buffer) {
  9. buffer = src_buffer;
  10. buffer_end = buffer + max_delay_;
  11. max_delay = max_delay_;
  12. output = buffer;
  13. SetDelay(max_delay_);
  14. Clear();
  15. }
  16. void 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. s32 DelayLineBase::GetDelay() const {
  24. return delay;
  25. }
  26. s32 DelayLineBase::GetMaxDelay() const {
  27. return max_delay;
  28. }
  29. f32 DelayLineBase::TapOut(s32 last_sample) {
  30. const float* ptr = input - (last_sample + 1);
  31. if (ptr < buffer) {
  32. ptr += (max_delay + 1);
  33. }
  34. return *ptr;
  35. }
  36. f32 DelayLineBase::Tick(f32 sample) {
  37. *(input++) = sample;
  38. const auto out_sample = *(output++);
  39. if (buffer_end < input) {
  40. input = buffer;
  41. }
  42. if (buffer_end < output) {
  43. output = buffer;
  44. }
  45. return out_sample;
  46. }
  47. float* DelayLineBase::GetInput() {
  48. return input;
  49. }
  50. const float* DelayLineBase::GetInput() const {
  51. return input;
  52. }
  53. f32 DelayLineBase::GetOutputSample() const {
  54. return *output;
  55. }
  56. void DelayLineBase::Clear() {
  57. std::memset(buffer, 0, sizeof(float) * max_delay);
  58. }
  59. void DelayLineBase::Reset() {
  60. buffer = nullptr;
  61. buffer_end = nullptr;
  62. max_delay = 0;
  63. input = nullptr;
  64. output = nullptr;
  65. delay = 0;
  66. }
  67. DelayLineAllPass::DelayLineAllPass() = default;
  68. DelayLineAllPass::~DelayLineAllPass() = default;
  69. void DelayLineAllPass::Initialize(u32 delay_, float coeffcient_, f32* src_buffer) {
  70. DelayLineBase::Initialize(delay_, src_buffer);
  71. SetCoefficient(coeffcient_);
  72. }
  73. void DelayLineAllPass::SetCoefficient(float coeffcient_) {
  74. coefficient = coeffcient_;
  75. }
  76. f32 DelayLineAllPass::Tick(f32 sample) {
  77. const auto temp = sample - coefficient * *output;
  78. return coefficient * temp + DelayLineBase::Tick(temp);
  79. }
  80. void DelayLineAllPass::Reset() {
  81. coefficient = 0.0f;
  82. DelayLineBase::Reset();
  83. }
  84. } // namespace AudioCore