diff --git a/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs b/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs index 1eedfa660..22919f1e1 100644 --- a/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs +++ b/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs @@ -75,9 +75,12 @@ namespace Ryujinx.Audio.Backends.CompatLayer return SampleFormat.PcmFloat; } - // TODO: Implement PCM24 conversion. + if (_realDriver.SupportsSampleFormat(SampleFormat.PcmInt24)) + { + return SampleFormat.PcmInt24; + } - // If nothing is truly supported, attempt PCM8 at the cost of loosing quality. + // If nothing is truly supported, attempt PCM8 at the cost of losing quality. if (_realDriver.SupportsSampleFormat(SampleFormat.PcmInt8)) { return SampleFormat.PcmInt8; diff --git a/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs b/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs index ca6090fe9..f22a7a690 100644 --- a/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs +++ b/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs @@ -58,10 +58,13 @@ namespace Ryujinx.Audio.Backends.CompatLayer switch (realSampleFormat) { case SampleFormat.PcmInt8: - PcmHelper.Convert(MemoryMarshal.Cast(convertedSamples), samples); + PcmHelper.ConvertSampleToPcm8(MemoryMarshal.Cast(convertedSamples), samples); + break; + case SampleFormat.PcmInt24: + PcmHelper.ConvertSampleToPcm24(convertedSamples, samples); break; case SampleFormat.PcmInt32: - PcmHelper.Convert(MemoryMarshal.Cast(convertedSamples), samples); + PcmHelper.ConvertSampleToPcm32(MemoryMarshal.Cast(convertedSamples), samples); break; case SampleFormat.PcmFloat: PcmHelper.ConvertSampleToPcmFloat(MemoryMarshal.Cast(convertedSamples), samples); diff --git a/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs b/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs index 1459e3a0f..0233a8d71 100644 --- a/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs +++ b/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs @@ -37,19 +37,32 @@ namespace Ryujinx.Audio.Renderer.Dsp } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static TOutput ConvertSample(TInput value) where TInput: INumber, IMinMaxValue where TOutput : INumber, IMinMaxValue - { - TInput conversionRate = TInput.CreateSaturating(TOutput.MaxValue / TOutput.CreateSaturating(TInput.MaxValue)); - - return TOutput.CreateSaturating(value * conversionRate); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Convert(Span output, ReadOnlySpan input) where TInput : INumber, IMinMaxValue where TOutput : INumber, IMinMaxValue + public static void ConvertSampleToPcm8(Span output, ReadOnlySpan input) { for (int i = 0; i < input.Length; i++) { - output[i] = ConvertSample(input[i]); + // Output most significant byte + output[i] = (sbyte)(input[i] >> 8); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ConvertSampleToPcm24(Span output, ReadOnlySpan input) + { + for (int i = 0; i < input.Length; i++) + { + output[i * 3 + 2] = (byte)(input[i] >> 8); + output[i * 3 + 1] = (byte)(input[i] & 0xff); + output[i * 3 + 0] = 0; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ConvertSampleToPcm32(Span output, ReadOnlySpan input) + { + for (int i = 0; i < input.Length; i++) + { + output[i] = ((int)input[i]) << 16; } }