audout: Fix a possible crash with SDL2 when the SDL2 audio backend is dummy (#4605)

This change makes audio device error not fatal.
In case of error, the SDL2 audio backend will behave like the dummy
backend.
This commit is contained in:
Mary 2023-03-27 20:56:36 +02:00 committed by GitHub
parent b5032b3c91
commit 7ca779a26d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -18,6 +18,7 @@ namespace Ryujinx.Audio.Backends.SDL2
private ulong _playedSampleCount; private ulong _playedSampleCount;
private ManualResetEvent _updateRequiredEvent; private ManualResetEvent _updateRequiredEvent;
private uint _outputStream; private uint _outputStream;
private bool _hasSetupError;
private SDL_AudioCallback _callbackDelegate; private SDL_AudioCallback _callbackDelegate;
private int _bytesPerFrame; private int _bytesPerFrame;
private uint _sampleCount; private uint _sampleCount;
@ -42,7 +43,7 @@ namespace Ryujinx.Audio.Backends.SDL2
private void EnsureAudioStreamSetup(AudioBuffer buffer) private void EnsureAudioStreamSetup(AudioBuffer buffer)
{ {
uint bufferSampleCount = (uint)GetSampleCount(buffer); uint bufferSampleCount = (uint)GetSampleCount(buffer);
bool needAudioSetup = _outputStream == 0 || bool needAudioSetup = (_outputStream == 0 && !_hasSetupError) ||
(bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount); (bufferSampleCount >= Constants.TargetSampleCount && bufferSampleCount < _sampleCount);
if (needAudioSetup) if (needAudioSetup)
@ -51,12 +52,9 @@ namespace Ryujinx.Audio.Backends.SDL2
uint newOutputStream = SDL2HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate); uint newOutputStream = SDL2HardwareDeviceDriver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount, _sampleCount, _callbackDelegate);
if (newOutputStream == 0) _hasSetupError = newOutputStream == 0;
{
// No stream in place, this is unexpected. if (!_hasSetupError)
throw new InvalidOperationException($"OpenStream failed with error: \"{SDL_GetError()}\"");
}
else
{ {
if (_outputStream != 0) if (_outputStream != 0)
{ {
@ -151,11 +149,20 @@ namespace Ryujinx.Audio.Backends.SDL2
{ {
EnsureAudioStreamSetup(buffer); EnsureAudioStreamSetup(buffer);
SDL2AudioBuffer driverBuffer = new SDL2AudioBuffer(buffer.DataPointer, GetSampleCount(buffer)); if (_outputStream != 0)
{
SDL2AudioBuffer driverBuffer = new SDL2AudioBuffer(buffer.DataPointer, GetSampleCount(buffer));
_ringBuffer.Write(buffer.Data, 0, buffer.Data.Length); _ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
_queuedBuffers.Enqueue(driverBuffer); _queuedBuffers.Enqueue(driverBuffer);
}
else
{
Interlocked.Add(ref _playedSampleCount, GetSampleCount(buffer));
_updateRequiredEvent.Set();
}
} }
public override void SetVolume(float volume) public override void SetVolume(float volume)