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:
parent
ad3aa2f5dc
commit
f4ac17c904
Binary file not shown.
Binary file not shown.
|
@ -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" />
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue