From d112083c44e0d150b16382540632f906ed6154f9 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 20 Sep 2015 14:36:45 +0100 Subject: [PATCH] Clean up sound devices on game exit. --- OpenRA.Game/Game.cs | 1 + OpenRA.Game/Sound/Sound.cs | 7 +++++- OpenRA.Game/Sound/SoundDevice.cs | 2 +- OpenRA.Platforms.Default/OpenAlSoundEngine.cs | 22 ++++++++++++++----- OpenRA.Platforms.Null/NullSound.cs | 4 +++- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 2e1eb7b794..2e496b6873 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -672,6 +672,7 @@ namespace OpenRA worldRenderer.Dispose(); ModData.Dispose(); ChromeProvider.Deinitialize(); + Sound.Dispose(); Renderer.Dispose(); OnQuit(); diff --git a/OpenRA.Game/Sound/Sound.cs b/OpenRA.Game/Sound/Sound.cs index 6543fa7b13..2127cc1046 100644 --- a/OpenRA.Game/Sound/Sound.cs +++ b/OpenRA.Game/Sound/Sound.cs @@ -20,7 +20,7 @@ using OpenRA.Traits; namespace OpenRA { - public class Sound + public sealed class Sound : IDisposable { readonly ISoundEngine soundEngine; Cache sounds; @@ -368,5 +368,10 @@ namespace OpenRA return PlayPredefined(rules, player, null, type.ToLowerInvariant(), notification, variant, true, WPos.Zero, 1f, false); } + + public void Dispose() + { + soundEngine.Dispose(); + } } } diff --git a/OpenRA.Game/Sound/SoundDevice.cs b/OpenRA.Game/Sound/SoundDevice.cs index 23bbf3dcdb..15cec3b2bf 100644 --- a/OpenRA.Game/Sound/SoundDevice.cs +++ b/OpenRA.Game/Sound/SoundDevice.cs @@ -12,7 +12,7 @@ using System; namespace OpenRA { - public interface ISoundEngine + public interface ISoundEngine : IDisposable { SoundDevice[] AvailableDevices(); ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate); diff --git a/OpenRA.Platforms.Default/OpenAlSoundEngine.cs b/OpenRA.Platforms.Default/OpenAlSoundEngine.cs index fc8fed488d..5880f74426 100644 --- a/OpenRA.Platforms.Default/OpenAlSoundEngine.cs +++ b/OpenRA.Platforms.Default/OpenAlSoundEngine.cs @@ -21,7 +21,7 @@ using OpenTK.Audio.OpenAL; namespace OpenRA.Platforms.Default { - class OpenAlSoundEngine : ISoundEngine + sealed class OpenAlSoundEngine : ISoundEngine { public SoundDevice[] AvailableDevices() { @@ -49,6 +49,7 @@ namespace OpenRA.Platforms.Default const int GroupDistanceSqr = GroupDistance * GroupDistance; const int PoolSize = 32; + IntPtr device; float volume = 1f; Dictionary sourcePool = new Dictionary(); @@ -88,16 +89,16 @@ namespace OpenRA.Platforms.Default else Console.WriteLine("Using default device"); - var dev = Alc.OpenDevice(Game.Settings.Sound.Device); - if (dev == IntPtr.Zero) + device = Alc.OpenDevice(Game.Settings.Sound.Device); + if (device == IntPtr.Zero) { Console.WriteLine("Failed to open device. Falling back to default"); - dev = Alc.OpenDevice(null); - if (dev == IntPtr.Zero) + device = Alc.OpenDevice(null); + if (device == IntPtr.Zero) throw new InvalidOperationException("Can't create OpenAL device"); } - var ctx = Alc.CreateContext(dev, (int[])null); + var ctx = Alc.CreateContext(device, (int[])null); if (ctx == ContextHandle.Zero) throw new InvalidOperationException("Can't create OpenAL context"); Alc.MakeContextCurrent(ctx); @@ -286,6 +287,15 @@ namespace OpenRA.Platforms.Default AL.Listener(ALListenerfv.Orientation, ref orientation); AL.Listener(ALListenerf.EfxMetersPerUnit, .01f); } + + public void Dispose() + { + if (device == IntPtr.Zero) + return; + + Alc.CloseDevice(device); + device = IntPtr.Zero; + } } class OpenAlSoundSource : ISoundSource diff --git a/OpenRA.Platforms.Null/NullSound.cs b/OpenRA.Platforms.Null/NullSound.cs index 41fe831415..7751868d5f 100644 --- a/OpenRA.Platforms.Null/NullSound.cs +++ b/OpenRA.Platforms.Null/NullSound.cs @@ -12,7 +12,7 @@ using System; namespace OpenRA.Platforms.Null { - class NullSoundEngine : ISoundEngine + sealed class NullSoundEngine : ISoundEngine { public SoundDevice[] AvailableDevices() { @@ -42,6 +42,8 @@ namespace OpenRA.Platforms.Null public void SetSoundVolume(float volume, ISound music, ISound video) { } public float Volume { get; set; } + + public void Dispose() { } } class NullSoundSource : ISoundSource { }