DelayState.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //
  2. // Copyright (c) 2019-2021 Ryujinx
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. //
  17. using Ryujinx.Audio.Renderer.Dsp.Effect;
  18. using Ryujinx.Audio.Renderer.Parameter.Effect;
  19. using System.Runtime.CompilerServices;
  20. namespace Ryujinx.Audio.Renderer.Dsp.State
  21. {
  22. public class DelayState
  23. {
  24. public DelayLine[] DelayLines { get; }
  25. public float[] LowPassZ { get; set; }
  26. public float FeedbackGain { get; private set; }
  27. public float DelayFeedbackBaseGain { get; private set; }
  28. public float DelayFeedbackCrossGain { get; private set; }
  29. public float LowPassFeedbackGain { get; private set; }
  30. public float LowPassBaseGain { get; private set; }
  31. private const int FixedPointPrecision = 14;
  32. public DelayState(ref DelayParameter parameter, ulong workBuffer)
  33. {
  34. DelayLines = new DelayLine[parameter.ChannelCount];
  35. LowPassZ = new float[parameter.ChannelCount];
  36. uint sampleRate = (uint)FixedPointHelper.ToInt(parameter.SampleRate, FixedPointPrecision) / 1000;
  37. for (int i = 0; i < DelayLines.Length; i++)
  38. {
  39. DelayLines[i] = new DelayLine(sampleRate, parameter.DelayTimeMax);
  40. DelayLines[i].SetDelay(parameter.DelayTime);
  41. }
  42. UpdateParameter(ref parameter);
  43. }
  44. public void UpdateParameter(ref DelayParameter parameter)
  45. {
  46. FeedbackGain = FixedPointHelper.ToFloat(parameter.FeedbackGain, FixedPointPrecision) * 0.98f;
  47. float channelSpread = FixedPointHelper.ToFloat(parameter.ChannelSpread, FixedPointPrecision);
  48. DelayFeedbackBaseGain = (1.0f - channelSpread) * FeedbackGain;
  49. if (parameter.ChannelCount == 4 || parameter.ChannelCount == 6)
  50. {
  51. DelayFeedbackCrossGain = channelSpread * 0.5f * FeedbackGain;
  52. }
  53. else
  54. {
  55. DelayFeedbackCrossGain = channelSpread * FeedbackGain;
  56. }
  57. LowPassFeedbackGain = 0.95f * FixedPointHelper.ToFloat(parameter.LowPassAmount, FixedPointPrecision);
  58. LowPassBaseGain = 1.0f - LowPassFeedbackGain;
  59. }
  60. public void UpdateLowPassFilter(ref float tempRawRef, uint channelCount)
  61. {
  62. for (int i = 0; i < channelCount; i++)
  63. {
  64. float lowPassResult = LowPassFeedbackGain * LowPassZ[i] + Unsafe.Add(ref tempRawRef, i) * LowPassBaseGain;
  65. LowPassZ[i] = lowPassResult;
  66. DelayLines[i].Update(lowPassResult);
  67. }
  68. }
  69. }
  70. }