using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using System; using System.Runtime.InteropServices; namespace Ryujinx.Audio.Renderer.Common { /// /// Represent the update state of a voice. /// /// This is shared between the server and audio processor. [StructLayout(LayoutKind.Sequential, Pack = Align)] public struct VoiceUpdateState { public const int Align = 0x10; public const int BiquadStateOffset = 0x0; public const int BiquadStateSize = 0x10; /// /// The state of the biquad filters of this voice. /// public Array2 BiquadFilterState; /// /// The total amount of samples that was played. /// /// This is reset to 0 when a finishes playing and is set. /// This is reset to 0 when looping while is set. public ulong PlayedSampleCount; /// /// The current sample offset in the pointed by . /// public int Offset; /// /// The current index of the in use. /// public uint WaveBufferIndex; private WaveBufferValidArray _isWaveBufferValid; /// /// The total amount of consumed. /// public uint WaveBufferConsumed; /// /// Pitch used for Sample Rate Conversion. /// public Array8 Pitch; public float Fraction; /// /// The ADPCM loop context when is in use. /// public AdpcmLoopContext LoopContext; /// /// The last samples after a mix ramp. /// /// This is used for depop (to perform voice drop). public Array24 LastSamples; /// /// The current count of loop performed. /// public int LoopCount; [StructLayout(LayoutKind.Sequential, Size = 1 * Constants.VoiceWaveBufferCount, Pack = 1)] private struct WaveBufferValidArray { } /// /// Contains information of validity. /// public Span IsWaveBufferValid => SpanHelpers.AsSpan(ref _isWaveBufferValid); /// /// Mark the current as played and switch to the next one. /// /// The current /// The wavebuffer index. /// The amount of wavebuffers consumed. /// The total count of sample played. public void MarkEndOfBufferWaveBufferProcessing(ref WaveBuffer waveBuffer, ref int waveBufferIndex, ref uint waveBufferConsumed, ref ulong playedSampleCount) { IsWaveBufferValid[waveBufferIndex++] = false; LoopCount = 0; waveBufferConsumed++; if (waveBufferIndex >= Constants.VoiceWaveBufferCount) { waveBufferIndex = 0; } if (waveBuffer.IsEndOfStream) { playedSampleCount = 0; } } } }