aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio.Renderer/Server/Sink
diff options
context:
space:
mode:
authorMary <me@thog.eu>2021-02-26 01:11:56 +0100
committerGitHub <noreply@github.com>2021-02-26 01:11:56 +0100
commitf556c80d0230056335632b60c71f1567e177239e (patch)
tree748aa6be62b93a8e941e25dbd83f39e1dbb37035 /Ryujinx.Audio.Renderer/Server/Sink
parent1c49089ff00fc87dc4872f135dc6a0d36169a970 (diff)
Haydn: Part 1 (#2007)
* Haydn: Part 1 Based on my reverse of audio 11.0.0. As always, core implementation under LGPLv3 for the same reasons as for Amadeus. This place the bases of a more flexible audio system while making audout & audin accurate. This have the following improvements: - Complete reimplementation of audout and audin. - Audin currently only have a dummy backend. - Dramatically reduce CPU usage by up to 50% in common cases (SoundIO and OpenAL). - Audio Renderer now can output to 5.1 devices when supported. - Audio Renderer init its backend on demand instead of keeping two up all the time. - All backends implementation are now in their own project. - Ryujinx.Audio.Renderer was renamed Ryujinx.Audio and was refactored because of this. As a note, games having issues with OpenAL haven't improved and will not because of OpenAL design (stopping when buffers finish playing causing possible audio "pops" when buffers are very small). * Update for latest hexkyz's edits on Switchbrew * audren: Rollback channel configuration changes * Address gdkchan's comments * Fix typo in OpenAL backend driver * Address last comments * Fix a nit * Address gdkchan's comments
Diffstat (limited to 'Ryujinx.Audio.Renderer/Server/Sink')
-rw-r--r--Ryujinx.Audio.Renderer/Server/Sink/BaseSink.cs119
-rw-r--r--Ryujinx.Audio.Renderer/Server/Sink/CircularBufferSink.cs126
-rw-r--r--Ryujinx.Audio.Renderer/Server/Sink/DeviceSink.cs92
-rw-r--r--Ryujinx.Audio.Renderer/Server/Sink/SinkContext.cs73
4 files changed, 0 insertions, 410 deletions
diff --git a/Ryujinx.Audio.Renderer/Server/Sink/BaseSink.cs b/Ryujinx.Audio.Renderer/Server/Sink/BaseSink.cs
deleted file mode 100644
index 949e3971..00000000
--- a/Ryujinx.Audio.Renderer/Server/Sink/BaseSink.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-//
-// Copyright (c) 2019-2021 Ryujinx
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-//
-
-using Ryujinx.Audio.Renderer.Common;
-using Ryujinx.Audio.Renderer.Parameter;
-using Ryujinx.Audio.Renderer.Server.MemoryPool;
-using System.Diagnostics;
-using static Ryujinx.Audio.Renderer.Common.BehaviourParameter;
-
-namespace Ryujinx.Audio.Renderer.Server.Sink
-{
- /// <summary>
- /// Base class used for server information of a sink.
- /// </summary>
- public class BaseSink
- {
- /// <summary>
- /// The type of this <see cref="BaseSink"/>.
- /// </summary>
- public SinkType Type;
-
- /// <summary>
- /// Set to true if the sink is used.
- /// </summary>
- public bool IsUsed;
-
- /// <summary>
- /// Set to true if the sink need to be skipped because of invalid state.
- /// </summary>
- public bool ShouldSkip;
-
- /// <summary>
- /// The node id of the sink.
- /// </summary>
- public int NodeId;
-
- /// <summary>
- /// Create a new <see cref="BaseSink"/>.
- /// </summary>
- public BaseSink()
- {
- CleanUp();
- }
-
- /// <summary>
- /// Clean up the internal state of the <see cref="BaseSink"/>.
- /// </summary>
- public virtual void CleanUp()
- {
- Type = TargetSinkType;
- IsUsed = false;
- ShouldSkip = false;
- }
-
- /// <summary>
- /// The target <see cref="SinkType"/> handled by this <see cref="BaseSink"/>.
- /// </summary>
- public virtual SinkType TargetSinkType => SinkType.Invalid;
-
- /// <summary>
- /// Check if the <see cref="SinkType"/> sent by the user match the internal <see cref="SinkType"/>.
- /// </summary>
- /// <param name="parameter">The user parameter.</param>
- /// <returns>Return true, if the <see cref="SinkType"/> sent by the user match the internal <see cref="SinkType"/>.</returns>
- public bool IsTypeValid(ref SinkInParameter parameter)
- {
- return parameter.Type == TargetSinkType;
- }
-
- /// <summary>
- /// Update the <see cref="BaseSink"/> state during command generation.
- /// </summary>
- public virtual void UpdateForCommandGeneration()
- {
- Debug.Assert(Type == TargetSinkType);
- }
-
- /// <summary>
- /// Update the internal common parameters from user parameter.
- /// </summary>
- /// <param name="parameter">The user parameter.</param>
- protected void UpdateStandardParameter(ref SinkInParameter parameter)
- {
- if (IsUsed != parameter.IsUsed)
- {
- IsUsed = parameter.IsUsed;
- NodeId = parameter.NodeId;
- }
- }
-
- /// <summary>
- /// Update the internal state from user parameter.
- /// </summary>
- /// <param name="errorInfo">The possible <see cref="ErrorInfo"/> that was generated.</param>
- /// <param name="parameter">The user parameter.</param>
- /// <param name="outStatus">The user output status.</param>
- /// <param name="mapper">The mapper to use.</param>
- public virtual void Update(out ErrorInfo errorInfo, ref SinkInParameter parameter, ref SinkOutStatus outStatus, PoolMapper mapper)
- {
- Debug.Assert(IsTypeValid(ref parameter));
-
- errorInfo = new ErrorInfo();
- }
- }
-}
diff --git a/Ryujinx.Audio.Renderer/Server/Sink/CircularBufferSink.cs b/Ryujinx.Audio.Renderer/Server/Sink/CircularBufferSink.cs
deleted file mode 100644
index 16d25a65..00000000
--- a/Ryujinx.Audio.Renderer/Server/Sink/CircularBufferSink.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-//
-// Copyright (c) 2019-2021 Ryujinx
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-//
-
-using Ryujinx.Audio.Renderer.Common;
-using Ryujinx.Audio.Renderer.Parameter;
-using Ryujinx.Audio.Renderer.Parameter.Sink;
-using Ryujinx.Audio.Renderer.Server.MemoryPool;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.Audio.Renderer.Server.Sink
-{
- /// <summary>
- /// Server information for a circular buffer sink.
- /// </summary>
- public class CircularBufferSink : BaseSink
- {
- /// <summary>
- /// The circular buffer parameter.
- /// </summary>
- public CircularBufferParameter Parameter;
-
- /// <summary>
- /// The last written data offset on the circular buffer.
- /// </summary>
- private uint _lastWrittenOffset;
-
- /// <summary>
- /// THe previous written offset of the circular buffer.
- /// </summary>
- private uint _oldWrittenOffset;
-
- /// <summary>
- /// The current offset to write data on the circular buffer.
- /// </summary>
- public uint CurrentWriteOffset { get; private set; }
-
- /// <summary>
- /// The <see cref="AddressInfo"/> of the circular buffer.
- /// </summary>
- public AddressInfo CircularBufferAddressInfo;
-
- public CircularBufferSink()
- {
- CircularBufferAddressInfo = AddressInfo.Create();
- }
-
- public override SinkType TargetSinkType => SinkType.CircularBuffer;
-
- public override void Update(out BehaviourParameter.ErrorInfo errorInfo, ref SinkInParameter parameter, ref SinkOutStatus outStatus, PoolMapper mapper)
- {
- errorInfo = new BehaviourParameter.ErrorInfo();
- outStatus = new SinkOutStatus();
-
- Debug.Assert(IsTypeValid(ref parameter));
-
- ref CircularBufferParameter inputDeviceParameter = ref MemoryMarshal.Cast<byte, CircularBufferParameter>(parameter.SpecificData)[0];
-
- if (parameter.IsUsed != IsUsed || ShouldSkip)
- {
- UpdateStandardParameter(ref parameter);
-
- if (parameter.IsUsed)
- {
- Debug.Assert(CircularBufferAddressInfo.CpuAddress == 0);
- Debug.Assert(CircularBufferAddressInfo.GetReference(false) == 0);
-
- ShouldSkip = !mapper.TryAttachBuffer(out errorInfo, ref CircularBufferAddressInfo, inputDeviceParameter.BufferAddress, inputDeviceParameter.BufferSize);
- }
- else
- {
- Debug.Assert(CircularBufferAddressInfo.CpuAddress != 0);
- Debug.Assert(CircularBufferAddressInfo.GetReference(false) != 0);
- }
-
- Parameter = inputDeviceParameter;
- }
-
- outStatus.LastWrittenOffset = _lastWrittenOffset;
- }
-
- public override void UpdateForCommandGeneration()
- {
- Debug.Assert(Type == TargetSinkType);
-
- if (IsUsed)
- {
- uint frameSize = RendererConstants.TargetSampleSize * Parameter.SampleCount * Parameter.InputCount;
-
- _lastWrittenOffset = _oldWrittenOffset;
-
- _oldWrittenOffset = CurrentWriteOffset;
-
- CurrentWriteOffset += frameSize;
-
- if (Parameter.BufferSize > 0)
- {
- CurrentWriteOffset %= Parameter.BufferSize;
- }
- }
- }
-
- public override void CleanUp()
- {
- CircularBufferAddressInfo = AddressInfo.Create();
- _lastWrittenOffset = 0;
- _oldWrittenOffset = 0;
- CurrentWriteOffset = 0;
- base.CleanUp();
- }
- }
-}
diff --git a/Ryujinx.Audio.Renderer/Server/Sink/DeviceSink.cs b/Ryujinx.Audio.Renderer/Server/Sink/DeviceSink.cs
deleted file mode 100644
index 79af05f7..00000000
--- a/Ryujinx.Audio.Renderer/Server/Sink/DeviceSink.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// Copyright (c) 2019-2021 Ryujinx
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-//
-
-using Ryujinx.Audio.Renderer.Common;
-using Ryujinx.Audio.Renderer.Parameter;
-using Ryujinx.Audio.Renderer.Parameter.Sink;
-using Ryujinx.Audio.Renderer.Server.MemoryPool;
-using Ryujinx.Audio.Renderer.Server.Upsampler;
-using System;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.Audio.Renderer.Server.Sink
-{
- /// <summary>
- /// Server information for a device sink.
- /// </summary>
- public class DeviceSink : BaseSink
- {
- /// <summary>
- /// The downmix coefficients.
- /// </summary>
- public float[] DownMixCoefficients;
-
- /// <summary>
- /// The device parameters.
- /// </summary>
- public DeviceParameter Parameter;
-
- /// <summary>
- /// The upsampler instance used by this sink.
- /// </summary>
- /// <remarks>Null if no upsampling is needed.</remarks>
- public UpsamplerState UpsamplerState;
-
- /// <summary>
- /// Create a new <see cref="DeviceSink"/>.
- /// </summary>
- public DeviceSink()
- {
- DownMixCoefficients = new float[4];
- }
-
- public override void CleanUp()
- {
- UpsamplerState?.Release();
-
- UpsamplerState = null;
-
- base.CleanUp();
- }
-
- public override SinkType TargetSinkType => SinkType.Device;
-
- public override void Update(out BehaviourParameter.ErrorInfo errorInfo, ref SinkInParameter parameter, ref SinkOutStatus outStatus, PoolMapper mapper)
- {
- Debug.Assert(IsTypeValid(ref parameter));
-
- ref DeviceParameter inputDeviceParameter = ref MemoryMarshal.Cast<byte, DeviceParameter>(parameter.SpecificData)[0];
-
- if (parameter.IsUsed != IsUsed)
- {
- UpdateStandardParameter(ref parameter);
- Parameter = inputDeviceParameter;
- }
- else
- {
- Parameter.DownMixParameterEnabled = inputDeviceParameter.DownMixParameterEnabled;
- inputDeviceParameter.DownMixParameter.ToSpan().CopyTo(Parameter.DownMixParameter.ToSpan());
- }
-
- Parameter.DownMixParameter.ToSpan().CopyTo(DownMixCoefficients.AsSpan());
-
- errorInfo = new BehaviourParameter.ErrorInfo();
- outStatus = new SinkOutStatus();
- }
- }
-}
diff --git a/Ryujinx.Audio.Renderer/Server/Sink/SinkContext.cs b/Ryujinx.Audio.Renderer/Server/Sink/SinkContext.cs
deleted file mode 100644
index b57dbde9..00000000
--- a/Ryujinx.Audio.Renderer/Server/Sink/SinkContext.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// Copyright (c) 2019-2021 Ryujinx
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-//
-
-using System.Diagnostics;
-
-namespace Ryujinx.Audio.Renderer.Server.Sink
-{
- /// <summary>
- /// Sink context.
- /// </summary>
- public class SinkContext
- {
- /// <summary>
- /// Storage for <see cref="BaseSink"/>.
- /// </summary>
- private BaseSink[] _sinks;
-
- /// <summary>
- /// The total sink count.
- /// </summary>
- private uint _sinkCount;
-
- /// <summary>
- /// Initialize the <see cref="SinkContext"/>.
- /// </summary>
- /// <param name="sinksCount">The total sink count.</param>
- public void Initialize(uint sinksCount)
- {
- _sinkCount = sinksCount;
- _sinks = new BaseSink[_sinkCount];
-
- for (int i = 0; i < _sinkCount; i++)
- {
- _sinks[i] = new BaseSink();
- }
- }
-
- /// <summary>
- /// Get the total sink count.
- /// </summary>
- /// <returns>The total sink count.</returns>
- public uint GetCount()
- {
- return _sinkCount;
- }
-
- /// <summary>
- /// Get a reference to a <see cref="BaseSink"/> at the given <paramref name="id"/>.
- /// </summary>
- /// <param name="id">The index to use.</param>
- /// <returns>A reference to a <see cref="BaseSink"/> at the given <paramref name="id"/>.</returns>
- public ref BaseSink GetSink(int id)
- {
- Debug.Assert(id >= 0 && id < _sinkCount);
-
- return ref _sinks[id];
- }
- }
-}