 f556c80d02
			
		
	
	
		f556c80d02
		
			
		
	
	
	
	
		
			
			* 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
		
			
				
	
	
		
			121 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //
 | |
| // 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.Dsp.State;
 | |
| using Ryujinx.Common.Memory;
 | |
| using Ryujinx.Common.Utilities;
 | |
| using System;
 | |
| using System.Runtime.InteropServices;
 | |
| 
 | |
| namespace Ryujinx.Audio.Renderer.Common
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Represent the update state of a voice.
 | |
|     /// </summary>
 | |
|     /// <remarks>This is shared between the server and audio processor.</remarks>
 | |
|     [StructLayout(LayoutKind.Sequential, Pack = Align)]
 | |
|     public struct VoiceUpdateState
 | |
|     {
 | |
|         public const int Align = 0x10;
 | |
|         public const int BiquadStateOffset = 0x0;
 | |
|         public const int BiquadStateSize = 0x10;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The state of the biquad filters of this voice.
 | |
|         /// </summary>
 | |
|         public Array2<BiquadFilterState> BiquadFilterState;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The total amount of samples that was played.
 | |
|         /// </summary>
 | |
|         /// <remarks>This is reset to 0 when a <see cref="WaveBuffer"/> finishes playing and <see cref="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 current sample offset in the <see cref="WaveBuffer"/> pointed by <see cref="WaveBufferIndex"/>.
 | |
|         /// </summary>
 | |
|         public int Offset;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The current index of the <see cref="WaveBuffer"/> in use.
 | |
|         /// </summary>
 | |
|         public uint WaveBufferIndex;
 | |
| 
 | |
|         private WaveBufferValidArray _isWaveBufferValid;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The total amount of <see cref="WaveBuffer"/> consumed.
 | |
|         /// </summary>
 | |
|         public uint WaveBufferConsumed;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Pitch used for Sample Rate Conversion.
 | |
|         /// </summary>
 | |
|         public Array8<short> Pitch;
 | |
| 
 | |
|         public float Fraction;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The ADPCM loop context when <see cref="SampleFormat.Adpcm"/> is in use.
 | |
|         /// </summary>
 | |
|         public AdpcmLoopContext LoopContext;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The last samples after a mix ramp.
 | |
|         /// </summary>
 | |
|         /// <remarks>This is used for depop (to perform voice drop).</remarks>
 | |
|         public Array24<float> LastSamples;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// The current count of loop performed.
 | |
|         /// </summary>
 | |
|         public int LoopCount;
 | |
| 
 | |
|         [StructLayout(LayoutKind.Sequential, Size = 1 * Constants.VoiceWaveBufferCount, Pack = 1)]
 | |
|         private struct WaveBufferValidArray { }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Contains information of <see cref="WaveBuffer"/> validity.
 | |
|         /// </summary>
 | |
|         public Span<bool> IsWaveBufferValid => SpanHelpers.AsSpan<WaveBufferValidArray, bool>(ref _isWaveBufferValid);
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Mark the current <see cref="WaveBuffer"/> as played and switch to the next one.
 | |
|         /// </summary>
 | |
|         /// <param name="waveBuffer">The current <see cref="WaveBuffer"/></param>
 | |
|         /// <param name="waveBufferIndex">The wavebuffer index.</param>
 | |
|         /// <param name="waveBufferConsumed">The amount of wavebuffers consumed.</param>
 | |
|         /// <param name="playedSampleCount">The total count of sample played.</param>
 | |
|         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;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |