DepopForMixBuffersCommand.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.CompilerServices;
  4. namespace Ryujinx.Audio.Renderer.Dsp.Command
  5. {
  6. public class DepopForMixBuffersCommand : ICommand
  7. {
  8. public bool Enabled { get; set; }
  9. public int NodeId { get; }
  10. public CommandType CommandType => CommandType.DepopForMixBuffers;
  11. public ulong EstimatedProcessingTime { get; set; }
  12. public uint MixBufferOffset { get; }
  13. public uint MixBufferCount { get; }
  14. public float Decay { get; }
  15. public Memory<float> DepopBuffer { get; }
  16. public DepopForMixBuffersCommand(Memory<float> depopBuffer, uint bufferOffset, uint mixBufferCount, int nodeId, uint sampleRate)
  17. {
  18. Enabled = true;
  19. NodeId = nodeId;
  20. MixBufferOffset = bufferOffset;
  21. MixBufferCount = mixBufferCount;
  22. DepopBuffer = depopBuffer;
  23. if (sampleRate == 48000)
  24. {
  25. Decay = 0.962189f;
  26. }
  27. else // if (sampleRate == 32000)
  28. {
  29. Decay = 0.943695f;
  30. }
  31. }
  32. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  33. private unsafe float ProcessDepopMix(float* buffer, float depopValue, uint sampleCount)
  34. {
  35. if (depopValue < 0)
  36. {
  37. depopValue = -depopValue;
  38. for (int i = 0; i < sampleCount; i++)
  39. {
  40. depopValue = FloatingPointHelper.MultiplyRoundDown(Decay, depopValue);
  41. buffer[i] -= depopValue;
  42. }
  43. return -depopValue;
  44. }
  45. else
  46. {
  47. for (int i = 0; i < sampleCount; i++)
  48. {
  49. depopValue = FloatingPointHelper.MultiplyRoundDown(Decay, depopValue);
  50. buffer[i] += depopValue;
  51. }
  52. return depopValue;
  53. }
  54. }
  55. public void Process(CommandList context)
  56. {
  57. Span<float> depopBuffer = DepopBuffer.Span;
  58. uint bufferCount = Math.Min(MixBufferOffset + MixBufferCount, context.BufferCount);
  59. for (int i = (int)MixBufferOffset; i < bufferCount; i++)
  60. {
  61. float depopValue = depopBuffer[i];
  62. if (depopValue != 0)
  63. {
  64. unsafe
  65. {
  66. float* buffer = (float*)context.GetBufferPointer(i);
  67. depopBuffer[i] = ProcessDepopMix(buffer, depopValue, context.SampleCount);
  68. }
  69. }
  70. }
  71. }
  72. }
  73. }