From d4d0a48bfe89d6e8e12ce16829bb2c440b56007c Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 22 Feb 2024 16:58:33 -0300 Subject: Migrate Audio service to new IPC (#6285) * Migrate audren to new IPC * Migrate audout * Migrate audin * Migrate hwopus * Bye bye old audio service * Switch volume control to IHardwareDeviceDriver * Somewhat unrelated changes * Remove Concentus reference from HLE * Implement OpenAudioRendererForManualExecution * Remove SetVolume/GetVolume methods that are not necessary * Remove SetVolume/GetVolume methods that are not necessary (2) * Fix incorrect volume update * PR feedback * PR feedback * Stub audrec * Init outParameter * Make FinalOutputRecorderParameter/Internal readonly * Make FinalOutputRecorder IDisposable * Fix HardwareOpusDecoderManager parameter buffers * Opus work buffer size and error handling improvements * Add AudioInProtocolName enum * Fix potential divisions by zero --- .../CompatLayer/CompatLayerHardwareDeviceDriver.cs | 12 ++++-- .../Backends/Dummy/DummyHardwareDeviceDriver.cs | 8 +++- .../Dummy/DummyHardwareDeviceSessionOutput.cs | 4 +- src/Ryujinx.Audio/Input/AudioInputManager.cs | 8 +--- .../Integration/HardwareDeviceImpl.cs | 4 +- .../Integration/IHardwareDeviceDriver.cs | 4 +- src/Ryujinx.Audio/Output/AudioOutputManager.cs | 47 +--------------------- src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs | 34 ++-------------- .../Renderer/Server/AudioRendererManager.cs | 28 +++---------- 9 files changed, 33 insertions(+), 116 deletions(-) (limited to 'src/Ryujinx.Audio') diff --git a/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs b/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs index 3f3806c3..a2c2cdcd 100644 --- a/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs @@ -16,6 +16,12 @@ namespace Ryujinx.Audio.Backends.CompatLayer public static bool IsSupported => true; + public float Volume + { + get => _realDriver.Volume; + set => _realDriver.Volume = value; + } + public CompatLayerHardwareDeviceDriver(IHardwareDeviceDriver realDevice) { _realDriver = realDevice; @@ -90,7 +96,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer throw new ArgumentException("No valid sample format configuration found!"); } - public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume) + public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount) { if (channelCount == 0) { @@ -102,8 +108,6 @@ namespace Ryujinx.Audio.Backends.CompatLayer sampleRate = Constants.TargetSampleRate; } - volume = Math.Clamp(volume, 0, 1); - if (!_realDriver.SupportsDirection(direction)) { if (direction == Direction.Input) @@ -119,7 +123,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer SampleFormat hardwareSampleFormat = SelectHardwareSampleFormat(sampleFormat); uint hardwareChannelCount = SelectHardwareChannelCount(channelCount); - IHardwareDeviceSession realSession = _realDriver.OpenDeviceSession(direction, memoryManager, hardwareSampleFormat, sampleRate, hardwareChannelCount, volume); + IHardwareDeviceSession realSession = _realDriver.OpenDeviceSession(direction, memoryManager, hardwareSampleFormat, sampleRate, hardwareChannelCount); if (hardwareChannelCount == channelCount && hardwareSampleFormat == sampleFormat) { diff --git a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs index bac21c44..3a3c1d1b 100644 --- a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs @@ -14,13 +14,17 @@ namespace Ryujinx.Audio.Backends.Dummy public static bool IsSupported => true; + public float Volume { get; set; } + public DummyHardwareDeviceDriver() { _updateRequiredEvent = new ManualResetEvent(false); _pauseEvent = new ManualResetEvent(true); + + Volume = 1f; } - public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume) + public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount) { if (sampleRate == 0) { @@ -34,7 +38,7 @@ namespace Ryujinx.Audio.Backends.Dummy if (direction == Direction.Output) { - return new DummyHardwareDeviceSessionOutput(this, memoryManager, sampleFormat, sampleRate, channelCount, volume); + return new DummyHardwareDeviceSessionOutput(this, memoryManager, sampleFormat, sampleRate, channelCount); } return new DummyHardwareDeviceSessionInput(this, memoryManager); diff --git a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs index 1c248faa..34cf653c 100644 --- a/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs +++ b/src/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs @@ -13,9 +13,9 @@ namespace Ryujinx.Audio.Backends.Dummy private ulong _playedSampleCount; - public DummyHardwareDeviceSessionOutput(IHardwareDeviceDriver manager, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount) + public DummyHardwareDeviceSessionOutput(IHardwareDeviceDriver manager, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount) { - _volume = requestedVolume; + _volume = 1f; _manager = manager; } diff --git a/src/Ryujinx.Audio/Input/AudioInputManager.cs b/src/Ryujinx.Audio/Input/AudioInputManager.cs index 4d1796c9..d56997e9 100644 --- a/src/Ryujinx.Audio/Input/AudioInputManager.cs +++ b/src/Ryujinx.Audio/Input/AudioInputManager.cs @@ -166,7 +166,6 @@ namespace Ryujinx.Audio.Input /// /// If true, filter disconnected devices /// The list of all audio inputs name -#pragma warning disable CA1822 // Mark member as static public string[] ListAudioIns(bool filtered) { if (filtered) @@ -176,7 +175,6 @@ namespace Ryujinx.Audio.Input return new[] { Constants.DefaultDeviceInputName }; } -#pragma warning restore CA1822 /// /// Open a new . @@ -188,8 +186,6 @@ namespace Ryujinx.Audio.Input /// The input device name wanted by the user /// The sample format to use /// The user configuration - /// The applet resource user id of the application - /// The process handle of the application /// A reporting an error or a success public ResultCode OpenAudioIn(out string outputDeviceName, out AudioOutputConfiguration outputConfiguration, @@ -197,9 +193,7 @@ namespace Ryujinx.Audio.Input IVirtualMemoryManager memoryManager, string inputDeviceName, SampleFormat sampleFormat, - ref AudioInputConfiguration parameter, - ulong appletResourceUserId, - uint processHandle) + ref AudioInputConfiguration parameter) { int sessionId = AcquireSessionId(); diff --git a/src/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs b/src/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs index 576954b9..1369f953 100644 --- a/src/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs +++ b/src/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs @@ -13,9 +13,9 @@ namespace Ryujinx.Audio.Integration private readonly byte[] _buffer; - public HardwareDeviceImpl(IHardwareDeviceDriver deviceDriver, uint channelCount, uint sampleRate, float volume) + public HardwareDeviceImpl(IHardwareDeviceDriver deviceDriver, uint channelCount, uint sampleRate) { - _session = deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, null, SampleFormat.PcmInt16, sampleRate, channelCount, volume); + _session = deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, null, SampleFormat.PcmInt16, sampleRate, channelCount); _channelCount = channelCount; _sampleRate = sampleRate; _currentBufferTag = 0; diff --git a/src/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs b/src/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs index 9c812fb9..95b0e4e5 100644 --- a/src/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs +++ b/src/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs @@ -16,7 +16,9 @@ namespace Ryujinx.Audio.Integration Output, } - IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume = 1f); + float Volume { get; set; } + + IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount); ManualResetEvent GetUpdateRequiredEvent(); ManualResetEvent GetPauseEvent(); diff --git a/src/Ryujinx.Audio/Output/AudioOutputManager.cs b/src/Ryujinx.Audio/Output/AudioOutputManager.cs index 5232357b..308cd156 100644 --- a/src/Ryujinx.Audio/Output/AudioOutputManager.cs +++ b/src/Ryujinx.Audio/Output/AudioOutputManager.cs @@ -165,12 +165,10 @@ namespace Ryujinx.Audio.Output /// Get the list of all audio outputs name. /// /// The list of all audio outputs name -#pragma warning disable CA1822 // Mark member as static public string[] ListAudioOuts() { return new[] { Constants.DefaultDeviceOutputName }; } -#pragma warning restore CA1822 /// /// Open a new . @@ -182,9 +180,6 @@ namespace Ryujinx.Audio.Output /// The input device name wanted by the user /// The sample format to use /// The user configuration - /// The applet resource user id of the application - /// The process handle of the application - /// The volume level to request /// A reporting an error or a success public ResultCode OpenAudioOut(out string outputDeviceName, out AudioOutputConfiguration outputConfiguration, @@ -192,16 +187,13 @@ namespace Ryujinx.Audio.Output IVirtualMemoryManager memoryManager, string inputDeviceName, SampleFormat sampleFormat, - ref AudioInputConfiguration parameter, - ulong appletResourceUserId, - uint processHandle, - float volume) + ref AudioInputConfiguration parameter) { int sessionId = AcquireSessionId(); _sessionsBufferEvents[sessionId].Clear(); - IHardwareDeviceSession deviceSession = _deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, memoryManager, sampleFormat, parameter.SampleRate, parameter.ChannelCount, volume); + IHardwareDeviceSession deviceSession = _deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, memoryManager, sampleFormat, parameter.SampleRate, parameter.ChannelCount); AudioOutputSystem audioOut = new(this, _lock, deviceSession, _sessionsBufferEvents[sessionId]); @@ -234,41 +226,6 @@ namespace Ryujinx.Audio.Output return result; } - /// - /// Sets the volume for all output devices. - /// - /// The volume to set. - public void SetVolume(float volume) - { - if (_sessions != null) - { - foreach (AudioOutputSystem session in _sessions) - { - session?.SetVolume(volume); - } - } - } - - /// - /// Gets the volume for all output devices. - /// - /// A float indicating the volume level. - public float GetVolume() - { - if (_sessions != null) - { - foreach (AudioOutputSystem session in _sessions) - { - if (session != null) - { - return session.GetVolume(); - } - } - } - - return 0.0f; - } - public void Dispose() { GC.SuppressFinalize(this); diff --git a/src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs b/src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs index 9c885b2c..3e11df05 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs @@ -45,7 +45,6 @@ namespace Ryujinx.Audio.Renderer.Dsp _event = new ManualResetEvent(false); } -#pragma warning disable IDE0051 // Remove unused private member private static uint GetHardwareChannelCount(IHardwareDeviceDriver deviceDriver) { // Get the real device driver (In case the compat layer is on top of it). @@ -59,9 +58,8 @@ namespace Ryujinx.Audio.Renderer.Dsp // NOTE: We default to stereo as this will get downmixed to mono by the compat layer if it's not compatible. return 2; } -#pragma warning restore IDE0051 - public void Start(IHardwareDeviceDriver deviceDriver, float volume) + public void Start(IHardwareDeviceDriver deviceDriver) { OutputDevices = new IHardwareDevice[Constants.AudioRendererSessionCountMax]; @@ -70,7 +68,7 @@ namespace Ryujinx.Audio.Renderer.Dsp for (int i = 0; i < OutputDevices.Length; i++) { // TODO: Don't hardcode sample rate. - OutputDevices[i] = new HardwareDeviceImpl(deviceDriver, channelCount, Constants.TargetSampleRate, volume); + OutputDevices[i] = new HardwareDeviceImpl(deviceDriver, channelCount, Constants.TargetSampleRate); } _mailbox = new Mailbox(); @@ -231,33 +229,6 @@ namespace Ryujinx.Audio.Renderer.Dsp _mailbox.SendResponse(MailboxMessage.Stop); } - public float GetVolume() - { - if (OutputDevices != null) - { - foreach (IHardwareDevice outputDevice in OutputDevices) - { - if (outputDevice != null) - { - return outputDevice.GetVolume(); - } - } - } - - return 0f; - } - - public void SetVolume(float volume) - { - if (OutputDevices != null) - { - foreach (IHardwareDevice outputDevice in OutputDevices) - { - outputDevice?.SetVolume(volume); - } - } - } - public void Dispose() { GC.SuppressFinalize(this); @@ -269,6 +240,7 @@ namespace Ryujinx.Audio.Renderer.Dsp if (disposing) { _event.Dispose(); + _mailbox?.Dispose(); } } } diff --git a/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs b/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs index 0dbbd26c..e334a89f 100644 --- a/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs +++ b/src/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs @@ -177,12 +177,12 @@ namespace Ryujinx.Audio.Renderer.Server /// /// Start the and worker thread. /// - private void StartLocked(float volume) + private void StartLocked() { _isRunning = true; // TODO: virtual device mapping (IAudioDevice) - Processor.Start(_deviceDriver, volume); + Processor.Start(_deviceDriver); _workerThread = new Thread(SendCommands) { @@ -254,7 +254,7 @@ namespace Ryujinx.Audio.Renderer.Server /// Register a new . /// /// The to register. - private void Register(AudioRenderSystem renderer, float volume) + private void Register(AudioRenderSystem renderer) { lock (_sessionLock) { @@ -265,7 +265,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (!_isRunning) { - StartLocked(volume); + StartLocked(); } } } @@ -312,8 +312,7 @@ namespace Ryujinx.Audio.Renderer.Server ulong appletResourceUserId, ulong workBufferAddress, ulong workBufferSize, - uint processHandle, - float volume) + uint processHandle) { int sessionId = AcquireSessionId(); @@ -338,7 +337,7 @@ namespace Ryujinx.Audio.Renderer.Server { renderer = audioRenderer; - Register(renderer, volume); + Register(renderer); } else { @@ -350,21 +349,6 @@ namespace Ryujinx.Audio.Renderer.Server return result; } - public float GetVolume() - { - if (Processor != null) - { - return Processor.GetVolume(); - } - - return 0f; - } - - public void SetVolume(float volume) - { - Processor?.SetVolume(volume); - } - public void Dispose() { GC.SuppressFinalize(this); -- cgit v1.2.3