DownMixSurroundToStereoCommand.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. namespace Ryujinx.Audio.Renderer.Dsp.Command
  4. {
  5. public class DownMixSurroundToStereoCommand : ICommand
  6. {
  7. public bool Enabled { get; set; }
  8. public int NodeId { get; }
  9. public CommandType CommandType => CommandType.DownMixSurroundToStereo;
  10. public uint EstimatedProcessingTime { get; set; }
  11. public ushort[] InputBufferIndices { get; }
  12. public ushort[] OutputBufferIndices { get; }
  13. public float[] Coefficients { get; }
  14. public DownMixSurroundToStereoCommand(uint bufferOffset, Span<byte> inputBufferOffset, Span<byte> outputBufferOffset, float[] downMixParameter, int nodeId)
  15. {
  16. Enabled = true;
  17. NodeId = nodeId;
  18. InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
  19. OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
  20. for (int i = 0; i < Constants.VoiceChannelCountMax; i++)
  21. {
  22. InputBufferIndices[i] = (ushort)(bufferOffset + inputBufferOffset[i]);
  23. OutputBufferIndices[i] = (ushort)(bufferOffset + outputBufferOffset[i]);
  24. }
  25. Coefficients = downMixParameter;
  26. }
  27. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  28. private static float DownMixSurroundToStereo(ReadOnlySpan<float> coefficients, float back, float lfe, float center, float front)
  29. {
  30. return FloatingPointHelper.RoundUp(coefficients[3] * back + coefficients[2] * lfe + coefficients[1] * center + coefficients[0] * front);
  31. }
  32. public void Process(CommandList context)
  33. {
  34. ReadOnlySpan<float> frontLeft = context.GetBuffer(InputBufferIndices[0]);
  35. ReadOnlySpan<float> frontRight = context.GetBuffer(InputBufferIndices[1]);
  36. ReadOnlySpan<float> frontCenter = context.GetBuffer(InputBufferIndices[2]);
  37. ReadOnlySpan<float> lowFrequency = context.GetBuffer(InputBufferIndices[3]);
  38. ReadOnlySpan<float> backLeft = context.GetBuffer(InputBufferIndices[4]);
  39. ReadOnlySpan<float> backRight = context.GetBuffer(InputBufferIndices[5]);
  40. Span<float> stereoLeft = context.GetBuffer(OutputBufferIndices[0]);
  41. Span<float> stereoRight = context.GetBuffer(OutputBufferIndices[1]);
  42. for (int i = 0; i < context.SampleCount; i++)
  43. {
  44. stereoLeft[i] = DownMixSurroundToStereo(Coefficients, backLeft[i], lowFrequency[i], frontCenter[i], frontLeft[i]);
  45. stereoRight[i] = DownMixSurroundToStereo(Coefficients, backRight[i], lowFrequency[i], frontCenter[i], frontRight[i]);
  46. }
  47. context.ClearBuffer(OutputBufferIndices[2]);
  48. context.ClearBuffer(OutputBufferIndices[3]);
  49. context.ClearBuffer(OutputBufferIndices[4]);
  50. context.ClearBuffer(OutputBufferIndices[5]);
  51. }
  52. }
  53. }