MixRampGroupedCommand.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using Ryujinx.Audio.Renderer.Common;
  2. using System;
  3. using System.Runtime.CompilerServices;
  4. namespace Ryujinx.Audio.Renderer.Dsp.Command
  5. {
  6. public class MixRampGroupedCommand : ICommand
  7. {
  8. public bool Enabled { get; set; }
  9. public int NodeId { get; }
  10. public CommandType CommandType => CommandType.MixRampGrouped;
  11. public uint EstimatedProcessingTime { get; set; }
  12. public uint MixBufferCount { get; }
  13. public ushort[] InputBufferIndices { get; }
  14. public ushort[] OutputBufferIndices { get; }
  15. public float[] Volume0 { get; }
  16. public float[] Volume1 { get; }
  17. public Memory<VoiceUpdateState> State { get; }
  18. public MixRampGroupedCommand(uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, Span<float> volume0, Span<float> volume1, Memory<VoiceUpdateState> state, int nodeId)
  19. {
  20. Enabled = true;
  21. MixBufferCount = mixBufferCount;
  22. NodeId = nodeId;
  23. InputBufferIndices = new ushort[Constants.MixBufferCountMax];
  24. OutputBufferIndices = new ushort[Constants.MixBufferCountMax];
  25. Volume0 = new float[Constants.MixBufferCountMax];
  26. Volume1 = new float[Constants.MixBufferCountMax];
  27. for (int i = 0; i < mixBufferCount; i++)
  28. {
  29. InputBufferIndices[i] = (ushort)inputBufferIndex;
  30. OutputBufferIndices[i] = (ushort)(outputBufferIndex + i);
  31. Volume0[i] = volume0[i];
  32. Volume1[i] = volume1[i];
  33. }
  34. State = state;
  35. }
  36. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  37. private float ProcessMixRampGrouped(Span<float> outputBuffer, ReadOnlySpan<float> inputBuffer, float volume0, float volume1, int sampleCount)
  38. {
  39. float ramp = (volume1 - volume0) / sampleCount;
  40. float volume = volume0;
  41. float state = 0;
  42. for (int i = 0; i < sampleCount; i++)
  43. {
  44. state = FloatingPointHelper.MultiplyRoundUp(inputBuffer[i], volume);
  45. outputBuffer[i] += state;
  46. volume += ramp;
  47. }
  48. return state;
  49. }
  50. public void Process(CommandList context)
  51. {
  52. for (int i = 0; i < MixBufferCount; i++)
  53. {
  54. ReadOnlySpan<float> inputBuffer = context.GetBuffer(InputBufferIndices[i]);
  55. Span<float> outputBuffer = context.GetBuffer(OutputBufferIndices[i]);
  56. float volume0 = Volume0[i];
  57. float volume1 = Volume1[i];
  58. ref VoiceUpdateState state = ref State.Span[0];
  59. if (volume0 != 0 || volume1 != 0)
  60. {
  61. state.LastSamples[i] = ProcessMixRampGrouped(outputBuffer, inputBuffer, volume0, volume1, (int)context.SampleCount);
  62. }
  63. else
  64. {
  65. state.LastSamples[i] = 0;
  66. }
  67. }
  68. }
  69. }
  70. }