Replace OpenAL dlls with openal-soft provided ones (downloaded from their official site: https://www.openal-soft.org/)

Fix hanging issue with OpenAL on device disconnection
Cleanup other hanging/crash fixes in other audio backends
This commit is contained in:
CasualPokePlayer 2023-12-18 02:32:37 -08:00
parent ad3aa2f5dc
commit f4ac17c904
6 changed files with 60 additions and 34 deletions

Binary file not shown.

BIN
Assets/dll/soft_oal.dll Normal file

Binary file not shown.

View File

@ -11,6 +11,7 @@
<PackageReference Include="Silk.NET.OpenAL" Version="2.18.0" />
<PackageReference Include="Silk.NET.OpenAL.Extensions.Creative" Version="2.18.0" />
<PackageReference Include="Silk.NET.OpenAL.Extensions.Enumeration" Version="2.18.0" />
<PackageReference Include="Silk.NET.OpenAL.Extensions.EXT" Version="2.18.0" />
<PackageReference Include="Vortice.MediaFoundation" Version="2.4.2" />
<PackageReference Include="Vortice.XAudio2" Version="2.4.2" />
<PackageReference Include="SharpDX.DirectSound" Version="4.2.0" />

View File

@ -46,16 +46,6 @@ namespace BizHawk.Bizware.Audio
_disposed = true;
}
private void ResetToDefaultDevice()
{
_deviceBuffer?.Dispose();
_deviceBuffer = null;
_device.Dispose();
_device = new();
_device.SetCooperativeLevel(_mainWindowHandle, CooperativeLevel.Priority);
}
public static IEnumerable<string> GetDeviceNames()
{
return DirectSound.GetDevices().Select(d => d.Description);
@ -67,6 +57,18 @@ namespace BizHawk.Bizware.Audio
public int MaxSamplesDeficit { get; private set; }
private void ResetToDefaultDevice()
{
_deviceBuffer.Dispose();
_deviceBuffer = null;
_device.Dispose();
_device = new();
_device.SetCooperativeLevel(_mainWindowHandle, CooperativeLevel.Priority);
StartPlaying();
}
private bool IsPlaying
{
get
@ -86,7 +88,6 @@ namespace BizHawk.Bizware.Audio
{
// this only seems to ever occur if the device is disconnected...
ResetToDefaultDevice();
StartPlaying();
return false;
}
}

View File

@ -8,6 +8,7 @@ using Silk.NET.Core.Native;
using Silk.NET.OpenAL;
using Silk.NET.OpenAL.Extensions.Creative;
using Silk.NET.OpenAL.Extensions.Enumeration;
using Silk.NET.OpenAL.Extensions.EXT;
namespace BizHawk.Bizware.Audio
{
@ -29,6 +30,8 @@ namespace BizHawk.Bizware.Audio
private BufferPool _bufferPool;
private int _currentSamplesQueued;
private short[] _tempSampleBuffer;
private unsafe Device* _device;
private Disconnect _disconnectExt;
public OpenALSoundOutput(IHostAudioManager sound, string chosenDeviceName)
{
@ -37,6 +40,12 @@ namespace BizHawk.Bizware.Audio
GetDeviceNames().Contains(chosenDeviceName) ? chosenDeviceName : null,
_sound.SampleRate
);
unsafe
{
_device = _alc.GetContextsDevice(_alc.GetCurrentContext());
_disconnectExt = _alc.TryGetExtension<Disconnect>(_device, out var ext) ? ext : null;
}
}
public void Dispose()
@ -85,8 +94,28 @@ namespace BizHawk.Bizware.Audio
BufferSizeSamples = 0;
}
private unsafe void ResetToDefaultDeviceIfDisconnected()
{
var connected = 1;
_disconnectExt?.GetContextProperty(_device, DisconnectContextInteger.Connected, 1, &connected);
if (connected != 0)
{
return;
}
StopSound();
_context.Dispose();
_context = new(device: null, _sound.SampleRate);
_device = _alc.GetContextsDevice(_alc.GetCurrentContext());
_disconnectExt = _alc.TryGetExtension<Disconnect>(_device, out var ext) ? ext : null;
StartSound();
}
public int CalculateSamplesNeeded()
{
ResetToDefaultDeviceIfDisconnected();
var currentSamplesPlayed = GetSource(GetSourceInteger.SampleOffset);
var sourceState = GetSourceState();
var isInitializing = sourceState == SourceState.Initial;

View File

@ -41,26 +41,6 @@ namespace BizHawk.Bizware.Audio
return $"{MMDEVAPI_TOKEN}{device.Id}{DEVINTERFACE_AUDIO_RENDER}";
}
private void ResetToDefaultDevice()
{
var wasPlaying = _sourceVoice != null;
_sourceVoice?.Dispose();
_bufferPool?.Dispose();
_masteringVoice.Dispose();
_device.Dispose();
_device = XAudio2.XAudio2Create();
_device.CriticalError += (_, _) => _deviceResetRequired = true;
_masteringVoice = _device.CreateMasteringVoice(
inputChannels: _sound.ChannelCount,
inputSampleRate: _sound.SampleRate);
if (wasPlaying)
{
StartSound();
}
}
public XAudio2SoundOutput(IHostAudioManager sound, string chosenDeviceName)
{
_sound = sound;
@ -126,14 +106,29 @@ namespace BizHawk.Bizware.Audio
BufferSizeSamples = 0;
}
public int CalculateSamplesNeeded()
private void ResetToDefaultDeviceIfNeeded()
{
if (_deviceResetRequired)
{
_deviceResetRequired = false;
ResetToDefaultDevice();
}
StopSound();
_masteringVoice.Dispose();
_device.Dispose();
_device = XAudio2.XAudio2Create();
_device.CriticalError += (_, _) => _deviceResetRequired = true;
_masteringVoice = _device.CreateMasteringVoice(
inputChannels: _sound.ChannelCount,
inputSampleRate: _sound.SampleRate);
StartSound();
}
}
public int CalculateSamplesNeeded()
{
ResetToDefaultDeviceIfNeeded();
var isInitializing = _runningSamplesQueued == 0;
var voiceState = _sourceVoice.State;
var detectedUnderrun = !isInitializing && voiceState.BuffersQueued == 0;