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
This commit is contained in:
parent
1c49089ff0
commit
f556c80d02
249 changed files with 5614 additions and 2712 deletions
116
Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs
Normal file
116
Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs
Normal file
|
@ -0,0 +1,116 @@
|
|||
//
|
||||
// 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.Server.Types;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Audio Renderer user configuration.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct AudioRendererConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// The target sample rate of the user.
|
||||
/// </summary>
|
||||
/// <remarks>Only 32000Hz and 48000Hz are considered valid, other sample rates will cause undefined behaviour.</remarks>
|
||||
public uint SampleRate;
|
||||
|
||||
/// <summary>
|
||||
/// The target sample count per <see cref="Dsp.AudioProcessor"/> updates.
|
||||
/// </summary>
|
||||
public uint SampleCount;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum mix buffer count.
|
||||
/// </summary>
|
||||
public uint MixBufferCount;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of sub mixes that could be used by the user.
|
||||
/// </summary>
|
||||
public uint SubMixBufferCount;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of voices that could be used by the user.
|
||||
/// </summary>
|
||||
public uint VoiceCount;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of sinks that could be used by the user.
|
||||
/// </summary>
|
||||
public uint SinkCount;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of effects that could be used by the user.
|
||||
/// </summary>
|
||||
public uint EffectCount;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of performance metric frames that could be used by the user.
|
||||
/// </summary>
|
||||
public uint PerformanceMetricFramesCount;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if the user allows the <see cref="Server.AudioRenderSystem"/> to drop voices.
|
||||
/// </summary>
|
||||
/// <seealso cref="Server.AudioRenderSystem.ComputeVoiceDrop(Server.CommandBuffer, long, long)"/>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool VoiceDropEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused
|
||||
/// </summary>
|
||||
private byte _reserved;
|
||||
|
||||
/// <summary>
|
||||
/// The target rendering device.
|
||||
/// </summary>
|
||||
/// <remarks>Must be <see cref="AudioRendererRenderingDevice.Dsp"/></remarks>
|
||||
public AudioRendererRenderingDevice RenderingDevice;
|
||||
|
||||
/// <summary>
|
||||
/// The target execution mode.
|
||||
/// </summary>
|
||||
/// <remarks>Must be <see cref="AudioRendererExecutionMode.Auto"/></remarks>
|
||||
public AudioRendererExecutionMode ExecutionMode;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of splitters that could be used by the user.
|
||||
/// </summary>
|
||||
public uint SplitterCount;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of splitters destinations that could be used by the user.
|
||||
/// </summary>
|
||||
public uint SplitterDestinationCount;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the external context.
|
||||
/// </summary>
|
||||
/// <remarks>This is a leftover of the old "codec" interface system that was present between 1.0.0 and 3.0.0. This was entirely removed from the server side with REV8.</remarks>
|
||||
public uint ExternalContextSize;
|
||||
|
||||
/// <summary>
|
||||
/// The user audio revision
|
||||
/// </summary>
|
||||
/// <seealso cref="Server.BehaviourContext"/>
|
||||
public int Revision;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// 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.Common.Memory;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using static Ryujinx.Audio.Renderer.Common.BehaviourParameter;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Output information for behaviour.
|
||||
/// </summary>
|
||||
/// <remarks>This is used to report errors to the user during <see cref="Server.AudioRenderSystem.Update(Memory{byte}, Memory{byte}, ReadOnlyMemory{byte})"/> processing.</remarks>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct BehaviourErrorInfoOutStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The reported errors.
|
||||
/// </summary>
|
||||
public Array10<ErrorInfo> ErrorInfos;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of error that got reported.
|
||||
/// </summary>
|
||||
public uint ErrorInfosCount;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed uint _reserved[3];
|
||||
}
|
||||
}
|
51
Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs
Normal file
51
Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs
Normal file
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// 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.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Biquad filter parameters.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 1)]
|
||||
public struct BiquadFilterParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Set to true if the biquad filter is active.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool Enable;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private byte _reserved;
|
||||
|
||||
/// <summary>
|
||||
/// Biquad filter numerator (b0, b1, b2).
|
||||
/// </summary>
|
||||
public Array3<short> Numerator;
|
||||
|
||||
/// <summary>
|
||||
/// Biquad filter denominator (a1, a2).
|
||||
/// </summary>
|
||||
/// <remarks>a0 = 1</remarks>
|
||||
public Array2<short> Denominator;
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Effect
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="EffectInParameter.SpecificData"/> for <see cref="Common.EffectType.AuxiliaryBuffer"/>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct AuxiliaryBufferParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/> to write data to <see cref="SendBufferInfoAddress"/>.
|
||||
/// </summary>
|
||||
public Array24<byte> Input;
|
||||
|
||||
/// <summary>
|
||||
/// The output channel indices that will be used by the <see cref="Dsp.AudioProcessor"/> to read data from <see cref="ReturnBufferInfoAddress"/>.
|
||||
/// </summary>
|
||||
public Array24<byte> Output;
|
||||
|
||||
/// <summary>
|
||||
/// The total channel count used.
|
||||
/// </summary>
|
||||
public uint ChannelCount;
|
||||
|
||||
/// <summary>
|
||||
/// The target sample rate.
|
||||
/// </summary>
|
||||
public uint SampleRate;
|
||||
|
||||
/// <summary>
|
||||
/// The buffer storage total size.
|
||||
/// </summary>
|
||||
public uint BufferStorageSize;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of channels supported.
|
||||
/// </summary>
|
||||
/// <remarks>This is unused.</remarks>
|
||||
public uint ChannelCountMax;
|
||||
|
||||
/// <summary>
|
||||
/// The address of the start of the region containing two <see cref="Dsp.State.AuxiliaryBufferHeader"/> followed by the data that will be written by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public ulong SendBufferInfoAddress;
|
||||
|
||||
/// <summary>
|
||||
/// The address of the start of the region containling data that will be written by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
/// <remarks>This is unused.</remarks>
|
||||
public ulong SendBufferStorageAddress;
|
||||
|
||||
/// <summary>
|
||||
/// The address of the start of the region containing two <see cref="Dsp.State.AuxiliaryBufferHeader"/> followed by the data that will be read by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public ulong ReturnBufferInfoAddress;
|
||||
|
||||
/// <summary>
|
||||
/// The address of the start of the region containling data that will be read by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
/// <remarks>This is unused.</remarks>
|
||||
public ulong ReturnBufferStorageAddress;
|
||||
|
||||
/// <summary>
|
||||
/// Size of a sample of the mix buffer.
|
||||
/// </summary>
|
||||
/// <remarks>This is unused.</remarks>
|
||||
public uint MixBufferSampleSize;
|
||||
|
||||
/// <summary>
|
||||
/// The total count of sample that can be stored.
|
||||
/// </summary>
|
||||
/// <remarks>This is unused.</remarks>
|
||||
public uint TotalSampleCount;
|
||||
|
||||
/// <summary>
|
||||
/// The count of sample of the mix buffer.
|
||||
/// </summary>
|
||||
/// <remarks>This is unused.</remarks>
|
||||
public uint MixBufferSampleCount;
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
using Ryujinx.Audio.Renderer.Server.Effect;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Effect
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="EffectInParameter.SpecificData"/> for <see cref="Common.EffectType.BiquadFilter"/>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct BiquadFilterEffectParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array6<byte> Input;
|
||||
|
||||
/// <summary>
|
||||
/// The output channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array6<byte> Output;
|
||||
|
||||
/// <summary>
|
||||
/// Biquad filter numerator (b0, b1, b2).
|
||||
/// </summary>
|
||||
public Array3<short> Numerator;
|
||||
|
||||
/// <summary>
|
||||
/// Biquad filter denominator (a1, a2).
|
||||
/// </summary>
|
||||
/// <remarks>a0 = 1</remarks>
|
||||
public Array2<short> Denominator;
|
||||
|
||||
/// <summary>
|
||||
/// The total channel count used.
|
||||
/// </summary>
|
||||
public byte ChannelCount;
|
||||
|
||||
/// <summary>
|
||||
/// The current usage status of the effect on the client side.
|
||||
/// </summary>
|
||||
public UsageState Status;
|
||||
}
|
||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Effect
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="EffectInParameter.SpecificData"/> for <see cref="Common.EffectType.BufferMix"/>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct BufferMixParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array24<byte> Input;
|
||||
|
||||
/// <summary>
|
||||
/// The output channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array24<byte> Output;
|
||||
|
||||
/// <summary>
|
||||
/// The output volumes of the mixes.
|
||||
/// </summary>
|
||||
public Array24<float> Volumes;
|
||||
|
||||
/// <summary>
|
||||
/// The total count of mixes used.
|
||||
/// </summary>
|
||||
public uint MixesCount;
|
||||
}
|
||||
}
|
118
Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs
Normal file
118
Ryujinx.Audio/Renderer/Parameter/Effect/DelayParameter.cs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
using Ryujinx.Audio.Renderer.Server.Effect;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Effect
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="EffectInParameter.SpecificData"/> for <see cref="Common.EffectType.Delay"/>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct DelayParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array6<byte> Input;
|
||||
|
||||
/// <summary>
|
||||
/// The output channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array6<byte> Output;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of channels supported.
|
||||
/// </summary>
|
||||
public ushort ChannelCountMax;
|
||||
|
||||
/// <summary>
|
||||
/// The total channel count used.
|
||||
/// </summary>
|
||||
public ushort ChannelCount;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum delay time in milliseconds.
|
||||
/// </summary>
|
||||
public uint DelayTimeMax;
|
||||
|
||||
/// <summary>
|
||||
/// The delay time in milliseconds.
|
||||
/// </summary>
|
||||
public uint DelayTime;
|
||||
|
||||
/// <summary>
|
||||
/// The target sample rate. (Q15)
|
||||
/// </summary>
|
||||
public uint SampleRate;
|
||||
|
||||
/// <summary>
|
||||
/// The input gain. (Q15)
|
||||
/// </summary>
|
||||
public uint InGain;
|
||||
|
||||
/// <summary>
|
||||
/// The feedback gain. (Q15)
|
||||
/// </summary>
|
||||
public uint FeedbackGain;
|
||||
|
||||
/// <summary>
|
||||
/// The output gain. (Q15)
|
||||
/// </summary>
|
||||
public uint OutGain;
|
||||
|
||||
/// <summary>
|
||||
/// The dry gain. (Q15)
|
||||
/// </summary>
|
||||
public uint DryGain;
|
||||
|
||||
/// <summary>
|
||||
/// The channel spread of the <see cref="FeedbackGain"/>. (Q15)
|
||||
/// </summary>
|
||||
public uint ChannelSpread;
|
||||
|
||||
/// <summary>
|
||||
/// The low pass amount. (Q15)
|
||||
/// </summary>
|
||||
public uint LowPassAmount;
|
||||
|
||||
/// <summary>
|
||||
/// The current usage status of the effect on the client side.
|
||||
/// </summary>
|
||||
public UsageState Status;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the <see cref="ChannelCount"/> is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the <see cref="ChannelCount"/> is valid.</returns>
|
||||
public bool IsChannelCountValid()
|
||||
{
|
||||
return EffectInParameter.IsChannelCountValid(ChannelCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the <see cref="ChannelCountMax"/> is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the <see cref="ChannelCountMax"/> is valid.</returns>
|
||||
public bool IsChannelCountMaxValid()
|
||||
{
|
||||
return EffectInParameter.IsChannelCountValid(ChannelCountMax);
|
||||
}
|
||||
}
|
||||
}
|
144
Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs
Normal file
144
Ryujinx.Audio/Renderer/Parameter/Effect/Reverb3dParameter.cs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
using Ryujinx.Audio.Renderer.Server.Effect;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Effect
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="EffectInParameter.SpecificData"/> for <see cref="Common.EffectType.Reverb3d"/>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Reverb3dParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array6<byte> Input;
|
||||
|
||||
/// <summary>
|
||||
/// The output channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array6<byte> Output;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of channels supported.
|
||||
/// </summary>
|
||||
public ushort ChannelCountMax;
|
||||
|
||||
/// <summary>
|
||||
/// The total channel count used.
|
||||
/// </summary>
|
||||
public ushort ChannelCount;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private uint _reserved;
|
||||
|
||||
/// <summary>
|
||||
/// The target sample rate.
|
||||
/// </summary>
|
||||
/// <remarks>This is in kHz.</remarks>
|
||||
public uint SampleRate;
|
||||
|
||||
/// <summary>
|
||||
/// Gain of the room high-frequency effect.
|
||||
/// </summary>
|
||||
public float RoomHf;
|
||||
|
||||
/// <summary>
|
||||
/// Reference high frequency.
|
||||
/// </summary>
|
||||
public float HfReference;
|
||||
|
||||
/// <summary>
|
||||
/// Reverberation decay time at low frequencies.
|
||||
/// </summary>
|
||||
public float DecayTime;
|
||||
|
||||
/// <summary>
|
||||
/// Ratio of the decay time at high frequencies to the decay time at low frequencies.
|
||||
/// </summary>
|
||||
public float HfDecayRatio;
|
||||
|
||||
/// <summary>
|
||||
/// Gain of the room effect.
|
||||
/// </summary>
|
||||
public float RoomGain;
|
||||
|
||||
/// <summary>
|
||||
/// Gain of the early reflections relative to <see cref="RoomGain"/>.
|
||||
/// </summary>
|
||||
public float ReflectionsGain;
|
||||
|
||||
/// <summary>
|
||||
/// Gain of the late reverberation relative to <see cref="RoomGain"/>.
|
||||
/// </summary>
|
||||
public float ReverbGain;
|
||||
|
||||
/// <summary>
|
||||
/// Echo density in the late reverberation decay.
|
||||
/// </summary>
|
||||
public float Diffusion;
|
||||
|
||||
/// <summary>
|
||||
/// Modal density in the late reverberation decay.
|
||||
/// </summary>
|
||||
public float ReflectionDelay;
|
||||
|
||||
/// <summary>
|
||||
/// Time limit between the early reflections and the late reverberation relative to the time of the first reflection.
|
||||
/// </summary>
|
||||
public float ReverbDelayTime;
|
||||
|
||||
/// <summary>
|
||||
/// Modal density in the late reverberation decay.
|
||||
/// </summary>
|
||||
public float Density;
|
||||
|
||||
/// <summary>
|
||||
/// The dry gain.
|
||||
/// </summary>
|
||||
public float DryGain;
|
||||
|
||||
/// <summary>
|
||||
/// The current usage status of the effect on the client side.
|
||||
/// </summary>
|
||||
public UsageState ParameterStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the <see cref="ChannelCount"/> is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the <see cref="ChannelCount"/> is valid.</returns>
|
||||
public bool IsChannelCountValid()
|
||||
{
|
||||
return EffectInParameter.IsChannelCountValid(ChannelCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the <see cref="ChannelCountMax"/> is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the <see cref="ChannelCountMax"/> is valid.</returns>
|
||||
public bool IsChannelCountMaxValid()
|
||||
{
|
||||
return EffectInParameter.IsChannelCountValid(ChannelCountMax);
|
||||
}
|
||||
}
|
||||
}
|
136
Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs
Normal file
136
Ryujinx.Audio/Renderer/Parameter/Effect/ReverbParameter.cs
Normal file
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="EffectInParameter.SpecificData"/> for <see cref="Common.EffectType.Reverb"/>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct ReverbParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The input channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array6<byte> Input;
|
||||
|
||||
/// <summary>
|
||||
/// The output channel indices that will be used by the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public Array6<byte> Output;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of channels supported.
|
||||
/// </summary>
|
||||
public ushort ChannelCountMax;
|
||||
|
||||
/// <summary>
|
||||
/// The total channel count used.
|
||||
/// </summary>
|
||||
public ushort ChannelCount;
|
||||
|
||||
/// <summary>
|
||||
/// The target sample rate. (Q15)
|
||||
/// </summary>
|
||||
/// <remarks>This is in kHz.</remarks>
|
||||
public int SampleRate;
|
||||
|
||||
/// <summary>
|
||||
/// The early mode to use.
|
||||
/// </summary>
|
||||
public ReverbEarlyMode EarlyMode;
|
||||
|
||||
/// <summary>
|
||||
/// The gain to apply to the result of the early reflection. (Q15)
|
||||
/// </summary>
|
||||
public int EarlyGain;
|
||||
|
||||
/// <summary>
|
||||
/// The pre-delay time in milliseconds. (Q15)
|
||||
/// </summary>
|
||||
public int PreDelayTime;
|
||||
|
||||
/// <summary>
|
||||
/// The late mode to use.
|
||||
/// </summary>
|
||||
public ReverbLateMode LateMode;
|
||||
|
||||
/// <summary>
|
||||
/// The gain to apply to the result of the late reflection. (Q15)
|
||||
/// </summary>
|
||||
public int LateGain;
|
||||
|
||||
/// <summary>
|
||||
/// The decay time. (Q15)
|
||||
/// </summary>
|
||||
public int DecayTime;
|
||||
|
||||
/// <summary>
|
||||
/// The high frequency decay ratio. (Q15)
|
||||
/// </summary>
|
||||
/// <remarks>If <see cref="HighFrequencyDecayRatio"/> >= 0.995f, it is considered disabled.</remarks>
|
||||
public int HighFrequencyDecayRatio;
|
||||
|
||||
/// <summary>
|
||||
/// The coloration of the decay. (Q15)
|
||||
/// </summary>
|
||||
public int Coloration;
|
||||
|
||||
/// <summary>
|
||||
/// The reverb gain. (Q15)
|
||||
/// </summary>
|
||||
public int ReverbGain;
|
||||
|
||||
/// <summary>
|
||||
/// The output gain. (Q15)
|
||||
/// </summary>
|
||||
public int OutGain;
|
||||
|
||||
/// <summary>
|
||||
/// The dry gain. (Q15)
|
||||
/// </summary>
|
||||
public int DryGain;
|
||||
|
||||
/// <summary>
|
||||
/// The current usage status of the effect on the client side.
|
||||
/// </summary>
|
||||
public UsageState Status;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the <see cref="ChannelCount"/> is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the <see cref="ChannelCount"/> is valid.</returns>
|
||||
public bool IsChannelCountValid()
|
||||
{
|
||||
return EffectInParameter.IsChannelCountValid(ChannelCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the <see cref="ChannelCountMax"/> is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the <see cref="ChannelCountMax"/> is valid.</returns>
|
||||
public bool IsChannelCountMaxValid()
|
||||
{
|
||||
return EffectInParameter.IsChannelCountValid(ChannelCountMax);
|
||||
}
|
||||
}
|
||||
}
|
103
Ryujinx.Audio/Renderer/Parameter/EffectInParameter.cs
Normal file
103
Ryujinx.Audio/Renderer/Parameter/EffectInParameter.cs
Normal file
|
@ -0,0 +1,103 @@
|
|||
//
|
||||
// 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.Common.Utilities;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input information for an effect.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct EffectInParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of the effect.
|
||||
/// </summary>
|
||||
public EffectType Type;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if the effect is new.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsNew;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if the effect must be active.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private byte _reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// The target mix id of the effect.
|
||||
/// </summary>
|
||||
public int MixId;
|
||||
|
||||
/// <summary>
|
||||
/// Address of the processing workbuffer.
|
||||
/// </summary>
|
||||
/// <remarks>This is additional data that could be required by the effect processing.</remarks>
|
||||
public ulong BufferBase;
|
||||
|
||||
/// <summary>
|
||||
/// Size of the processing workbuffer.
|
||||
/// </summary>
|
||||
/// <remarks>This is additional data that could be required by the effect processing.</remarks>
|
||||
public ulong BufferSize;
|
||||
|
||||
/// <summary>
|
||||
/// Position of the effect while processing effects.
|
||||
/// </summary>
|
||||
public uint ProcessingOrder;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private uint _reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Specific data storage.
|
||||
/// </summary>
|
||||
private SpecificDataStruct _specificDataStart;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 0xA0, Pack = 1)]
|
||||
private struct SpecificDataStruct { }
|
||||
|
||||
/// <summary>
|
||||
/// Specific data changing depending of the <see cref="Type"/>. See also the <see cref="Effect"/> namespace.
|
||||
/// </summary>
|
||||
public Span<byte> SpecificData => SpanHelpers.AsSpan<SpecificDataStruct, byte>(ref _specificDataStart);
|
||||
|
||||
/// <summary>
|
||||
/// Check if the given channel count is valid.
|
||||
/// </summary>
|
||||
/// <param name="channelCount">The channel count to check</param>
|
||||
/// <returns>Returns true if the channel count is valid.</returns>
|
||||
public static bool IsChannelCountValid(int channelCount)
|
||||
{
|
||||
return channelCount == 1 || channelCount == 2 || channelCount == 4 || channelCount == 6;
|
||||
}
|
||||
}
|
||||
}
|
54
Ryujinx.Audio/Renderer/Parameter/EffectOutStatus.cs
Normal file
54
Ryujinx.Audio/Renderer/Parameter/EffectOutStatus.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Output information for an effect.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct EffectOutStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The state of an effect.
|
||||
/// </summary>
|
||||
public enum EffectState : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// The effect is enabled.
|
||||
/// </summary>
|
||||
Enabled = 3,
|
||||
|
||||
/// <summary>
|
||||
/// The effect is disabled.
|
||||
/// </summary>
|
||||
Disabled = 4
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Current effect state.
|
||||
/// </summary>
|
||||
public EffectState State;
|
||||
|
||||
/// <summary>
|
||||
/// Unused/Reserved.
|
||||
/// </summary>
|
||||
private unsafe fixed byte _reserved[15];
|
||||
}
|
||||
}
|
50
Ryujinx.Audio/Renderer/Parameter/MemoryPoolInParameter.cs
Normal file
50
Ryujinx.Audio/Renderer/Parameter/MemoryPoolInParameter.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// 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 System.Runtime.InteropServices;
|
||||
using CpuAddress = System.UInt64;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input information for a memory pool.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct MemoryPoolInParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The CPU address used by the memory pool.
|
||||
/// </summary>
|
||||
public CpuAddress CpuAddress;
|
||||
|
||||
/// <summary>
|
||||
/// The size used by the memory pool.
|
||||
/// </summary>
|
||||
public ulong Size;
|
||||
|
||||
/// <summary>
|
||||
/// The target state the user wants.
|
||||
/// </summary>
|
||||
public MemoryPoolUserState State;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed uint _reserved[3];
|
||||
}
|
||||
}
|
39
Ryujinx.Audio/Renderer/Parameter/MemoryPoolOutStatus.cs
Normal file
39
Ryujinx.Audio/Renderer/Parameter/MemoryPoolOutStatus.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// 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 System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Output information for a memory pool.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct MemoryPoolOutStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The current server memory pool state.
|
||||
/// </summary>
|
||||
public MemoryPoolUserState State;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed uint _reserved[3];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input information header for mix updates on REV7 and later
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct MixInParameterDirtyOnlyUpdate
|
||||
{
|
||||
/// <summary>
|
||||
/// Magic of the header
|
||||
/// </summary>
|
||||
/// <remarks>Never checked on hardware.</remarks>
|
||||
public uint Magic;
|
||||
|
||||
/// <summary>
|
||||
/// The count of <see cref="MixParameter"/> following this header.
|
||||
/// </summary>
|
||||
public uint MixCount;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed byte _reserved[24];
|
||||
}
|
||||
}
|
112
Ryujinx.Audio/Renderer/Parameter/MixParameter.cs
Normal file
112
Ryujinx.Audio/Renderer/Parameter/MixParameter.cs
Normal file
|
@ -0,0 +1,112 @@
|
|||
//
|
||||
// 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.Common.Utilities;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input information for a mix.
|
||||
/// </summary>
|
||||
/// <remarks>Also used on the client side for mix tracking.</remarks>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct MixParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Base volume of the mix.
|
||||
/// </summary>
|
||||
public float Volume;
|
||||
|
||||
/// <summary>
|
||||
/// Target sample rate of the mix.
|
||||
/// </summary>
|
||||
public uint SampleRate;
|
||||
|
||||
/// <summary>
|
||||
/// Target buffer count.
|
||||
/// </summary>
|
||||
public uint BufferCount;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if in use.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsUsed;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if it was changed.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsDirty;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private ushort _reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// The id of the mix.
|
||||
/// </summary>
|
||||
public int MixId;
|
||||
|
||||
/// <summary>
|
||||
/// The effect count. (client side)
|
||||
/// </summary>
|
||||
public uint EffectCount;
|
||||
|
||||
/// <summary>
|
||||
/// The mix node id.
|
||||
/// </summary>
|
||||
public int NodeId;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private ulong _reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Mix buffer volumes storage.
|
||||
/// </summary>
|
||||
private MixVolumeArray _mixBufferVolumeArray;
|
||||
|
||||
/// <summary>
|
||||
/// The mix to output the result of this mix.
|
||||
/// </summary>
|
||||
public int DestinationMixId;
|
||||
|
||||
/// <summary>
|
||||
/// The splitter to output the result of this mix.
|
||||
/// </summary>
|
||||
public uint DestinationSplitterId;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private uint _reserved3;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 4 * Constants.MixBufferCountMax * Constants.MixBufferCountMax, Pack = 1)]
|
||||
private struct MixVolumeArray { }
|
||||
|
||||
/// <summary>
|
||||
/// Mix buffer volumes.
|
||||
/// </summary>
|
||||
/// <remarks>Used when no splitter id is specified.</remarks>
|
||||
public Span<float> MixBufferVolume => SpanHelpers.AsSpan<MixVolumeArray, float>(ref _mixBufferVolumeArray);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Performance
|
||||
{
|
||||
/// <summary>
|
||||
/// Input information for performance monitoring.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct PerformanceInParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The target node id to monitor performance on.
|
||||
/// </summary>
|
||||
public int TargetNodeId;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed uint _reserved[3];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Performance
|
||||
{
|
||||
/// <summary>
|
||||
/// Output information for performance monitoring.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct PerformanceOutStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the total size output to the performance buffer.
|
||||
/// </summary>
|
||||
public uint HistorySize;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed uint _reserved[3];
|
||||
}
|
||||
}
|
38
Ryujinx.Audio/Renderer/Parameter/RendererInfoOutStatus.cs
Normal file
38
Ryujinx.Audio/Renderer/Parameter/RendererInfoOutStatus.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Renderer output information on REV5 and later.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct RendererInfoOutStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The count of updates sent to the <see cref="Dsp.AudioProcessor"/>.
|
||||
/// </summary>
|
||||
public ulong ElapsedFrameCount;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/Unused.
|
||||
/// </summary>
|
||||
private ulong _reserved;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// 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.Common;
|
||||
using Ryujinx.Audio.Renderer.Common;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using CpuAddress = System.UInt64;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Sink
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="SinkInParameter.SpecificData"/> for <see cref="SinkType.CircularBuffer"/>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct CircularBufferParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The CPU address of the user circular buffer.
|
||||
/// </summary>
|
||||
public CpuAddress BufferAddress;
|
||||
|
||||
/// <summary>
|
||||
/// The size of the user circular buffer.
|
||||
/// </summary>
|
||||
public uint BufferSize;
|
||||
|
||||
/// <summary>
|
||||
/// The total count of channels to output to the circular buffer.
|
||||
/// </summary>
|
||||
public uint InputCount;
|
||||
|
||||
/// <summary>
|
||||
/// The target sample count to output per update in the circular buffer.
|
||||
/// </summary>
|
||||
public uint SampleCount;
|
||||
|
||||
/// <summary>
|
||||
/// Last read offset on the CPU side.
|
||||
/// </summary>
|
||||
public uint LastReadOffset;
|
||||
|
||||
/// <summary>
|
||||
/// The target <see cref="SampleFormat"/>.
|
||||
/// </summary>
|
||||
/// <remarks>Only <see cref="SampleFormat.PcmInt16"/> is supported.</remarks>
|
||||
public SampleFormat SampleFormat;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private unsafe fixed byte _reserved1[3];
|
||||
|
||||
/// <summary>
|
||||
/// The input channels index that will be used.
|
||||
/// </summary>
|
||||
public Array6<byte> Input;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private ushort _reserved2;
|
||||
}
|
||||
}
|
75
Ryujinx.Audio/Renderer/Parameter/Sink/DeviceParameter.cs
Normal file
75
Ryujinx.Audio/Renderer/Parameter/Sink/DeviceParameter.cs
Normal file
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// 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.Common.Memory;
|
||||
using Ryujinx.Common.Utilities;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter.Sink
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="SinkInParameter.SpecificData"/> for <see cref="Common.SinkType.Device"/>.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct DeviceParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Device name storage.
|
||||
/// </summary>
|
||||
private DeviceNameStruct _deviceName;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private byte _padding;
|
||||
|
||||
/// <summary>
|
||||
/// The total count of channels to output to the device.
|
||||
/// </summary>
|
||||
public uint InputCount;
|
||||
|
||||
/// <summary>
|
||||
/// The input channels index that will be used.
|
||||
/// </summary>
|
||||
public Array6<byte> Input;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private byte _reserved;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if the user controls Surround to Stereo downmixing coefficients.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool DownMixParameterEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// The user Surround to Stereo downmixing coefficients.
|
||||
/// </summary>
|
||||
public Array4<float> DownMixParameter;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 0xFF, Pack = 1)]
|
||||
private struct DeviceNameStruct { }
|
||||
|
||||
/// <summary>
|
||||
/// The output device name.
|
||||
/// </summary>
|
||||
public Span<byte> DeviceName => SpanHelpers.AsSpan<DeviceNameStruct, byte>(ref _deviceName);
|
||||
}
|
||||
}
|
70
Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs
Normal file
70
Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// 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.Common.Utilities;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input information for a sink.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SinkInParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of the sink.
|
||||
/// </summary>
|
||||
public SinkType Type;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if the sink is used.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsUsed;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private ushort _reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// The node id of the sink.
|
||||
/// </summary>
|
||||
public int NodeId;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private unsafe fixed ulong _reserved2[3];
|
||||
|
||||
/// <summary>
|
||||
/// Specific data storage.
|
||||
/// </summary>
|
||||
private SpecificDataStruct _specificDataStart;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 0x120, Pack = 1)]
|
||||
private struct SpecificDataStruct { }
|
||||
|
||||
/// <summary>
|
||||
/// Specific data changing depending of the <see cref="Type"/>. See also the <see cref="Sink"/> namespace.
|
||||
/// </summary>
|
||||
public Span<byte> SpecificData => SpanHelpers.AsSpan<SpecificDataStruct, byte>(ref _specificDataStart);
|
||||
}
|
||||
}
|
43
Ryujinx.Audio/Renderer/Parameter/SinkOutStatus.cs
Normal file
43
Ryujinx.Audio/Renderer/Parameter/SinkOutStatus.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Output information for a sink.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SinkOutStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Last written offset if the sink type is <see cref="Common.SinkType.CircularBuffer"/>.
|
||||
/// </summary>
|
||||
public uint LastWrittenOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private uint _padding;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private unsafe fixed ulong _reserved[3];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// 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.Common.Utilities;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input header for a splitter destination update.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SplitterDestinationInParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Magic of the input header.
|
||||
/// </summary>
|
||||
public uint Magic;
|
||||
|
||||
/// <summary>
|
||||
/// Target splitter destination data id.
|
||||
/// </summary>
|
||||
public int Id;
|
||||
|
||||
/// <summary>
|
||||
/// Mix buffer volumes storage.
|
||||
/// </summary>
|
||||
private MixArray _mixBufferVolume;
|
||||
|
||||
/// <summary>
|
||||
/// The mix to output the result of the splitter.
|
||||
/// </summary>
|
||||
public int DestinationId;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if in use.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsUsed;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/padding.
|
||||
/// </summary>
|
||||
private unsafe fixed byte _reserved[3];
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 4 * Constants.MixBufferCountMax, Pack = 1)]
|
||||
private struct MixArray { }
|
||||
|
||||
/// <summary>
|
||||
/// Mix buffer volumes.
|
||||
/// </summary>
|
||||
/// <remarks>Used when a splitter id is specified in the mix.</remarks>
|
||||
public Span<float> MixBufferVolume => SpanHelpers.AsSpan<MixArray, float>(ref _mixBufferVolume);
|
||||
|
||||
/// <summary>
|
||||
/// The expected constant of any input header.
|
||||
/// </summary>
|
||||
private const uint ValidMagic = 0x44444E53;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the magic is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the magic is valid.</returns>
|
||||
public bool IsMagicValid()
|
||||
{
|
||||
return Magic == ValidMagic;
|
||||
}
|
||||
}
|
||||
}
|
63
Ryujinx.Audio/Renderer/Parameter/SplitterInParameter.cs
Normal file
63
Ryujinx.Audio/Renderer/Parameter/SplitterInParameter.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input header for a splitter state update.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SplitterInParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Magic of the input header.
|
||||
/// </summary>
|
||||
public uint Magic;
|
||||
|
||||
/// <summary>
|
||||
/// Target splitter id.
|
||||
/// </summary>
|
||||
public int Id;
|
||||
|
||||
/// <summary>
|
||||
/// Target sample rate to use on the splitter.
|
||||
/// </summary>
|
||||
public uint SampleRate;
|
||||
|
||||
/// <summary>
|
||||
/// Count of splitter destinations.
|
||||
/// </summary>
|
||||
/// <remarks>Splitter destination ids are defined right after this header.</remarks>
|
||||
public int DestinationCount;
|
||||
|
||||
/// <summary>
|
||||
/// The expected constant of any input header.
|
||||
/// </summary>
|
||||
private const uint ValidMagic = 0x49444E53;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the magic is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the magic is valid.</returns>
|
||||
public bool IsMagicValid()
|
||||
{
|
||||
return Magic == ValidMagic;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input header for splitter update.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct SplitterInParameterHeader
|
||||
{
|
||||
/// <summary>
|
||||
/// Magic of the input header.
|
||||
/// </summary>
|
||||
public uint Magic;
|
||||
|
||||
/// <summary>
|
||||
/// The count of <see cref="SplitterInParameter"/> after the header.
|
||||
/// </summary>
|
||||
public uint SplitterCount;
|
||||
|
||||
/// <summary>
|
||||
/// The count of splitter destinations after the header and splitter info.
|
||||
/// </summary>
|
||||
public uint SplitterDestinationCount;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed uint _reserved[5];
|
||||
|
||||
/// <summary>
|
||||
/// The expected constant of any input splitter header.
|
||||
/// </summary>
|
||||
private const uint ValidMagic = 0x48444E53;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the magic is valid.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the magic is valid.</returns>
|
||||
public bool IsMagicValid()
|
||||
{
|
||||
return Magic == ValidMagic;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// 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.Common.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input information for a voice channel resources.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Size = 0x70, Pack = 1)]
|
||||
public struct VoiceChannelResourceInParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// The id of the voice channel resource.
|
||||
/// </summary>
|
||||
public uint Id;
|
||||
|
||||
/// <summary>
|
||||
/// Mix volumes for the voice channel resource.
|
||||
/// </summary>
|
||||
public Array24<float> Mix;
|
||||
|
||||
/// <summary>
|
||||
/// Indicate if the voice channel resource is used.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsUsed;
|
||||
}
|
||||
}
|
361
Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs
Normal file
361
Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs
Normal file
|
@ -0,0 +1,361 @@
|
|||
//
|
||||
// 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.Common;
|
||||
using Ryujinx.Audio.Renderer.Common;
|
||||
using Ryujinx.Audio.Renderer.Dsp;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Input information for a voice.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Size = 0x170, Pack = 1)]
|
||||
public struct VoiceInParameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of the voice.
|
||||
/// </summary>
|
||||
public int Id;
|
||||
|
||||
/// <summary>
|
||||
/// Node id of the voice.
|
||||
/// </summary>
|
||||
public int NodeId;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if the voice is new.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsNew;
|
||||
|
||||
/// <summary>
|
||||
/// Set to true if the voice is used.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool InUse;
|
||||
|
||||
/// <summary>
|
||||
/// The voice <see cref="PlayState"/> wanted by the user.
|
||||
/// </summary>
|
||||
public PlayState PlayState;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="SampleFormat"/> of the voice.
|
||||
/// </summary>
|
||||
public SampleFormat SampleFormat;
|
||||
|
||||
/// <summary>
|
||||
/// The sample rate of the voice.
|
||||
/// </summary>
|
||||
public uint SampleRate;
|
||||
|
||||
/// <summary>
|
||||
/// The priority of the voice.
|
||||
/// </summary>
|
||||
public uint Priority;
|
||||
|
||||
/// <summary>
|
||||
/// Target sorting position of the voice. (Used to sort voices with the same <see cref="Priority"/>)
|
||||
/// </summary>
|
||||
public uint SortingOrder;
|
||||
|
||||
/// <summary>
|
||||
/// The total channel count used.
|
||||
/// </summary>
|
||||
public uint ChannelCount;
|
||||
|
||||
/// <summary>
|
||||
/// The pitch used on the voice.
|
||||
/// </summary>
|
||||
public float Pitch;
|
||||
|
||||
/// <summary>
|
||||
/// The output volume of the voice.
|
||||
/// </summary>
|
||||
public float Volume;
|
||||
|
||||
/// <summary>
|
||||
/// Biquad filters to apply to the output of the voice.
|
||||
/// </summary>
|
||||
public Array2<BiquadFilterParameter> BiquadFilters;
|
||||
|
||||
/// <summary>
|
||||
/// Total count of <see cref="WaveBufferInternal"/> of the voice.
|
||||
/// </summary>
|
||||
public uint WaveBuffersCount;
|
||||
|
||||
/// <summary>
|
||||
/// Current playing <see cref="WaveBufferInternal"/> of the voice.
|
||||
/// </summary>
|
||||
public uint WaveBuffersIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private uint _reserved1;
|
||||
|
||||
/// <summary>
|
||||
/// User state address required by the data source.
|
||||
/// </summary>
|
||||
/// <remarks>Only used for <see cref="SampleFormat.Adpcm"/> as the address of the GC-ADPCM coefficients.</remarks>
|
||||
public ulong DataSourceStateAddress;
|
||||
|
||||
/// <summary>
|
||||
/// User state size required by the data source.
|
||||
/// </summary>
|
||||
/// <remarks>Only used for <see cref="SampleFormat.Adpcm"/> as the size of the GC-ADPCM coefficients.</remarks>
|
||||
public ulong DataSourceStateSize;
|
||||
|
||||
/// <summary>
|
||||
/// The target mix id of the voice.
|
||||
/// </summary>
|
||||
public int MixId;
|
||||
|
||||
/// <summary>
|
||||
/// The target splitter id of the voice.
|
||||
/// </summary>
|
||||
public uint SplitterId;
|
||||
|
||||
/// <summary>
|
||||
/// The wavebuffer parameters of this voice.
|
||||
/// </summary>
|
||||
public Array4<WaveBufferInternal> WaveBuffers;
|
||||
|
||||
/// <summary>
|
||||
/// The channel resource ids associated to the voice.
|
||||
/// </summary>
|
||||
public Array6<int> ChannelResourceIds;
|
||||
|
||||
/// <summary>
|
||||
/// Reset the voice drop flag during voice server update.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool ResetVoiceDropFlag;
|
||||
|
||||
/// <summary>
|
||||
/// Flush the amount of wavebuffer specified. This will result in the wavebuffer being skipped and marked played.
|
||||
/// </summary>
|
||||
/// <remarks>This was added on REV5.</remarks>
|
||||
public byte FlushWaveBufferCount;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private ushort _reserved2;
|
||||
|
||||
/// <summary>
|
||||
/// Change the behaviour of the voice.
|
||||
/// </summary>
|
||||
/// <remarks>This was added on REV5.</remarks>
|
||||
public DecodingBehaviour DecodingBehaviourFlags;
|
||||
|
||||
/// <summary>
|
||||
/// Change the Sample Rate Conversion (SRC) quality of the voice.
|
||||
/// </summary>
|
||||
/// <remarks>This was added on REV8.</remarks>
|
||||
public SampleRateConversionQuality SrcQuality;
|
||||
|
||||
/// <summary>
|
||||
/// This was previously used for opus codec support on the Audio Renderer and was removed on REV3.
|
||||
/// </summary>
|
||||
public uint ExternalContext;
|
||||
|
||||
/// <summary>
|
||||
/// This was previously used for opus codec support on the Audio Renderer and was removed on REV3.
|
||||
/// </summary>
|
||||
public uint ExternalContextSize;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed uint _reserved3[2];
|
||||
|
||||
/// <summary>
|
||||
/// Input information for a voice wavebuffer.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Size = 0x38, Pack = 1)]
|
||||
public struct WaveBufferInternal
|
||||
{
|
||||
/// <summary>
|
||||
/// Address of the wavebuffer data.
|
||||
/// </summary>
|
||||
public ulong Address;
|
||||
|
||||
/// <summary>
|
||||
/// Size of the wavebuffer data.
|
||||
/// </summary>
|
||||
public ulong Size;
|
||||
|
||||
/// <summary>
|
||||
/// Offset of the first sample to play.
|
||||
/// </summary>
|
||||
public uint StartSampleOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Offset of the last sample to play.
|
||||
/// </summary>
|
||||
public uint EndSampleOffset;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, the wavebuffer will loop when reaching <see cref="EndSampleOffset"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Starting with REV8, you can specify how many times to loop the wavebuffer (<see cref="LoopCount"/>) and where it should start and end when looping (<see cref="LoopFirstSampleOffset"/> and <see cref="LoopLastSampleOffset"/>)
|
||||
/// </remarks>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool ShouldLoop;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that this is the last wavebuffer to play of the voice.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool IsEndOfStream;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if the server should update its internal state.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool SentToServer;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private byte _reserved;
|
||||
|
||||
/// <summary>
|
||||
/// If set to anything other than 0, specifies how many times to loop the wavebuffer.
|
||||
/// </summary>
|
||||
/// <remarks>This was added in REV8.</remarks>
|
||||
public int LoopCount;
|
||||
|
||||
/// <summary>
|
||||
/// Address of the context used by the sample decoder.
|
||||
/// </summary>
|
||||
/// <remarks>This is only currently used by <see cref="SampleFormat.Adpcm"/>.</remarks>
|
||||
public ulong ContextAddress;
|
||||
|
||||
/// <summary>
|
||||
/// Size of the context used by the sample decoder.
|
||||
/// </summary>
|
||||
/// <remarks>This is only currently used by <see cref="SampleFormat.Adpcm"/>.</remarks>
|
||||
public ulong ContextSize;
|
||||
|
||||
/// <summary>
|
||||
/// If set to anything other than 0, specifies the offset of the first sample to play when looping.
|
||||
/// </summary>
|
||||
/// <remarks>This was added in REV8.</remarks>
|
||||
public uint LoopFirstSampleOffset;
|
||||
|
||||
/// <summary>
|
||||
/// If set to anything other than 0, specifies the offset of the last sample to play when looping.
|
||||
/// </summary>
|
||||
/// <remarks>This was added in REV8.</remarks>
|
||||
public uint LoopLastSampleOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the sample offsets are in a valid range for generic PCM.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The PCM sample type</typeparam>
|
||||
/// <returns>Returns true if the sample offset are in range of the size.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private bool IsSampleOffsetInRangeForPcm<T>() where T : unmanaged
|
||||
{
|
||||
uint dataTypeSize = (uint)Unsafe.SizeOf<T>();
|
||||
|
||||
return StartSampleOffset * dataTypeSize <= Size &&
|
||||
EndSampleOffset * dataTypeSize <= Size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if the sample offsets are in a valid range for the given <see cref="SampleFormat"/>.
|
||||
/// </summary>
|
||||
/// <param name="format">The target <see cref="SampleFormat"/></param>
|
||||
/// <returns>Returns true if the sample offset are in range of the size.</returns>
|
||||
public bool IsSampleOffsetValid(SampleFormat format)
|
||||
{
|
||||
bool result;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case SampleFormat.PcmInt16:
|
||||
result = IsSampleOffsetInRangeForPcm<ushort>();
|
||||
break;
|
||||
case SampleFormat.PcmFloat:
|
||||
result = IsSampleOffsetInRangeForPcm<float>();
|
||||
break;
|
||||
case SampleFormat.Adpcm:
|
||||
result = AdpcmHelper.GetAdpcmDataSize((int)StartSampleOffset) <= Size &&
|
||||
AdpcmHelper.GetAdpcmDataSize((int)EndSampleOffset) <= Size;
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException($"{format} not implemented!");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flag altering the behaviour of wavebuffer decoding.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum DecodingBehaviour : ushort
|
||||
{
|
||||
/// <summary>
|
||||
/// Default decoding behaviour.
|
||||
/// </summary>
|
||||
Default = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Reset the played samples accumulator when looping.
|
||||
/// </summary>
|
||||
PlayedSampleCountResetWhenLooping = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Skip pitch and Sample Rate Conversion (SRC).
|
||||
/// </summary>
|
||||
SkipPitchAndSampleRateConversion = 2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify the quality to use during Sample Rate Conversion (SRC) and pitch handling.
|
||||
/// </summary>
|
||||
/// <remarks>This was added in REV8.</remarks>
|
||||
public enum SampleRateConversionQuality : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Resample interpolating 4 samples per output sample.
|
||||
/// </summary>
|
||||
Default,
|
||||
|
||||
/// <summary>
|
||||
/// Resample interpolating 8 samples per output sample.
|
||||
/// </summary>
|
||||
High,
|
||||
|
||||
/// <summary>
|
||||
/// Resample interpolating 1 samples per output sample.
|
||||
/// </summary>
|
||||
Low
|
||||
}
|
||||
}
|
||||
}
|
52
Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs
Normal file
52
Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// 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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Audio.Renderer.Parameter
|
||||
{
|
||||
/// <summary>
|
||||
/// Output information about a voice.
|
||||
/// </summary>
|
||||
/// <remarks>See <seealso cref="Server.StateUpdater.UpdateVoices(Server.Voice.VoiceContext, System.Memory{Server.MemoryPool.MemoryPoolState})"/></remarks>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct VoiceOutStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The total amount of samples that was played.
|
||||
/// </summary>
|
||||
/// <remarks>This is reset to 0 when a <see cref="Common.WaveBuffer"/> finishes playing and <see cref="Common.WaveBuffer.IsEndOfStream"/> is set.</remarks>
|
||||
/// <remarks>This is reset to 0 when looping while <see cref="Parameter.VoiceInParameter.DecodingBehaviour.PlayedSampleCountResetWhenLooping"/> is set.</remarks>
|
||||
public ulong PlayedSampleCount;
|
||||
|
||||
/// <summary>
|
||||
/// The total amount of <see cref="WaveBuffer"/> consumed.
|
||||
/// </summary>
|
||||
public uint PlayedWaveBuffersCount;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, the voice was dropped.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool VoiceDropFlag;
|
||||
|
||||
/// <summary>
|
||||
/// Reserved/unused.
|
||||
/// </summary>
|
||||
private unsafe fixed byte _reserved[3];
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue