From cee712105850ac3385cd0091a923438167433f9f Mon Sep 17 00:00:00 2001
From: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
Date: Sat, 8 Apr 2023 01:22:00 +0200
Subject: Move solution and projects to src
---
.../Renderer/Server/Splitter/SplitterState.cs | 221 +++++++++++++++++++++
1 file changed, 221 insertions(+)
create mode 100644 src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs
(limited to 'src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs')
diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs
new file mode 100644
index 00000000..15a0c6ba
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterState.cs
@@ -0,0 +1,221 @@
+using Ryujinx.Audio.Renderer.Parameter;
+using System;
+using System.Buffers;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Server.Splitter
+{
+ ///
+ /// Server state for a splitter.
+ ///
+ [StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = Alignment)]
+ public struct SplitterState
+ {
+ public const int Alignment = 0x10;
+
+ ///
+ /// The unique id of this .
+ ///
+ public int Id;
+
+ ///
+ /// Target sample rate to use on the splitter.
+ ///
+ public uint SampleRate;
+
+ ///
+ /// Count of splitter destinations ().
+ ///
+ public int DestinationCount;
+
+ ///
+ /// Set to true if the splitter has a new connection.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool HasNewConnection;
+
+ ///
+ /// Linked list of .
+ ///
+ private unsafe SplitterDestination* _destinationsData;
+
+ ///
+ /// Span to the first element of the linked list of .
+ ///
+ public Span Destinations
+ {
+ get
+ {
+ unsafe
+ {
+ return (IntPtr)_destinationsData != IntPtr.Zero ? new Span(_destinationsData, 1) : Span.Empty;
+ }
+ }
+ }
+
+ ///
+ /// Create a new .
+ ///
+ /// The unique id of this .
+ public SplitterState(int id) : this()
+ {
+ Id = id;
+ }
+
+ public Span GetData(int index)
+ {
+ int i = 0;
+
+ Span result = Destinations;
+
+ while (i < index)
+ {
+ if (result.IsEmpty)
+ {
+ break;
+ }
+
+ result = result[0].Next;
+ i++;
+ }
+
+ return result;
+ }
+
+ ///
+ /// Clear the new connection flag.
+ ///
+ public void ClearNewConnectionFlag()
+ {
+ HasNewConnection = false;
+ }
+
+ ///
+ /// Utility function to apply a given to all .
+ ///
+ /// The action to execute on each elements.
+ private void ForEachDestination(SpanAction action)
+ {
+ Span temp = Destinations;
+
+ int i = 0;
+
+ while (true)
+ {
+ if (temp.IsEmpty)
+ {
+ break;
+ }
+
+ Span next = temp[0].Next;
+
+ action.Invoke(temp, i++);
+
+ temp = next;
+ }
+ }
+
+ ///
+ /// Update the from user parameter.
+ ///
+ /// The splitter context.
+ /// The user parameter.
+ /// The raw input data after the .
+ public void Update(SplitterContext context, ref SplitterInParameter parameter, ReadOnlySpan input)
+ {
+ ClearLinks();
+
+ int destinationCount;
+
+ if (context.IsBugFixed)
+ {
+ destinationCount = parameter.DestinationCount;
+ }
+ else
+ {
+ destinationCount = Math.Min(context.GetDestinationCountPerStateForCompatibility(), parameter.DestinationCount);
+ }
+
+ if (destinationCount > 0)
+ {
+ ReadOnlySpan destinationIds = MemoryMarshal.Cast(input);
+
+ Memory destination = context.GetDestinationMemory(destinationIds[0]);
+
+ SetDestination(ref destination.Span[0]);
+
+ DestinationCount = destinationCount;
+
+ for (int i = 1; i < destinationCount; i++)
+ {
+ Memory nextDestination = context.GetDestinationMemory(destinationIds[i]);
+
+ destination.Span[0].Link(ref nextDestination.Span[0]);
+ destination = nextDestination;
+ }
+ }
+
+ Debug.Assert(parameter.Id == Id);
+
+ if (parameter.Id == Id)
+ {
+ SampleRate = parameter.SampleRate;
+ HasNewConnection = true;
+ }
+ }
+
+ ///
+ /// Set the head of the linked list of .
+ ///
+ /// A reference to a .
+ public void SetDestination(ref SplitterDestination newValue)
+ {
+ unsafe
+ {
+ fixed (SplitterDestination* newValuePtr = &newValue)
+ {
+ _destinationsData = newValuePtr;
+ }
+ }
+ }
+
+ ///
+ /// Update the internal state of this instance.
+ ///
+ public void UpdateInternalState()
+ {
+ ForEachDestination((destination, _) => destination[0].UpdateInternalState());
+ }
+
+ ///
+ /// Clear all links from the .
+ ///
+ public void ClearLinks()
+ {
+ ForEachDestination((destination, _) => destination[0].Unlink());
+
+ unsafe
+ {
+ _destinationsData = (SplitterDestination*)IntPtr.Zero;
+ }
+ }
+
+ ///
+ /// Initialize a given .
+ ///
+ /// All the to initialize.
+ public static void InitializeSplitters(Span splitters)
+ {
+ foreach (ref SplitterState splitter in splitters)
+ {
+ unsafe
+ {
+ splitter._destinationsData = (SplitterDestination*)IntPtr.Zero;
+ }
+
+ splitter.DestinationCount = 0;
+ }
+ }
+ }
+}
\ No newline at end of file
--
cgit v1.2.3