DelayState.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using Ryujinx.Audio.Renderer.Dsp.Effect;
  2. using Ryujinx.Audio.Renderer.Parameter.Effect;
  3. using System.Runtime.CompilerServices;
  4. namespace Ryujinx.Audio.Renderer.Dsp.State
  5. {
  6. public class DelayState
  7. {
  8. public DelayLine[] DelayLines { get; }
  9. public float[] LowPassZ { get; set; }
  10. public float FeedbackGain { get; private set; }
  11. public float DelayFeedbackBaseGain { get; private set; }
  12. public float DelayFeedbackCrossGain { get; private set; }
  13. public float LowPassFeedbackGain { get; private set; }
  14. public float LowPassBaseGain { get; private set; }
  15. private const int FixedPointPrecision = 14;
  16. public DelayState(ref DelayParameter parameter, ulong workBuffer)
  17. {
  18. DelayLines = new DelayLine[parameter.ChannelCount];
  19. LowPassZ = new float[parameter.ChannelCount];
  20. uint sampleRate = (uint)FixedPointHelper.ToInt(parameter.SampleRate, FixedPointPrecision) / 1000;
  21. for (int i = 0; i < DelayLines.Length; i++)
  22. {
  23. DelayLines[i] = new DelayLine(sampleRate, parameter.DelayTimeMax);
  24. DelayLines[i].SetDelay(parameter.DelayTime);
  25. }
  26. UpdateParameter(ref parameter);
  27. }
  28. public void UpdateParameter(ref DelayParameter parameter)
  29. {
  30. FeedbackGain = FixedPointHelper.ToFloat(parameter.FeedbackGain, FixedPointPrecision) * 0.98f;
  31. float channelSpread = FixedPointHelper.ToFloat(parameter.ChannelSpread, FixedPointPrecision);
  32. DelayFeedbackBaseGain = (1.0f - channelSpread) * FeedbackGain;
  33. if (parameter.ChannelCount == 4 || parameter.ChannelCount == 6)
  34. {
  35. DelayFeedbackCrossGain = channelSpread * 0.5f * FeedbackGain;
  36. }
  37. else
  38. {
  39. DelayFeedbackCrossGain = channelSpread * FeedbackGain;
  40. }
  41. LowPassFeedbackGain = 0.95f * FixedPointHelper.ToFloat(parameter.LowPassAmount, FixedPointPrecision);
  42. LowPassBaseGain = 1.0f - LowPassFeedbackGain;
  43. }
  44. public void UpdateLowPassFilter(ref float tempRawRef, uint channelCount)
  45. {
  46. for (int i = 0; i < channelCount; i++)
  47. {
  48. float lowPassResult = LowPassFeedbackGain * LowPassZ[i] + Unsafe.Add(ref tempRawRef, i) * LowPassBaseGain;
  49. LowPassZ[i] = lowPassResult;
  50. DelayLines[i].Update(lowPassResult);
  51. }
  52. }
  53. }
  54. }