aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs')
-rw-r--r--src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs
new file mode 100644
index 00000000..0233a8d7
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Dsp/PcmHelper.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+
+namespace Ryujinx.Audio.Renderer.Dsp
+{
+ public static class PcmHelper
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int GetCountToDecode(int startSampleOffset, int endSampleOffset, int offset, int count)
+ {
+ return Math.Min(count, endSampleOffset - startSampleOffset - offset);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong GetBufferOffset<T>(int startSampleOffset, int offset, int channelCount) where T : unmanaged
+ {
+ return (ulong)(Unsafe.SizeOf<T>() * channelCount * (startSampleOffset + offset));
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int GetBufferSize<T>(int startSampleOffset, int endSampleOffset, int offset, int count) where T : unmanaged
+ {
+ return GetCountToDecode(startSampleOffset, endSampleOffset, offset, count) * Unsafe.SizeOf<T>();
+ }
+
+ [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 void ConvertSampleToPcm8(Span<sbyte> output, ReadOnlySpan<short> input)
+ {
+ for (int i = 0; i < input.Length; 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;
+ }
+ }
+
+ [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)
+ {
+ return 0;
+ }
+
+ int decodedCount = input.Length / channelCount;
+
+ for (int i = 0; i < decodedCount; i++)
+ {
+ output[i] = input[i * channelCount + channelIndex];
+ }
+
+ return decodedCount;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Decode(Span<short> output, ReadOnlySpan<float> input, int startSampleOffset, int endSampleOffset, int channelIndex, int channelCount)
+ {
+ if (input.IsEmpty || endSampleOffset < startSampleOffset)
+ {
+ return 0;
+ }
+
+ int decodedCount = input.Length / channelCount;
+
+ for (int i = 0; i < decodedCount; i++)
+ {
+ output[i] = ConvertSampleToPcmInt16(input[i * channelCount + channelIndex]);
+ }
+
+ return decodedCount;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static short Saturate(float value)
+ {
+ if (value > short.MaxValue)
+ {
+ return short.MaxValue;
+ }
+
+ if (value < short.MinValue)
+ {
+ return short.MinValue;
+ }
+
+ return (short)value;
+ }
+ }
+} \ No newline at end of file