CircularBufferSink.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using Ryujinx.Audio.Renderer.Common;
  2. using Ryujinx.Audio.Renderer.Parameter;
  3. using Ryujinx.Audio.Renderer.Parameter.Sink;
  4. using Ryujinx.Audio.Renderer.Server.MemoryPool;
  5. using System.Diagnostics;
  6. using System.Runtime.InteropServices;
  7. namespace Ryujinx.Audio.Renderer.Server.Sink
  8. {
  9. /// <summary>
  10. /// Server information for a circular buffer sink.
  11. /// </summary>
  12. public class CircularBufferSink : BaseSink
  13. {
  14. /// <summary>
  15. /// The circular buffer parameter.
  16. /// </summary>
  17. public CircularBufferParameter Parameter;
  18. /// <summary>
  19. /// The last written data offset on the circular buffer.
  20. /// </summary>
  21. private uint _lastWrittenOffset;
  22. /// <summary>
  23. /// THe previous written offset of the circular buffer.
  24. /// </summary>
  25. private uint _oldWrittenOffset;
  26. /// <summary>
  27. /// The current offset to write data on the circular buffer.
  28. /// </summary>
  29. public uint CurrentWriteOffset { get; private set; }
  30. /// <summary>
  31. /// The <see cref="AddressInfo"/> of the circular buffer.
  32. /// </summary>
  33. public AddressInfo CircularBufferAddressInfo;
  34. public CircularBufferSink()
  35. {
  36. CircularBufferAddressInfo = AddressInfo.Create();
  37. }
  38. public override SinkType TargetSinkType => SinkType.CircularBuffer;
  39. public override void Update(out BehaviourParameter.ErrorInfo errorInfo, ref SinkInParameter parameter, ref SinkOutStatus outStatus, PoolMapper mapper)
  40. {
  41. errorInfo = new BehaviourParameter.ErrorInfo();
  42. outStatus = new SinkOutStatus();
  43. Debug.Assert(IsTypeValid(ref parameter));
  44. ref CircularBufferParameter inputDeviceParameter = ref MemoryMarshal.Cast<byte, CircularBufferParameter>(parameter.SpecificData)[0];
  45. if (parameter.IsUsed != IsUsed || ShouldSkip)
  46. {
  47. UpdateStandardParameter(ref parameter);
  48. if (parameter.IsUsed)
  49. {
  50. Debug.Assert(CircularBufferAddressInfo.CpuAddress == 0);
  51. Debug.Assert(CircularBufferAddressInfo.GetReference(false) == 0);
  52. ShouldSkip = !mapper.TryAttachBuffer(out errorInfo, ref CircularBufferAddressInfo, inputDeviceParameter.BufferAddress, inputDeviceParameter.BufferSize);
  53. }
  54. else
  55. {
  56. Debug.Assert(CircularBufferAddressInfo.CpuAddress != 0);
  57. Debug.Assert(CircularBufferAddressInfo.GetReference(false) != 0);
  58. }
  59. Parameter = inputDeviceParameter;
  60. }
  61. outStatus.LastWrittenOffset = _lastWrittenOffset;
  62. }
  63. public override void UpdateForCommandGeneration()
  64. {
  65. Debug.Assert(Type == TargetSinkType);
  66. if (IsUsed)
  67. {
  68. uint frameSize = Constants.TargetSampleSize * Parameter.SampleCount * Parameter.InputCount;
  69. _lastWrittenOffset = _oldWrittenOffset;
  70. _oldWrittenOffset = CurrentWriteOffset;
  71. CurrentWriteOffset += frameSize;
  72. if (Parameter.BufferSize > 0)
  73. {
  74. CurrentWriteOffset %= Parameter.BufferSize;
  75. }
  76. }
  77. }
  78. public override void CleanUp()
  79. {
  80. CircularBufferAddressInfo = AddressInfo.Create();
  81. _lastWrittenOffset = 0;
  82. _oldWrittenOffset = 0;
  83. CurrentWriteOffset = 0;
  84. base.CleanUp();
  85. }
  86. }
  87. }