From f556c80d0230056335632b60c71f1567e177239e Mon Sep 17 00:00:00 2001 From: Mary Date: Fri, 26 Feb 2021 01:11:56 +0100 Subject: 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 --- .../Parameter/Effect/AuxiliaryBufferParameter.cs | 100 ++++++++++++++ .../Effect/BiquadFilterEffectParameter.cs | 61 +++++++++ .../Parameter/Effect/BufferMixerParameter.cs | 49 +++++++ .../Renderer/Parameter/Effect/DelayParameter.cs | 118 +++++++++++++++++ .../Renderer/Parameter/Effect/Reverb3dParameter.cs | 144 +++++++++++++++++++++ .../Renderer/Parameter/Effect/ReverbParameter.cs | 136 +++++++++++++++++++ 6 files changed, 608 insertions(+) create mode 100644 Ryujinx.Audio/Renderer/Parameter/Effect/AuxiliaryBufferParameter.cs create mode 100644 Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs create mode 100644 Ryujinx.Audio/Renderer/Parameter/Effect/BufferMixerParameter.cs create mode 100644 Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs create mode 100644 Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs create mode 100644 Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs (limited to 'Ryujinx.Audio/Renderer/Parameter/Effect') diff --git a/Ryujinx.Audio/Renderer/Parameter/Effect/AuxiliaryBufferParameter.cs b/Ryujinx.Audio/Renderer/Parameter/Effect/AuxiliaryBufferParameter.cs new file mode 100644 index 00000000..5a747922 --- /dev/null +++ b/Ryujinx.Audio/Renderer/Parameter/Effect/AuxiliaryBufferParameter.cs @@ -0,0 +1,100 @@ +// +// 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 . +// + +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.Audio.Renderer.Parameter.Effect +{ + /// + /// for . + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct AuxiliaryBufferParameter + { + /// + /// The input channel indices that will be used by the to write data to . + /// + public Array24 Input; + + /// + /// The output channel indices that will be used by the to read data from . + /// + public Array24 Output; + + /// + /// The total channel count used. + /// + public uint ChannelCount; + + /// + /// The target sample rate. + /// + public uint SampleRate; + + /// + /// The buffer storage total size. + /// + public uint BufferStorageSize; + + /// + /// The maximum number of channels supported. + /// + /// This is unused. + public uint ChannelCountMax; + + /// + /// The address of the start of the region containing two followed by the data that will be written by the . + /// + public ulong SendBufferInfoAddress; + + /// + /// The address of the start of the region containling data that will be written by the . + /// + /// This is unused. + public ulong SendBufferStorageAddress; + + /// + /// The address of the start of the region containing two followed by the data that will be read by the . + /// + public ulong ReturnBufferInfoAddress; + + /// + /// The address of the start of the region containling data that will be read by the . + /// + /// This is unused. + public ulong ReturnBufferStorageAddress; + + /// + /// Size of a sample of the mix buffer. + /// + /// This is unused. + public uint MixBufferSampleSize; + + /// + /// The total count of sample that can be stored. + /// + /// This is unused. + public uint TotalSampleCount; + + /// + /// The count of sample of the mix buffer. + /// + /// This is unused. + public uint MixBufferSampleCount; + } +} diff --git a/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs b/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs new file mode 100644 index 00000000..7d58d4be --- /dev/null +++ b/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs @@ -0,0 +1,61 @@ +// +// 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 . +// + +using Ryujinx.Audio.Renderer.Server.Effect; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.Audio.Renderer.Parameter.Effect +{ + /// + /// for . + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct BiquadFilterEffectParameter + { + /// + /// The input channel indices that will be used by the . + /// + public Array6 Input; + + /// + /// The output channel indices that will be used by the . + /// + public Array6 Output; + + /// + /// Biquad filter numerator (b0, b1, b2). + /// + public Array3 Numerator; + + /// + /// Biquad filter denominator (a1, a2). + /// + /// a0 = 1 + public Array2 Denominator; + + /// + /// The total channel count used. + /// + public byte ChannelCount; + + /// + /// The current usage status of the effect on the client side. + /// + public UsageState Status; + } +} diff --git a/Ryujinx.Audio/Renderer/Parameter/Effect/BufferMixerParameter.cs b/Ryujinx.Audio/Renderer/Parameter/Effect/BufferMixerParameter.cs new file mode 100644 index 00000000..b0c0c337 --- /dev/null +++ b/Ryujinx.Audio/Renderer/Parameter/Effect/BufferMixerParameter.cs @@ -0,0 +1,49 @@ +// +// 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 . +// + +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.Audio.Renderer.Parameter.Effect +{ + /// + /// for . + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct BufferMixParameter + { + /// + /// The input channel indices that will be used by the . + /// + public Array24 Input; + + /// + /// The output channel indices that will be used by the . + /// + public Array24 Output; + + /// + /// The output volumes of the mixes. + /// + public Array24 Volumes; + + /// + /// The total count of mixes used. + /// + public uint MixesCount; + } +} diff --git a/Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs b/Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs new file mode 100644 index 00000000..e0dbeb7c --- /dev/null +++ b/Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs @@ -0,0 +1,118 @@ +// +// 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 . +// + +using Ryujinx.Audio.Renderer.Server.Effect; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.Audio.Renderer.Parameter.Effect +{ + /// + /// for . + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct DelayParameter + { + /// + /// The input channel indices that will be used by the . + /// + public Array6 Input; + + /// + /// The output channel indices that will be used by the . + /// + public Array6 Output; + + /// + /// The maximum number of channels supported. + /// + public ushort ChannelCountMax; + + /// + /// The total channel count used. + /// + public ushort ChannelCount; + + /// + /// The maximum delay time in milliseconds. + /// + public uint DelayTimeMax; + + /// + /// The delay time in milliseconds. + /// + public uint DelayTime; + + /// + /// The target sample rate. (Q15) + /// + public uint SampleRate; + + /// + /// The input gain. (Q15) + /// + public uint InGain; + + /// + /// The feedback gain. (Q15) + /// + public uint FeedbackGain; + + /// + /// The output gain. (Q15) + /// + public uint OutGain; + + /// + /// The dry gain. (Q15) + /// + public uint DryGain; + + /// + /// The channel spread of the . (Q15) + /// + public uint ChannelSpread; + + /// + /// The low pass amount. (Q15) + /// + public uint LowPassAmount; + + /// + /// The current usage status of the effect on the client side. + /// + public UsageState Status; + + /// + /// Check if the is valid. + /// + /// Returns true if the is valid. + public bool IsChannelCountValid() + { + return EffectInParameter.IsChannelCountValid(ChannelCount); + } + + /// + /// Check if the is valid. + /// + /// Returns true if the is valid. + public bool IsChannelCountMaxValid() + { + return EffectInParameter.IsChannelCountValid(ChannelCountMax); + } + } +} diff --git a/Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs b/Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs new file mode 100644 index 00000000..0dbecfb8 --- /dev/null +++ b/Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs @@ -0,0 +1,144 @@ +// +// 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 . +// + +using Ryujinx.Audio.Renderer.Server.Effect; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.Audio.Renderer.Parameter.Effect +{ + /// + /// for . + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct Reverb3dParameter + { + /// + /// The input channel indices that will be used by the . + /// + public Array6 Input; + + /// + /// The output channel indices that will be used by the . + /// + public Array6 Output; + + /// + /// The maximum number of channels supported. + /// + public ushort ChannelCountMax; + + /// + /// The total channel count used. + /// + public ushort ChannelCount; + + /// + /// Reserved/unused. + /// + private uint _reserved; + + /// + /// The target sample rate. + /// + /// This is in kHz. + public uint SampleRate; + + /// + /// Gain of the room high-frequency effect. + /// + public float RoomHf; + + /// + /// Reference high frequency. + /// + public float HfReference; + + /// + /// Reverberation decay time at low frequencies. + /// + public float DecayTime; + + /// + /// Ratio of the decay time at high frequencies to the decay time at low frequencies. + /// + public float HfDecayRatio; + + /// + /// Gain of the room effect. + /// + public float RoomGain; + + /// + /// Gain of the early reflections relative to . + /// + public float ReflectionsGain; + + /// + /// Gain of the late reverberation relative to . + /// + public float ReverbGain; + + /// + /// Echo density in the late reverberation decay. + /// + public float Diffusion; + + /// + /// Modal density in the late reverberation decay. + /// + public float ReflectionDelay; + + /// + /// Time limit between the early reflections and the late reverberation relative to the time of the first reflection. + /// + public float ReverbDelayTime; + + /// + /// Modal density in the late reverberation decay. + /// + public float Density; + + /// + /// The dry gain. + /// + public float DryGain; + + /// + /// The current usage status of the effect on the client side. + /// + public UsageState ParameterStatus; + + /// + /// Check if the is valid. + /// + /// Returns true if the is valid. + public bool IsChannelCountValid() + { + return EffectInParameter.IsChannelCountValid(ChannelCount); + } + + /// + /// Check if the is valid. + /// + /// Returns true if the is valid. + public bool IsChannelCountMaxValid() + { + return EffectInParameter.IsChannelCountValid(ChannelCountMax); + } + } +} diff --git a/Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs b/Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs new file mode 100644 index 00000000..daa81c51 --- /dev/null +++ b/Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs @@ -0,0 +1,136 @@ +// +// 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 . +// + +using Ryujinx.Audio.Renderer.Common; +using Ryujinx.Audio.Renderer.Server.Effect; +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.Audio.Renderer.Parameter.Effect +{ + /// + /// for . + /// + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct ReverbParameter + { + /// + /// The input channel indices that will be used by the . + /// + public Array6 Input; + + /// + /// The output channel indices that will be used by the . + /// + public Array6 Output; + + /// + /// The maximum number of channels supported. + /// + public ushort ChannelCountMax; + + /// + /// The total channel count used. + /// + public ushort ChannelCount; + + /// + /// The target sample rate. (Q15) + /// + /// This is in kHz. + public int SampleRate; + + /// + /// The early mode to use. + /// + public ReverbEarlyMode EarlyMode; + + /// + /// The gain to apply to the result of the early reflection. (Q15) + /// + public int EarlyGain; + + /// + /// The pre-delay time in milliseconds. (Q15) + /// + public int PreDelayTime; + + /// + /// The late mode to use. + /// + public ReverbLateMode LateMode; + + /// + /// The gain to apply to the result of the late reflection. (Q15) + /// + public int LateGain; + + /// + /// The decay time. (Q15) + /// + public int DecayTime; + + /// + /// The high frequency decay ratio. (Q15) + /// + /// If >= 0.995f, it is considered disabled. + public int HighFrequencyDecayRatio; + + /// + /// The coloration of the decay. (Q15) + /// + public int Coloration; + + /// + /// The reverb gain. (Q15) + /// + public int ReverbGain; + + /// + /// The output gain. (Q15) + /// + public int OutGain; + + /// + /// The dry gain. (Q15) + /// + public int DryGain; + + /// + /// The current usage status of the effect on the client side. + /// + public UsageState Status; + + /// + /// Check if the is valid. + /// + /// Returns true if the is valid. + public bool IsChannelCountValid() + { + return EffectInParameter.IsChannelCountValid(ChannelCount); + } + + /// + /// Check if the is valid. + /// + /// Returns true if the is valid. + public bool IsChannelCountMaxValid() + { + return EffectInParameter.IsChannelCountValid(ChannelCountMax); + } + } +} -- cgit v1.2.3