Clean up sound devices on game exit.

This commit is contained in:
Paul Chote
2015-09-20 14:36:45 +01:00
parent ef55d646f7
commit d112083c44
5 changed files with 27 additions and 9 deletions

View File

@@ -672,6 +672,7 @@ namespace OpenRA
worldRenderer.Dispose(); worldRenderer.Dispose();
ModData.Dispose(); ModData.Dispose();
ChromeProvider.Deinitialize(); ChromeProvider.Deinitialize();
Sound.Dispose();
Renderer.Dispose(); Renderer.Dispose();
OnQuit(); OnQuit();

View File

@@ -20,7 +20,7 @@ using OpenRA.Traits;
namespace OpenRA namespace OpenRA
{ {
public class Sound public sealed class Sound : IDisposable
{ {
readonly ISoundEngine soundEngine; readonly ISoundEngine soundEngine;
Cache<string, ISoundSource> sounds; Cache<string, ISoundSource> sounds;
@@ -368,5 +368,10 @@ namespace OpenRA
return PlayPredefined(rules, player, null, type.ToLowerInvariant(), notification, variant, true, WPos.Zero, 1f, false); return PlayPredefined(rules, player, null, type.ToLowerInvariant(), notification, variant, true, WPos.Zero, 1f, false);
} }
public void Dispose()
{
soundEngine.Dispose();
}
} }
} }

View File

@@ -12,7 +12,7 @@ using System;
namespace OpenRA namespace OpenRA
{ {
public interface ISoundEngine public interface ISoundEngine : IDisposable
{ {
SoundDevice[] AvailableDevices(); SoundDevice[] AvailableDevices();
ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate); ISoundSource AddSoundSourceFromMemory(byte[] data, int channels, int sampleBits, int sampleRate);

View File

@@ -21,7 +21,7 @@ using OpenTK.Audio.OpenAL;
namespace OpenRA.Platforms.Default namespace OpenRA.Platforms.Default
{ {
class OpenAlSoundEngine : ISoundEngine sealed class OpenAlSoundEngine : ISoundEngine
{ {
public SoundDevice[] AvailableDevices() public SoundDevice[] AvailableDevices()
{ {
@@ -49,6 +49,7 @@ namespace OpenRA.Platforms.Default
const int GroupDistanceSqr = GroupDistance * GroupDistance; const int GroupDistanceSqr = GroupDistance * GroupDistance;
const int PoolSize = 32; const int PoolSize = 32;
IntPtr device;
float volume = 1f; float volume = 1f;
Dictionary<int, PoolSlot> sourcePool = new Dictionary<int, PoolSlot>(); Dictionary<int, PoolSlot> sourcePool = new Dictionary<int, PoolSlot>();
@@ -88,16 +89,16 @@ namespace OpenRA.Platforms.Default
else else
Console.WriteLine("Using default device"); Console.WriteLine("Using default device");
var dev = Alc.OpenDevice(Game.Settings.Sound.Device); device = Alc.OpenDevice(Game.Settings.Sound.Device);
if (dev == IntPtr.Zero) if (device == IntPtr.Zero)
{ {
Console.WriteLine("Failed to open device. Falling back to default"); Console.WriteLine("Failed to open device. Falling back to default");
dev = Alc.OpenDevice(null); device = Alc.OpenDevice(null);
if (dev == IntPtr.Zero) if (device == IntPtr.Zero)
throw new InvalidOperationException("Can't create OpenAL device"); 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) if (ctx == ContextHandle.Zero)
throw new InvalidOperationException("Can't create OpenAL context"); throw new InvalidOperationException("Can't create OpenAL context");
Alc.MakeContextCurrent(ctx); Alc.MakeContextCurrent(ctx);
@@ -286,6 +287,15 @@ namespace OpenRA.Platforms.Default
AL.Listener(ALListenerfv.Orientation, ref orientation); AL.Listener(ALListenerfv.Orientation, ref orientation);
AL.Listener(ALListenerf.EfxMetersPerUnit, .01f); AL.Listener(ALListenerf.EfxMetersPerUnit, .01f);
} }
public void Dispose()
{
if (device == IntPtr.Zero)
return;
Alc.CloseDevice(device);
device = IntPtr.Zero;
}
} }
class OpenAlSoundSource : ISoundSource class OpenAlSoundSource : ISoundSource

View File

@@ -12,7 +12,7 @@ using System;
namespace OpenRA.Platforms.Null namespace OpenRA.Platforms.Null
{ {
class NullSoundEngine : ISoundEngine sealed class NullSoundEngine : ISoundEngine
{ {
public SoundDevice[] AvailableDevices() public SoundDevice[] AvailableDevices()
{ {
@@ -42,6 +42,8 @@ namespace OpenRA.Platforms.Null
public void SetSoundVolume(float volume, ISound music, ISound video) { } public void SetSoundVolume(float volume, ISound music, ISound video) { }
public float Volume { get; set; } public float Volume { get; set; }
public void Dispose() { }
} }
class NullSoundSource : ISoundSource { } class NullSoundSource : ISoundSource { }