aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio/Renderer
diff options
context:
space:
mode:
authorMary-nyan <mary@mary.zone>2022-12-28 23:34:30 +0100
committerGitHub <noreply@github.com>2022-12-28 19:34:30 -0300
commitc20f3fbebdfec9ed5b0022fbec7fbe3269ffad88 (patch)
treeaa25a1975e41af2f63ee5afdcdfbbafb0ebba052 /Ryujinx.Audio/Renderer
parent0d3b82477ecbf7128340b6725a79413427c68748 (diff)
haydn: Add support for PCMFloat, PCM32 and PCM8 conversions (#4100)
* haydn: Add support for PCMFloat, PCM32 and PCM8 conversions This adds support in the compatibility layer for other sample format than PCM16. This should help extends compatibility with soundio on devices that doesn't expose PCM16. I ommited PCM24 conversion for now as it's not simplest of all. * Address TSRBerry's comment * Address comments * Fix conversion issue and clean up saturation usage * Revert saturation changes * Address gdkchan's comment
Diffstat (limited to 'Ryujinx.Audio/Renderer')
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs41
1 files changed, 40 insertions, 1 deletions
diff --git a/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs b/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs
index 1eec3e41..1459e3a0 100644
--- a/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs
@@ -1,4 +1,5 @@
using System;
+using System.Numerics;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Dsp
@@ -24,6 +25,44 @@ namespace Ryujinx.Audio.Renderer.Dsp
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static float ConvertSampleToPcmFloat(short sample)
+ {
+ return (float)sample / short.MaxValue;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static short ConvertSampleToPcmInt16(float sample)
+ {
+ return Saturate(sample * short.MaxValue);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static TOutput ConvertSample<TInput, TOutput>(TInput value) where TInput: INumber<TInput>, IMinMaxValue<TInput> where TOutput : INumber<TOutput>, IMinMaxValue<TOutput>
+ {
+ TInput conversionRate = TInput.CreateSaturating(TOutput.MaxValue / TOutput.CreateSaturating(TInput.MaxValue));
+
+ return TOutput.CreateSaturating(value * conversionRate);
+ }
+
+ [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>
+ {
+ for (int i = 0; i < input.Length; i++)
+ {
+ output[i] = ConvertSample<TInput, TOutput>(input[i]);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void ConvertSampleToPcmFloat(Span<float> output, ReadOnlySpan<short> input)
+ {
+ for (int i = 0; i < input.Length; i++)
+ {
+ output[i] = ConvertSampleToPcmFloat(input[i]);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Decode(Span<short> output, ReadOnlySpan<short> input, int startSampleOffset, int endSampleOffset, int channelIndex, int channelCount)
{
if (input.IsEmpty || endSampleOffset < startSampleOffset)
@@ -53,7 +92,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
for (int i = 0; i < decodedCount; i++)
{
- output[i] = (short)(input[i * channelCount + channelIndex] * short.MaxValue);
+ output[i] = ConvertSampleToPcmInt16(input[i * channelCount + channelIndex]);
}
return decodedCount;