CompatLayerHardwareDeviceSession.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using Ryujinx.Audio.Backends.Common;
  2. using Ryujinx.Audio.Common;
  3. using Ryujinx.Audio.Renderer.Dsp;
  4. using System;
  5. using System.Runtime.InteropServices;
  6. namespace Ryujinx.Audio.Backends.CompatLayer
  7. {
  8. class CompatLayerHardwareDeviceSession : HardwareDeviceSessionOutputBase
  9. {
  10. private HardwareDeviceSessionOutputBase _realSession;
  11. private SampleFormat _userSampleFormat;
  12. private uint _userChannelCount;
  13. public CompatLayerHardwareDeviceSession(HardwareDeviceSessionOutputBase realSession, SampleFormat userSampleFormat, uint userChannelCount) : base(realSession.MemoryManager, realSession.RequestedSampleFormat, realSession.RequestedSampleRate, userChannelCount)
  14. {
  15. _realSession = realSession;
  16. _userSampleFormat = userSampleFormat;
  17. _userChannelCount = userChannelCount;
  18. }
  19. public override void Dispose()
  20. {
  21. _realSession.Dispose();
  22. }
  23. public override ulong GetPlayedSampleCount()
  24. {
  25. return _realSession.GetPlayedSampleCount();
  26. }
  27. public override float GetVolume()
  28. {
  29. return _realSession.GetVolume();
  30. }
  31. public override void PrepareToClose()
  32. {
  33. _realSession.PrepareToClose();
  34. }
  35. public override void QueueBuffer(AudioBuffer buffer)
  36. {
  37. SampleFormat realSampleFormat = _realSession.RequestedSampleFormat;
  38. if (_userSampleFormat != realSampleFormat)
  39. {
  40. if (_userSampleFormat != SampleFormat.PcmInt16)
  41. {
  42. throw new NotImplementedException("Converting formats other than PCM16 is not supported.");
  43. }
  44. int userSampleCount = buffer.Data.Length / BackendHelper.GetSampleSize(_userSampleFormat);
  45. ReadOnlySpan<short> samples = MemoryMarshal.Cast<byte, short>(buffer.Data);
  46. byte[] convertedSamples = new byte[BackendHelper.GetSampleSize(realSampleFormat) * userSampleCount];
  47. switch (realSampleFormat)
  48. {
  49. case SampleFormat.PcmInt8:
  50. PcmHelper.ConvertSampleToPcm8(MemoryMarshal.Cast<byte, sbyte>(convertedSamples), samples);
  51. break;
  52. case SampleFormat.PcmInt24:
  53. PcmHelper.ConvertSampleToPcm24(convertedSamples, samples);
  54. break;
  55. case SampleFormat.PcmInt32:
  56. PcmHelper.ConvertSampleToPcm32(MemoryMarshal.Cast<byte, int>(convertedSamples), samples);
  57. break;
  58. case SampleFormat.PcmFloat:
  59. PcmHelper.ConvertSampleToPcmFloat(MemoryMarshal.Cast<byte, float>(convertedSamples), samples);
  60. break;
  61. default:
  62. throw new NotImplementedException($"Sample format conversion from {_userSampleFormat} to {realSampleFormat} not implemented.");
  63. }
  64. buffer.Data = convertedSamples;
  65. }
  66. _realSession.QueueBuffer(buffer);
  67. }
  68. public override bool RegisterBuffer(AudioBuffer buffer, byte[] samples)
  69. {
  70. if (samples == null)
  71. {
  72. return false;
  73. }
  74. if (_userChannelCount != _realSession.RequestedChannelCount)
  75. {
  76. if (_userSampleFormat != SampleFormat.PcmInt16)
  77. {
  78. throw new NotImplementedException("Downmixing formats other than PCM16 is not supported.");
  79. }
  80. ReadOnlySpan<short> samplesPCM16 = MemoryMarshal.Cast<byte, short>(samples);
  81. if (_userChannelCount == 6)
  82. {
  83. samplesPCM16 = Downmixing.DownMixSurroundToStereo(samplesPCM16);
  84. if (_realSession.RequestedChannelCount == 1)
  85. {
  86. samplesPCM16 = Downmixing.DownMixStereoToMono(samplesPCM16);
  87. }
  88. }
  89. else if (_userChannelCount == 2 && _realSession.RequestedChannelCount == 1)
  90. {
  91. samplesPCM16 = Downmixing.DownMixStereoToMono(samplesPCM16);
  92. }
  93. else
  94. {
  95. throw new NotImplementedException($"Downmixing from {_userChannelCount} to {_realSession.RequestedChannelCount} not implemented.");
  96. }
  97. samples = MemoryMarshal.Cast<short, byte>(samplesPCM16).ToArray();
  98. }
  99. AudioBuffer fakeBuffer = new AudioBuffer
  100. {
  101. BufferTag = buffer.BufferTag,
  102. DataPointer = buffer.DataPointer,
  103. DataSize = (ulong)samples.Length
  104. };
  105. bool result = _realSession.RegisterBuffer(fakeBuffer, samples);
  106. if (result)
  107. {
  108. buffer.Data = fakeBuffer.Data;
  109. buffer.DataSize = fakeBuffer.DataSize;
  110. }
  111. return result;
  112. }
  113. public override void SetVolume(float volume)
  114. {
  115. _realSession.SetVolume(volume);
  116. }
  117. public override void Start()
  118. {
  119. _realSession.Start();
  120. }
  121. public override void Stop()
  122. {
  123. _realSession.Stop();
  124. }
  125. public override void UnregisterBuffer(AudioBuffer buffer)
  126. {
  127. _realSession.UnregisterBuffer(buffer);
  128. }
  129. public override bool WasBufferFullyConsumed(AudioBuffer buffer)
  130. {
  131. return _realSession.WasBufferFullyConsumed(buffer);
  132. }
  133. }
  134. }