forked from Mirror/Ryujinx
Audio: Implement PCM24 output (#4321)
This commit is contained in:
parent
eb2cc159fa
commit
009e6bcd1b
3 changed files with 33 additions and 14 deletions
|
@ -75,9 +75,12 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
||||||
return SampleFormat.PcmFloat;
|
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))
|
if (_realDriver.SupportsSampleFormat(SampleFormat.PcmInt8))
|
||||||
{
|
{
|
||||||
return SampleFormat.PcmInt8;
|
return SampleFormat.PcmInt8;
|
||||||
|
|
|
@ -58,10 +58,13 @@ namespace Ryujinx.Audio.Backends.CompatLayer
|
||||||
switch (realSampleFormat)
|
switch (realSampleFormat)
|
||||||
{
|
{
|
||||||
case SampleFormat.PcmInt8:
|
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;
|
break;
|
||||||
case SampleFormat.PcmInt32:
|
case SampleFormat.PcmInt32:
|
||||||
PcmHelper.Convert(MemoryMarshal.Cast<byte, int>(convertedSamples), samples);
|
PcmHelper.ConvertSampleToPcm32(MemoryMarshal.Cast<byte, int>(convertedSamples), samples);
|
||||||
break;
|
break;
|
||||||
case SampleFormat.PcmFloat:
|
case SampleFormat.PcmFloat:
|
||||||
PcmHelper.ConvertSampleToPcmFloat(MemoryMarshal.Cast<byte, float>(convertedSamples), samples);
|
PcmHelper.ConvertSampleToPcmFloat(MemoryMarshal.Cast<byte, float>(convertedSamples), samples);
|
||||||
|
|
|
@ -37,19 +37,32 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[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));
|
|
||||||
|
|
||||||
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++)
|
for (int i = 0; i < input.Length; i++)
|
||||||
{
|
{
|
||||||
output[i] = ConvertSample<TInput, TOutput>(input[i]);
|
// Output most significant byte
|
||||||
|
output[i] = (sbyte)(input[i] >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[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 ConvertSampleToPcm32(Span<int> output, ReadOnlySpan<short> input)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < input.Length; i++)
|
||||||
|
{
|
||||||
|
output[i] = ((int)input[i]) << 16;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue