forked from Ryubing/Ryujinx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 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
- Loading branch information
Mary
authored
Feb 26, 2021
1 parent
1c49089
commit f556c80
Showing
249 changed files
with
5,602 additions
and
2,700 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace Ryujinx.Audio.Backends.OpenAL | ||
{ | ||
class OpenALAudioBuffer | ||
{ | ||
public int BufferId; | ||
public ulong DriverIdentifier; | ||
public ulong SampleCount; | ||
} | ||
} |
170 changes: 170 additions & 0 deletions
170
Ryujinx.Audio.Backends.OpenAL/OpenALHardwareDeviceDriver.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
using OpenTK.Audio; | ||
using Ryujinx.Audio.Common; | ||
using Ryujinx.Audio.Integration; | ||
using Ryujinx.Memory; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Threading; | ||
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver; | ||
|
||
namespace Ryujinx.Audio.Backends.OpenAL | ||
{ | ||
public class OpenALHardwareDeviceDriver : IHardwareDeviceDriver | ||
{ | ||
private object _lock = new object(); | ||
|
||
private AudioContext _context; | ||
private ManualResetEvent _updateRequiredEvent; | ||
private List<OpenALHardwareDeviceSession> _sessions; | ||
private bool _stillRunning; | ||
private Thread _updaterThread; | ||
|
||
public OpenALHardwareDeviceDriver() | ||
{ | ||
_context = new AudioContext(); | ||
_updateRequiredEvent = new ManualResetEvent(false); | ||
_sessions = new List<OpenALHardwareDeviceSession>(); | ||
|
||
_stillRunning = true; | ||
_updaterThread = new Thread(Update) | ||
{ | ||
Name = "HardwareDeviceDriver.OpenAL" | ||
}; | ||
|
||
_updaterThread.Start(); | ||
} | ||
|
||
public static bool IsSupported | ||
{ | ||
get | ||
{ | ||
try | ||
{ | ||
return AudioContext.AvailableDevices.Count > 0; | ||
} | ||
catch | ||
{ | ||
return false; | ||
} | ||
} | ||
} | ||
|
||
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount) | ||
{ | ||
if (channelCount == 0) | ||
{ | ||
channelCount = 2; | ||
} | ||
|
||
if (sampleRate == 0) | ||
{ | ||
sampleRate = Constants.TargetSampleRate; | ||
} | ||
|
||
if (direction != Direction.Output) | ||
{ | ||
throw new ArgumentException($"{direction}"); | ||
} | ||
else if (!SupportsChannelCount(channelCount)) | ||
{ | ||
throw new ArgumentException($"{channelCount}"); | ||
} | ||
|
||
lock (_lock) | ||
{ | ||
OpenALHardwareDeviceSession session = new OpenALHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount); | ||
|
||
_sessions.Add(session); | ||
|
||
return session; | ||
} | ||
} | ||
|
||
internal void Unregister(OpenALHardwareDeviceSession session) | ||
{ | ||
lock (_lock) | ||
{ | ||
_sessions.Remove(session); | ||
} | ||
} | ||
|
||
public ManualResetEvent GetUpdateRequiredEvent() | ||
{ | ||
return _updateRequiredEvent; | ||
} | ||
|
||
private void Update() | ||
{ | ||
while (_stillRunning) | ||
{ | ||
bool updateRequired = false; | ||
|
||
lock (_lock) | ||
{ | ||
foreach (OpenALHardwareDeviceSession session in _sessions) | ||
{ | ||
if (session.Update()) | ||
{ | ||
updateRequired = true; | ||
} | ||
} | ||
} | ||
|
||
if (updateRequired) | ||
{ | ||
_updateRequiredEvent.Set(); | ||
} | ||
|
||
// If it's not slept it will waste cycles. | ||
Thread.Sleep(10); | ||
} | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
Dispose(true); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (disposing) | ||
{ | ||
lock (_lock) | ||
{ | ||
_stillRunning = false; | ||
_updaterThread.Join(); | ||
|
||
// Loop against all sessions to dispose them (they will unregister themself) | ||
while (_sessions.Count > 0) | ||
{ | ||
OpenALHardwareDeviceSession session = _sessions[0]; | ||
|
||
session.Dispose(); | ||
} | ||
} | ||
|
||
_context.Dispose(); | ||
} | ||
} | ||
|
||
public bool SupportsSampleRate(uint sampleRate) | ||
{ | ||
return true; | ||
} | ||
|
||
public bool SupportsSampleFormat(SampleFormat sampleFormat) | ||
{ | ||
return true; | ||
} | ||
|
||
public bool SupportsChannelCount(uint channelCount) | ||
{ | ||
return channelCount == 1 || channelCount == 2 || channelCount == 6; | ||
} | ||
|
||
public bool SupportsDirection(Direction direction) | ||
{ | ||
return direction == Direction.Output; | ||
} | ||
} | ||
} |
Oops, something went wrong.