DelayLine.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using System;
  2. namespace Ryujinx.Audio.Renderer.Dsp.Effect
  3. {
  4. public class DelayLine : IDelayLine
  5. {
  6. private float[] _workBuffer;
  7. private uint _sampleRate;
  8. private uint _currentSampleIndex;
  9. private uint _lastSampleIndex;
  10. public uint CurrentSampleCount { get; private set; }
  11. public uint SampleCountMax { get; private set; }
  12. public DelayLine(uint sampleRate, float delayTimeMax)
  13. {
  14. _sampleRate = sampleRate;
  15. SampleCountMax = IDelayLine.GetSampleCount(_sampleRate, delayTimeMax);
  16. _workBuffer = new float[SampleCountMax + 1];
  17. SetDelay(delayTimeMax);
  18. }
  19. private void ConfigureDelay(uint targetSampleCount)
  20. {
  21. CurrentSampleCount = Math.Min(SampleCountMax, targetSampleCount);
  22. _currentSampleIndex = 0;
  23. if (CurrentSampleCount == 0)
  24. {
  25. _lastSampleIndex = 0;
  26. }
  27. else
  28. {
  29. _lastSampleIndex = CurrentSampleCount - 1;
  30. }
  31. }
  32. public void SetDelay(float delayTime)
  33. {
  34. ConfigureDelay(IDelayLine.GetSampleCount(_sampleRate, delayTime));
  35. }
  36. public float Read()
  37. {
  38. return _workBuffer[_currentSampleIndex];
  39. }
  40. public float Update(float value)
  41. {
  42. float output = Read();
  43. _workBuffer[_currentSampleIndex++] = value;
  44. if (_currentSampleIndex >= _lastSampleIndex)
  45. {
  46. _currentSampleIndex = 0;
  47. }
  48. return output;
  49. }
  50. public float TapUnsafe(uint sampleIndex, int offset)
  51. {
  52. return IDelayLine.Tap(_workBuffer, (int)_currentSampleIndex, (int)sampleIndex + offset, (int)CurrentSampleCount);
  53. }
  54. public float Tap(uint sampleIndex)
  55. {
  56. if (sampleIndex >= CurrentSampleCount)
  57. {
  58. sampleIndex = CurrentSampleCount - 1;
  59. }
  60. return TapUnsafe(sampleIndex, -1);
  61. }
  62. }
  63. }