aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio
diff options
context:
space:
mode:
authorsharmander <saldabain.dev@gmail.com>2021-12-23 11:33:56 -0500
committerGitHub <noreply@github.com>2021-12-23 13:33:56 -0300
commitcb43cc7e322014ce2bd0ee73b06d403be62fa8d5 (patch)
tree98dbdc73e947b94d04c5e12bf7dba80f93407e2c /Ryujinx.Audio
parente7c2dc8ec3329d50a52c36efeb31019850ce6015 (diff)
UI - Add Volume Controls + Mute Toggle (F2) (#2871)
* Add the ability to toggle mute in the status bar. * Add the ability to toggle mute in the status bar. * Formatting fixes * Add hotkey (F2) to mute * Add default hotkey to config.json * Add ability to change volume via slider. * Fix Headless * Fix SDL2 Problem : Credits to d3xMachina * Remove unnecessary work * Address gdk comments * Toggling with Hotkey now properly restores volume to original level. * Toggling with Hotkey now properly restores volume to original level. * Update UI to show Volume % instead of Muted/Unmuted * Clean up the volume ui a bit. * Undo unintentionally committed code. * Implement AudRen Support * Restore intiial volume level in function definition. * Finalize UI * Finalize UI * Use clamp for bounds check * Use Math.Clamp for volume in soundio * Address comments by gdkchan * Address remaining comments * Fix missing semicolon * Address remaining gdkchan comment * Fix comment * Change /* to // * Allow volume slider to change volume immediately. Also force label text to cast to int to prevent decimals from showing in status bar * Remove blank line * Undo setting of volume level when "Cancel" is pressed. * Fix allignment for settings window code
Diffstat (limited to 'Ryujinx.Audio')
-rw-r--r--Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs6
-rw-r--r--Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs4
-rw-r--r--Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs4
-rw-r--r--Ryujinx.Audio/Common/AudioDeviceSession.cs2
-rw-r--r--Ryujinx.Audio/Integration/HardwareDeviceImpl.cs14
-rw-r--r--Ryujinx.Audio/Integration/IHardwareDevice.cs12
-rw-r--r--Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs2
-rw-r--r--Ryujinx.Audio/Output/AudioOutputManager.cs40
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs31
-rw-r--r--Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs27
-rw-r--r--Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs11
-rw-r--r--Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs11
12 files changed, 144 insertions, 20 deletions
diff --git a/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs b/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs
index 0ae6a620..d9e170c3 100644
--- a/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs
+++ b/Ryujinx.Audio/Backends/CompatLayer/CompatLayerHardwareDeviceDriver.cs
@@ -68,7 +68,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
};
}
- public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
+ public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume)
{
if (channelCount == 0)
{
@@ -80,6 +80,8 @@ namespace Ryujinx.Audio.Backends.CompatLayer
sampleRate = Constants.TargetSampleRate;
}
+ volume = Math.Clamp(volume, 0, 1);
+
if (!_realDriver.SupportsDirection(direction))
{
if (direction == Direction.Input)
@@ -94,7 +96,7 @@ namespace Ryujinx.Audio.Backends.CompatLayer
uint hardwareChannelCount = SelectHardwareChannelCount(channelCount);
- IHardwareDeviceSession realSession = _realDriver.OpenDeviceSession(direction, memoryManager, sampleFormat, sampleRate, hardwareChannelCount);
+ IHardwareDeviceSession realSession = _realDriver.OpenDeviceSession(direction, memoryManager, sampleFormat, sampleRate, hardwareChannelCount, volume);
if (hardwareChannelCount == channelCount)
{
diff --git a/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs b/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs
index d729d3f6..f9783ee5 100644
--- a/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs
+++ b/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceDriver.cs
@@ -35,7 +35,7 @@ namespace Ryujinx.Audio.Backends.Dummy
_pauseEvent = new ManualResetEvent(true);
}
- public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
+ public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume)
{
if (sampleRate == 0)
{
@@ -49,7 +49,7 @@ namespace Ryujinx.Audio.Backends.Dummy
if (direction == Direction.Output)
{
- return new DummyHardwareDeviceSessionOutput(this, memoryManager, sampleFormat, sampleRate, channelCount);
+ return new DummyHardwareDeviceSessionOutput(this, memoryManager, sampleFormat, sampleRate, channelCount, volume);
}
else
{
diff --git a/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs b/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs
index 7cc19997..1e6a198a 100644
--- a/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs
+++ b/Ryujinx.Audio/Backends/Dummy/DummyHardwareDeviceSessionOutput.cs
@@ -30,9 +30,9 @@ namespace Ryujinx.Audio.Backends.Dummy
private ulong _playedSampleCount;
- public DummyHardwareDeviceSessionOutput(IHardwareDeviceDriver manager, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
+ public DummyHardwareDeviceSessionOutput(IHardwareDeviceDriver manager, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
{
- _volume = 1.0f;
+ _volume = requestedVolume;
_manager = manager;
}
diff --git a/Ryujinx.Audio/Common/AudioDeviceSession.cs b/Ryujinx.Audio/Common/AudioDeviceSession.cs
index fbdb5a75..511f3905 100644
--- a/Ryujinx.Audio/Common/AudioDeviceSession.cs
+++ b/Ryujinx.Audio/Common/AudioDeviceSession.cs
@@ -106,7 +106,7 @@ namespace Ryujinx.Audio.Common
_bufferAppendedCount = 0;
_bufferRegisteredCount = 0;
_bufferReleasedCount = 0;
- _volume = 1.0f;
+ _volume = deviceSession.GetVolume();
_state = AudioDeviceState.Stopped;
}
diff --git a/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs b/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs
index d489b008..d51aa3fb 100644
--- a/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs
+++ b/Ryujinx.Audio/Integration/HardwareDeviceImpl.cs
@@ -30,9 +30,9 @@ namespace Ryujinx.Audio.Integration
private byte[] _buffer;
- public HardwareDeviceImpl(IHardwareDeviceDriver deviceDriver, uint channelCount, uint sampleRate)
+ public HardwareDeviceImpl(IHardwareDeviceDriver deviceDriver, uint channelCount, uint sampleRate, float volume)
{
- _session = deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, null, SampleFormat.PcmInt16, sampleRate, channelCount);
+ _session = deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, null, SampleFormat.PcmInt16, sampleRate, channelCount, volume);
_channelCount = channelCount;
_sampleRate = sampleRate;
_currentBufferTag = 0;
@@ -56,6 +56,16 @@ namespace Ryujinx.Audio.Integration
_currentBufferTag = _currentBufferTag % 4;
}
+ public void SetVolume(float volume)
+ {
+ _session.SetVolume(volume);
+ }
+
+ public float GetVolume()
+ {
+ return _session.GetVolume();
+ }
+
public uint GetChannelCount()
{
return _channelCount;
diff --git a/Ryujinx.Audio/Integration/IHardwareDevice.cs b/Ryujinx.Audio/Integration/IHardwareDevice.cs
index 0f67b2c8..1eeb5ca4 100644
--- a/Ryujinx.Audio/Integration/IHardwareDevice.cs
+++ b/Ryujinx.Audio/Integration/IHardwareDevice.cs
@@ -26,6 +26,18 @@ namespace Ryujinx.Audio.Integration
public interface IHardwareDevice : IDisposable
{
/// <summary>
+ /// Sets the volume level for this device.
+ /// </summary>
+ /// <param name="volume">The volume level to set.</param>
+ void SetVolume(float volume);
+
+ /// <summary>
+ /// Gets the volume level for this device.
+ /// </summary>
+ /// <returns>The volume level of this device.</returns>
+ float GetVolume();
+
+ /// <summary>
/// Get the supported sample rate of this device.
/// </summary>
/// <returns>The supported sample rate of this device.</returns>
diff --git a/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs b/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs
index 1a53fa9b..c1869ce1 100644
--- a/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs
+++ b/Ryujinx.Audio/Integration/IHardwareDeviceDriver.cs
@@ -33,7 +33,7 @@ namespace Ryujinx.Audio.Integration
Output
}
- IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount);
+ IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume = 1f);
ManualResetEvent GetUpdateRequiredEvent();
ManualResetEvent GetPauseEvent();
diff --git a/Ryujinx.Audio/Output/AudioOutputManager.cs b/Ryujinx.Audio/Output/AudioOutputManager.cs
index 852632fa..dd115295 100644
--- a/Ryujinx.Audio/Output/AudioOutputManager.cs
+++ b/Ryujinx.Audio/Output/AudioOutputManager.cs
@@ -208,13 +208,14 @@ namespace Ryujinx.Audio.Output
SampleFormat sampleFormat,
ref AudioInputConfiguration parameter,
ulong appletResourceUserId,
- uint processHandle)
+ uint processHandle,
+ float volume)
{
int sessionId = AcquireSessionId();
_sessionsBufferEvents[sessionId].Clear();
- IHardwareDeviceSession deviceSession = _deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, memoryManager, sampleFormat, parameter.SampleRate, parameter.ChannelCount);
+ IHardwareDeviceSession deviceSession = _deviceDriver.OpenDeviceSession(IHardwareDeviceDriver.Direction.Output, memoryManager, sampleFormat, parameter.SampleRate, parameter.ChannelCount, volume);
AudioOutputSystem audioOut = new AudioOutputSystem(this, _lock, deviceSession, _sessionsBufferEvents[sessionId]);
@@ -247,6 +248,41 @@ namespace Ryujinx.Audio.Output
return result;
}
+ /// <summary>
+ /// Sets the volume for all output devices.
+ /// </summary>
+ /// <param name="volume">The volume to set.</param>
+ public void SetVolume(float volume)
+ {
+ if (_sessions != null)
+ {
+ foreach (AudioOutputSystem session in _sessions)
+ {
+ session?.SetVolume(volume);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the volume for all output devices.
+ /// </summary>
+ /// <returns>A float indicating the volume level.</returns>
+ public float GetVolume()
+ {
+ if (_sessions != null)
+ {
+ foreach (AudioOutputSystem session in _sessions)
+ {
+ if (session != null)
+ {
+ return session.GetVolume();
+ }
+ }
+ }
+
+ return 0.0f;
+ }
+
public void Dispose()
{
if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0)
diff --git a/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs b/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs
index e15165b9..303de9bb 100644
--- a/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/AudioProcessor.cs
@@ -78,7 +78,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
}
}
- public void Start(IHardwareDeviceDriver deviceDriver)
+ public void Start(IHardwareDeviceDriver deviceDriver, float volume)
{
OutputDevices = new IHardwareDevice[Constants.AudioRendererSessionCountMax];
@@ -89,7 +89,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);
+ OutputDevices[i] = new HardwareDeviceImpl(deviceDriver, channelCount, Constants.TargetSampleRate, volume);
}
_mailbox = new Mailbox<MailboxMessage>();
@@ -245,6 +245,33 @@ 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()
{
Dispose(true);
diff --git a/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs b/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs
index 7518c447..d20c3c03 100644
--- a/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs
+++ b/Ryujinx.Audio/Renderer/Server/AudioRendererManager.cs
@@ -186,12 +186,12 @@ namespace Ryujinx.Audio.Renderer.Server
/// <summary>
/// Start the <see cref="AudioProcessor"/> and worker thread.
/// </summary>
- private void StartLocked()
+ private void StartLocked(float volume)
{
_isRunning = true;
// TODO: virtual device mapping (IAudioDevice)
- Processor.Start(_deviceDriver);
+ Processor.Start(_deviceDriver, volume);
_workerThread = new Thread(SendCommands)
{
@@ -263,7 +263,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// Register a new <see cref="AudioRenderSystem"/>.
/// </summary>
/// <param name="renderer">The <see cref="AudioRenderSystem"/> to register.</param>
- private void Register(AudioRenderSystem renderer)
+ private void Register(AudioRenderSystem renderer, float volume)
{
lock (_sessionLock)
{
@@ -274,7 +274,7 @@ namespace Ryujinx.Audio.Renderer.Server
{
if (!_isRunning)
{
- StartLocked();
+ StartLocked(volume);
}
}
}
@@ -314,7 +314,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// <param name="workBufferSize">The guest work buffer size.</param>
/// <param name="processHandle">The process handle of the application.</param>
/// <returns>A <see cref="ResultCode"/> reporting an error or a success.</returns>
- public ResultCode OpenAudioRenderer(out AudioRenderSystem renderer, IVirtualMemoryManager memoryManager, ref AudioRendererConfiguration parameter, ulong appletResourceUserId, ulong workBufferAddress, ulong workBufferSize, uint processHandle)
+ public ResultCode OpenAudioRenderer(out AudioRenderSystem renderer, IVirtualMemoryManager memoryManager, ref AudioRendererConfiguration parameter, ulong appletResourceUserId, ulong workBufferAddress, ulong workBufferSize, uint processHandle, float volume)
{
int sessionId = AcquireSessionId();
@@ -326,7 +326,7 @@ namespace Ryujinx.Audio.Renderer.Server
{
renderer = audioRenderer;
- Register(renderer);
+ Register(renderer, volume);
}
else
{
@@ -338,6 +338,21 @@ 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()
{
if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0)
diff --git a/Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs b/Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs
index 2008bafc..8d717f6a 100644
--- a/Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs
+++ b/Ryujinx.Audio/Renderer/Utils/FileHardwareDevice.cs
@@ -76,6 +76,17 @@ namespace Ryujinx.Audio.Renderer.Utils
_stream.Flush();
}
+ public void SetVolume(float volume)
+ {
+ // Do nothing, volume is not used for FileHardwareDevice at the moment.
+ }
+
+ public float GetVolume()
+ {
+ // FileHardwareDevice does not incorporate volume.
+ return 0;
+ }
+
public uint GetChannelCount()
{
return _channelCount;
diff --git a/Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs b/Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs
index c5411ac0..e6be07c0 100644
--- a/Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs
+++ b/Ryujinx.Audio/Renderer/Utils/SplitterHardwareDevice.cs
@@ -37,6 +37,17 @@ namespace Ryujinx.Audio.Renderer.Utils
_secondaryDevice?.AppendBuffer(data, channelCount);
}
+ public void SetVolume(float volume)
+ {
+ _baseDevice.SetVolume(volume);
+ _secondaryDevice.SetVolume(volume);
+ }
+
+ public float GetVolume()
+ {
+ return _baseDevice.GetVolume();
+ }
+
public uint GetChannelCount()
{
return _baseDevice.GetChannelCount();