diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2024-02-22 16:58:33 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-22 16:58:33 -0300 |
| commit | d4d0a48bfe89d6e8e12ce16829bb2c440b56007c (patch) | |
| tree | 2376566ed2c06181b3dbc547b1f99f5b533d918b /src/Ryujinx.Horizon/Audio | |
| parent | 57d8afd0c99bb43d1ba1e3cc630d257c5da92741 (diff) | |
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
Diffstat (limited to 'src/Ryujinx.Horizon/Audio')
| -rw-r--r-- | src/Ryujinx.Horizon/Audio/AudioMain.cs | 17 | ||||
| -rw-r--r-- | src/Ryujinx.Horizon/Audio/AudioManagers.cs | 78 | ||||
| -rw-r--r-- | src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs | 55 | ||||
| -rw-r--r-- | src/Ryujinx.Horizon/Audio/HwopusIpcServer.cs | 46 | ||||
| -rw-r--r-- | src/Ryujinx.Horizon/Audio/HwopusMain.cs | 17 |
5 files changed, 213 insertions, 0 deletions
diff --git a/src/Ryujinx.Horizon/Audio/AudioMain.cs b/src/Ryujinx.Horizon/Audio/AudioMain.cs new file mode 100644 index 00000000..92c9e804 --- /dev/null +++ b/src/Ryujinx.Horizon/Audio/AudioMain.cs @@ -0,0 +1,17 @@ +namespace Ryujinx.Horizon.Audio +{ + class AudioMain : IService + { + public static void Main(ServiceTable serviceTable) + { + AudioUserIpcServer ipcServer = new(); + + ipcServer.Initialize(); + + serviceTable.SignalServiceReady(); + + ipcServer.ServiceRequests(); + ipcServer.Shutdown(); + } + } +} diff --git a/src/Ryujinx.Horizon/Audio/AudioManagers.cs b/src/Ryujinx.Horizon/Audio/AudioManagers.cs new file mode 100644 index 00000000..493a6f9b --- /dev/null +++ b/src/Ryujinx.Horizon/Audio/AudioManagers.cs @@ -0,0 +1,78 @@ +using Ryujinx.Audio; +using Ryujinx.Audio.Input; +using Ryujinx.Audio.Integration; +using Ryujinx.Audio.Output; +using Ryujinx.Audio.Renderer.Device; +using Ryujinx.Audio.Renderer.Server; +using Ryujinx.Cpu; +using Ryujinx.Horizon.Sdk.Audio; +using System; + +namespace Ryujinx.Horizon.Audio +{ + class AudioManagers : IDisposable + { + public AudioManager AudioManager { get; } + public AudioOutputManager AudioOutputManager { get; } + public AudioInputManager AudioInputManager { get; } + public AudioRendererManager AudioRendererManager { get; } + public VirtualDeviceSessionRegistry AudioDeviceSessionRegistry { get; } + + public AudioManagers(IHardwareDeviceDriver audioDeviceDriver, ITickSource tickSource) + { + AudioManager = new AudioManager(); + AudioOutputManager = new AudioOutputManager(); + AudioInputManager = new AudioInputManager(); + AudioRendererManager = new AudioRendererManager(tickSource); + AudioDeviceSessionRegistry = new VirtualDeviceSessionRegistry(audioDeviceDriver); + + IWritableEvent[] audioOutputRegisterBufferEvents = new IWritableEvent[Constants.AudioOutSessionCountMax]; + + for (int i = 0; i < audioOutputRegisterBufferEvents.Length; i++) + { + audioOutputRegisterBufferEvents[i] = new AudioEvent(); + } + + AudioOutputManager.Initialize(audioDeviceDriver, audioOutputRegisterBufferEvents); + + IWritableEvent[] audioInputRegisterBufferEvents = new IWritableEvent[Constants.AudioInSessionCountMax]; + + for (int i = 0; i < audioInputRegisterBufferEvents.Length; i++) + { + audioInputRegisterBufferEvents[i] = new AudioEvent(); + } + + AudioInputManager.Initialize(audioDeviceDriver, audioInputRegisterBufferEvents); + + IWritableEvent[] systemEvents = new IWritableEvent[Constants.AudioRendererSessionCountMax]; + + for (int i = 0; i < systemEvents.Length; i++) + { + systemEvents[i] = new AudioEvent(); + } + + AudioManager.Initialize(audioDeviceDriver.GetUpdateRequiredEvent(), AudioOutputManager.Update, AudioInputManager.Update); + + AudioRendererManager.Initialize(systemEvents, audioDeviceDriver); + + AudioManager.Start(); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + AudioManager.Dispose(); + AudioOutputManager.Dispose(); + AudioInputManager.Dispose(); + AudioRendererManager.Dispose(); + } + } + + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs b/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs new file mode 100644 index 00000000..20c824e1 --- /dev/null +++ b/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs @@ -0,0 +1,55 @@ +using Ryujinx.Horizon.Sdk.Audio.Detail; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sm; + +namespace Ryujinx.Horizon.Audio +{ + class AudioUserIpcServer + { + private const int MaxSessionsCount = 30; + + private const int PointerBufferSize = 0xB40; + private const int MaxDomains = 0; + private const int MaxDomainObjects = 0; + private const int MaxPortsCount = 1; + + private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); + + private SmApi _sm; + private ServerManager _serverManager; + private AudioManagers _managers; + + public void Initialize() + { + HeapAllocator allocator = new(); + + _sm = new SmApi(); + _sm.Initialize().AbortOnFailure(); + + _serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, MaxSessionsCount); + _managers = new AudioManagers(HorizonStatic.Options.AudioDeviceDriver, HorizonStatic.Options.TickSource); + + AudioRendererManager audioRendererManager = new(_managers.AudioRendererManager, _managers.AudioDeviceSessionRegistry); + AudioOutManager audioOutManager = new(_managers.AudioOutputManager); + AudioInManager audioInManager = new(_managers.AudioInputManager); + FinalOutputRecorderManager finalOutputRecorderManager = new(); + + _serverManager.RegisterObjectForServer(audioRendererManager, ServiceName.Encode("audren:u"), MaxSessionsCount); + _serverManager.RegisterObjectForServer(audioOutManager, ServiceName.Encode("audout:u"), MaxSessionsCount); + _serverManager.RegisterObjectForServer(audioInManager, ServiceName.Encode("audin:u"), MaxSessionsCount); + _serverManager.RegisterObjectForServer(finalOutputRecorderManager, ServiceName.Encode("audrec:u"), MaxSessionsCount); + } + + public void ServiceRequests() + { + _serverManager.ServiceRequests(); + } + + public void Shutdown() + { + _serverManager.Dispose(); + _managers.Dispose(); + _sm.Dispose(); + } + } +} diff --git a/src/Ryujinx.Horizon/Audio/HwopusIpcServer.cs b/src/Ryujinx.Horizon/Audio/HwopusIpcServer.cs new file mode 100644 index 00000000..e60e033c --- /dev/null +++ b/src/Ryujinx.Horizon/Audio/HwopusIpcServer.cs @@ -0,0 +1,46 @@ +using Ryujinx.Horizon.Sdk.Codec.Detail; +using Ryujinx.Horizon.Sdk.Sf.Hipc; +using Ryujinx.Horizon.Sdk.Sm; + +namespace Ryujinx.Horizon.Audio +{ + class HwopusIpcServer + { + private const int MaxSessionsCount = 24; + + private const int PointerBufferSize = 0x1000; + private const int MaxDomains = 8; + private const int MaxDomainObjects = 256; + private const int MaxPortsCount = 1; + + private static readonly ManagerOptions _options = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); + + private SmApi _sm; + private ServerManager _serverManager; + + public void Initialize() + { + HeapAllocator allocator = new(); + + _sm = new SmApi(); + _sm.Initialize().AbortOnFailure(); + + _serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _options, MaxSessionsCount); + + HardwareOpusDecoderManager hardwareOpusDecoderManager = new(); + + _serverManager.RegisterObjectForServer(hardwareOpusDecoderManager, ServiceName.Encode("hwopus"), MaxSessionsCount); + } + + public void ServiceRequests() + { + _serverManager.ServiceRequests(); + } + + public void Shutdown() + { + _serverManager.Dispose(); + _sm.Dispose(); + } + } +} diff --git a/src/Ryujinx.Horizon/Audio/HwopusMain.cs b/src/Ryujinx.Horizon/Audio/HwopusMain.cs new file mode 100644 index 00000000..04eee3fa --- /dev/null +++ b/src/Ryujinx.Horizon/Audio/HwopusMain.cs @@ -0,0 +1,17 @@ +namespace Ryujinx.Horizon.Audio +{ + class HwopusMain : IService + { + public static void Main(ServiceTable serviceTable) + { + HwopusIpcServer ipcServer = new(); + + ipcServer.Initialize(); + + serviceTable.SignalServiceReady(); + + ipcServer.ServiceRequests(); + ipcServer.Shutdown(); + } + } +} |
