diff options
| author | Mary <me@thog.eu> | 2021-02-26 01:11:56 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-26 01:11:56 +0100 |
| commit | f556c80d0230056335632b60c71f1567e177239e (patch) | |
| tree | 748aa6be62b93a8e941e25dbd83f39e1dbb37035 /Ryujinx.Audio.Renderer/Server/Effect/BaseEffect.cs | |
| parent | 1c49089ff00fc87dc4872f135dc6a0d36169a970 (diff) | |
Haydn: Part 1 (#2007)
* Haydn: Part 1
Based on my reverse of audio 11.0.0.
As always, core implementation under LGPLv3 for the same reasons as for Amadeus.
This place the bases of a more flexible audio system while making audout & audin accurate.
This have the following improvements:
- Complete reimplementation of audout and audin.
- Audin currently only have a dummy backend.
- Dramatically reduce CPU usage by up to 50% in common cases (SoundIO and OpenAL).
- Audio Renderer now can output to 5.1 devices when supported.
- Audio Renderer init its backend on demand instead of keeping two up all the time.
- All backends implementation are now in their own project.
- Ryujinx.Audio.Renderer was renamed Ryujinx.Audio and was refactored because of this.
As a note, games having issues with OpenAL haven't improved and will not
because of OpenAL design (stopping when buffers finish playing causing
possible audio "pops" when buffers are very small).
* Update for latest hexkyz's edits on Switchbrew
* audren: Rollback channel configuration changes
* Address gdkchan's comments
* Fix typo in OpenAL backend driver
* Address last comments
* Fix a nit
* Address gdkchan's comments
Diffstat (limited to 'Ryujinx.Audio.Renderer/Server/Effect/BaseEffect.cs')
| -rw-r--r-- | Ryujinx.Audio.Renderer/Server/Effect/BaseEffect.cs | 257 |
1 files changed, 0 insertions, 257 deletions
diff --git a/Ryujinx.Audio.Renderer/Server/Effect/BaseEffect.cs b/Ryujinx.Audio.Renderer/Server/Effect/BaseEffect.cs deleted file mode 100644 index 7c491fd1..00000000 --- a/Ryujinx.Audio.Renderer/Server/Effect/BaseEffect.cs +++ /dev/null @@ -1,257 +0,0 @@ -// -// Copyright (c) 2019-2021 Ryujinx -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <https://www.gnu.org/licenses/>. -// - -using Ryujinx.Audio.Renderer.Common; -using Ryujinx.Audio.Renderer.Parameter; -using Ryujinx.Audio.Renderer.Server.MemoryPool; -using Ryujinx.Audio.Renderer.Utils; -using System; -using System.Diagnostics; -using static Ryujinx.Audio.Renderer.Common.BehaviourParameter; - -using DspAddress = System.UInt64; - -namespace Ryujinx.Audio.Renderer.Server.Effect -{ - /// <summary> - /// Base class used as a server state for an effect. - /// </summary> - public class BaseEffect - { - /// <summary> - /// The <see cref="EffectType"/> of the effect. - /// </summary> - public EffectType Type; - - /// <summary> - /// Set to true if the effect must be active. - /// </summary> - public bool IsEnabled; - - /// <summary> - /// Set to true if the internal effect work buffers used wasn't mapped. - /// </summary> - public bool BufferUnmapped; - - /// <summary> - /// The current state of the effect. - /// </summary> - public UsageState UsageState; - - /// <summary> - /// The target mix id of the effect. - /// </summary> - public int MixId; - - /// <summary> - /// Position of the effect while processing effects. - /// </summary> - public uint ProcessingOrder; - - /// <summary> - /// Array of all the work buffer used by the effect. - /// </summary> - protected AddressInfo[] WorkBuffers; - - /// <summary> - /// Create a new <see cref="BaseEffect"/>. - /// </summary> - public BaseEffect() - { - Type = TargetEffectType; - UsageState = UsageState.Invalid; - - IsEnabled = false; - BufferUnmapped = false; - MixId = RendererConstants.UnusedMixId; - ProcessingOrder = uint.MaxValue; - - WorkBuffers = new AddressInfo[2]; - - foreach (ref AddressInfo info in WorkBuffers.AsSpan()) - { - info = AddressInfo.Create(); - } - } - - /// <summary> - /// The target <see cref="EffectType"/> handled by this <see cref="BaseEffect"/>. - /// </summary> - public virtual EffectType TargetEffectType => EffectType.Invalid; - - /// <summary> - /// Check if the <see cref="EffectType"/> sent by the user match the internal <see cref="EffectType"/>. - /// </summary> - /// <param name="parameter">The user parameter.</param> - /// <returns>Returns true if the <see cref="EffectType"/> sent by the user matches the internal <see cref="EffectType"/>.</returns> - public bool IsTypeValid(ref EffectInParameter parameter) - { - return parameter.Type == TargetEffectType; - } - - /// <summary> - /// Update the usage state during command generation. - /// </summary> - protected void UpdateUsageStateForCommandGeneration() - { - UsageState = IsEnabled ? UsageState.Enabled : UsageState.Disabled; - } - - /// <summary> - /// Update the internal common parameters from a user parameter. - /// </summary> - /// <param name="parameter">The user parameter.</param> - protected void UpdateParameterBase(ref EffectInParameter parameter) - { - MixId = parameter.MixId; - ProcessingOrder = parameter.ProcessingOrder; - } - - /// <summary> - /// Force unmap all the work buffers. - /// </summary> - /// <param name="mapper">The mapper to use.</param> - public void ForceUnmapBuffers(PoolMapper mapper) - { - foreach (ref AddressInfo info in WorkBuffers.AsSpan()) - { - if (info.GetReference(false) != 0) - { - mapper.ForceUnmap(ref info); - } - } - } - - /// <summary> - /// Check if the effect needs to be skipped. - /// </summary> - /// <returns>Returns true if the effect needs to be skipped.</returns> - public bool ShouldSkip() - { - return BufferUnmapped; - } - - /// <summary> - /// Update the <see cref="BaseEffect"/> state during command generation. - /// </summary> - public virtual void UpdateForCommandGeneration() - { - Debug.Assert(Type == TargetEffectType); - } - - /// <summary> - /// Update the internal state from a user parameter. - /// </summary> - /// <param name="updateErrorInfo">The possible <see cref="ErrorInfo"/> that was generated.</param> - /// <param name="parameter">The user parameter.</param> - /// <param name="mapper">The mapper to use.</param> - public virtual void Update(out ErrorInfo updateErrorInfo, ref EffectInParameter parameter, PoolMapper mapper) - { - Debug.Assert(IsTypeValid(ref parameter)); - - updateErrorInfo = new ErrorInfo(); - } - - /// <summary> - /// Get the work buffer DSP address at the given index. - /// </summary> - /// <param name="index">The index of the work buffer</param> - /// <returns>The work buffer DSP address at the given index.</returns> - public virtual DspAddress GetWorkBuffer(int index) - { - throw new InvalidOperationException(); - } - - /// <summary> - /// Get the first work buffer DSP address. - /// </summary> - /// <returns>The first work buffer DSP address.</returns> - protected DspAddress GetSingleBuffer() - { - if (IsEnabled) - { - return WorkBuffers[0].GetReference(true); - } - - if (UsageState != UsageState.Disabled) - { - DspAddress address = WorkBuffers[0].GetReference(false); - ulong size = WorkBuffers[0].Size; - - if (address != 0 && size != 0) - { - AudioProcessorMemoryManager.InvalidateDataCache(address, size); - } - } - - return 0; - } - - /// <summary> - /// Store the output status to the given user output. - /// </summary> - /// <param name="outStatus">The given user output.</param> - /// <param name="isAudioRendererActive">If set to true, the <see cref="AudioRenderSystem"/> is active.</param> - public void StoreStatus(ref EffectOutStatus outStatus, bool isAudioRendererActive) - { - if (isAudioRendererActive) - { - if (UsageState == UsageState.Disabled) - { - outStatus.State = EffectOutStatus.EffectState.Disabled; - } - else - { - outStatus.State = EffectOutStatus.EffectState.Enabled; - } - } - else if (UsageState == UsageState.New) - { - outStatus.State = EffectOutStatus.EffectState.Enabled; - } - else - { - outStatus.State = EffectOutStatus.EffectState.Disabled; - } - } - - /// <summary> - /// Get the <see cref="PerformanceDetailType"/> associated to the <see cref="Type"/> of this effect. - /// </summary> - /// <returns>The <see cref="PerformanceDetailType"/> associated to the <see cref="Type"/> of this effect.</returns> - public PerformanceDetailType GetPerformanceDetailType() - { - switch (Type) - { - case EffectType.BiquadFilter: - return PerformanceDetailType.BiquadFilter; - case EffectType.AuxiliaryBuffer: - return PerformanceDetailType.Aux; - case EffectType.Delay: - return PerformanceDetailType.Delay; - case EffectType.Reverb: - return PerformanceDetailType.Reverb; - case EffectType.Reverb3d: - return PerformanceDetailType.Reverb3d; - case EffectType.BufferMix: - return PerformanceDetailType.Mix; - default: - throw new NotImplementedException($"{Type}"); - } - } - } -} |
