Explorar o código

Audio: Implement PCM24 output (#4321)

merry %!s(int64=3) %!d(string=hai) anos
pai
achega
009e6bcd1b

+ 5 - 2
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;

+ 5 - 2
Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceSession.cs

@@ -58,10 +58,13 @@ namespace Ryujinx.Audio.Backends.CompatLayer
                 switch (realSampleFormat)
                 {
                     case SampleFormat.PcmInt8:
-                        PcmHelper.Convert(MemoryMarshal.Cast<byte, sbyte>(convertedSamples), samples);
+                        PcmHelper.ConvertSampleToPcm8(MemoryMarshal.Cast<byte, sbyte>(convertedSamples), samples);
+                        break;
+                    case SampleFormat.PcmInt24:
+                        PcmHelper.ConvertSampleToPcm24(convertedSamples, samples);
                         break;
                     case SampleFormat.PcmInt32:
-                        PcmHelper.Convert(MemoryMarshal.Cast<byte, int>(convertedSamples), samples);
+                        PcmHelper.ConvertSampleToPcm32(MemoryMarshal.Cast<byte, int>(convertedSamples), samples);
                         break;
                     case SampleFormat.PcmFloat:
                         PcmHelper.ConvertSampleToPcmFloat(MemoryMarshal.Cast<byte, float>(convertedSamples), samples);

+ 18 - 5
Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs

@@ -37,19 +37,32 @@ namespace Ryujinx.Audio.Renderer.Dsp
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static TOutput ConvertSample<TInput, TOutput>(TInput value) where TInput: INumber<TInput>, IMinMaxValue<TInput> where TOutput : INumber<TOutput>, IMinMaxValue<TOutput>
+        public static void ConvertSampleToPcm8(Span<sbyte> output, ReadOnlySpan<short> input)
         {
-            TInput conversionRate = TInput.CreateSaturating(TOutput.MaxValue / TOutput.CreateSaturating(TInput.MaxValue));
+            for (int i = 0; i < input.Length; i++)
+            {
+                // Output most significant byte
+                output[i] = (sbyte)(input[i] >> 8);
+            }
+        }
 
-            return TOutput.CreateSaturating(value * conversionRate);
+        [MethodImpl(MethodImplOptions.AggressiveInlining)]
+        public static void ConvertSampleToPcm24(Span<byte> output, ReadOnlySpan<short> 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 Convert<TInput, TOutput>(Span<TOutput> output, ReadOnlySpan<TInput> input) where TInput : INumber<TInput>, IMinMaxValue<TInput> where TOutput : INumber<TOutput>, IMinMaxValue<TOutput>
+        public static void ConvertSampleToPcm32(Span<int> output, ReadOnlySpan<short> input)
         {
             for (int i = 0; i < input.Length; i++)
             {
-                output[i] = ConvertSample<TInput, TOutput>(input[i]);
+                output[i] = ((int)input[i]) << 16;
             }
         }