diff options
Diffstat (limited to 'Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs')
-rw-r--r-- | Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs | 86 |
1 files changed, 61 insertions, 25 deletions
diff --git a/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs b/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs index ff3b0988..ca6090fe 100644 --- a/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs +++ b/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs @@ -1,5 +1,6 @@ using Ryujinx.Audio.Backends.Common; using Ryujinx.Audio.Common; +using Ryujinx.Audio.Renderer.Dsp; using System; using System.Runtime.InteropServices; @@ -8,11 +9,13 @@ namespace Ryujinx.Audio.Backends.CompatLayer class CompatLayerHardwareDeviceSession : HardwareDeviceSessionOutputBase { private HardwareDeviceSessionOutputBase _realSession; + private SampleFormat _userSampleFormat; private uint _userChannelCount; - public CompatLayerHardwareDeviceSession(HardwareDeviceSessionOutputBase realSession, uint userChannelCount) : base(realSession.MemoryManager, realSession.RequestedSampleFormat, realSession.RequestedSampleRate, userChannelCount) + public CompatLayerHardwareDeviceSession(HardwareDeviceSessionOutputBase realSession, SampleFormat userSampleFormat, uint userChannelCount) : base(realSession.MemoryManager, realSession.RequestedSampleFormat, realSession.RequestedSampleRate, userChannelCount) { _realSession = realSession; + _userSampleFormat = userSampleFormat; _userChannelCount = userChannelCount; } @@ -38,53 +41,86 @@ namespace Ryujinx.Audio.Backends.CompatLayer public override void QueueBuffer(AudioBuffer buffer) { + SampleFormat realSampleFormat = _realSession.RequestedSampleFormat; + + if (_userSampleFormat != realSampleFormat) + { + if (_userSampleFormat != SampleFormat.PcmInt16) + { + throw new NotImplementedException("Converting formats other than PCM16 is not supported."); + } + + int userSampleCount = buffer.Data.Length / BackendHelper.GetSampleSize(_userSampleFormat); + + ReadOnlySpan<short> samples = MemoryMarshal.Cast<byte, short>(buffer.Data); + byte[] convertedSamples = new byte[BackendHelper.GetSampleSize(realSampleFormat) * userSampleCount]; + + switch (realSampleFormat) + { + case SampleFormat.PcmInt8: + PcmHelper.Convert(MemoryMarshal.Cast<byte, sbyte>(convertedSamples), samples); + break; + case SampleFormat.PcmInt32: + PcmHelper.Convert(MemoryMarshal.Cast<byte, int>(convertedSamples), samples); + break; + case SampleFormat.PcmFloat: + PcmHelper.ConvertSampleToPcmFloat(MemoryMarshal.Cast<byte, float>(convertedSamples), samples); + break; + default: + throw new NotImplementedException($"Sample format conversion from {_userSampleFormat} to {realSampleFormat} not implemented."); + } + + buffer.Data = convertedSamples; + } + _realSession.QueueBuffer(buffer); } public override bool RegisterBuffer(AudioBuffer buffer, byte[] samples) { - if (RequestedSampleFormat != SampleFormat.PcmInt16) - { - throw new NotImplementedException("Downmixing formats other than PCM16 is not supported."); - } - if (samples == null) { return false; } - short[] downmixedBufferPCM16; + if (_userChannelCount != _realSession.RequestedChannelCount) + { + if (_userSampleFormat != SampleFormat.PcmInt16) + { + throw new NotImplementedException("Downmixing formats other than PCM16 is not supported."); + } - ReadOnlySpan<short> samplesPCM16 = MemoryMarshal.Cast<byte, short>(samples); + ReadOnlySpan<short> samplesPCM16 = MemoryMarshal.Cast<byte, short>(samples); - if (_userChannelCount == 6) - { - downmixedBufferPCM16 = Downmixing.DownMixSurroundToStereo(samplesPCM16); + if (_userChannelCount == 6) + { + samplesPCM16 = Downmixing.DownMixSurroundToStereo(samplesPCM16); - if (_realSession.RequestedChannelCount == 1) + if (_realSession.RequestedChannelCount == 1) + { + samplesPCM16 = Downmixing.DownMixStereoToMono(samplesPCM16); + } + } + else if (_userChannelCount == 2 && _realSession.RequestedChannelCount == 1) { - downmixedBufferPCM16 = Downmixing.DownMixStereoToMono(downmixedBufferPCM16); + samplesPCM16 = Downmixing.DownMixStereoToMono(samplesPCM16); + } + else + { + throw new NotImplementedException($"Downmixing from {_userChannelCount} to {_realSession.RequestedChannelCount} not implemented."); } - } - else if (_userChannelCount == 2 && _realSession.RequestedChannelCount == 1) - { - downmixedBufferPCM16 = Downmixing.DownMixStereoToMono(samplesPCM16); - } - else - { - throw new NotImplementedException($"Downmixing from {_userChannelCount} to {_realSession.RequestedChannelCount} not implemented."); - } - byte[] downmixedBuffer = MemoryMarshal.Cast<short, byte>(downmixedBufferPCM16).ToArray(); + samples = MemoryMarshal.Cast<short, byte>(samplesPCM16).ToArray(); + } AudioBuffer fakeBuffer = new AudioBuffer { BufferTag = buffer.BufferTag, DataPointer = buffer.DataPointer, - DataSize = (ulong)downmixedBuffer.Length + DataSize = (ulong)samples.Length }; - bool result = _realSession.RegisterBuffer(fakeBuffer, downmixedBuffer); + bool result = _realSession.RegisterBuffer(fakeBuffer, samples); if (result) { |