From 8fd10bf008eb2726fd585aa42048b249cdecc929 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 28 Jan 2021 18:01:42 -0800 Subject: [PATCH] properly destroy audio --- AudioDevice.cs | 42 ++++++++++++++++++++++++++++++++++++++++-- SoundInstance.cs | 5 +++++ StaticSoundInstance.cs | 6 +++--- StreamingSound.cs | 12 ++++++------ 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/AudioDevice.cs b/AudioDevice.cs index d4acd2e..7ba24e3 100644 --- a/AudioDevice.cs +++ b/AudioDevice.cs @@ -4,7 +4,7 @@ using System.Runtime.InteropServices; namespace MoonWorks.Audio { - public class AudioDevice + public class AudioDevice : IDisposable { public IntPtr Handle { get; } public byte[] Handle3D { get; } @@ -17,9 +17,10 @@ namespace MoonWorks.Audio public float SpeedOfSound = 343.5f; internal FAudio.FAudioVoiceSends ReverbSends; - private readonly List> streamingSounds = new List>(); + private bool IsDisposed; + public unsafe AudioDevice() { FAudio.FAudioCreate(out var handle, 0, 0); @@ -214,5 +215,42 @@ namespace MoonWorks.Audio { streamingSounds.Add(new WeakReference(instance)); } + + protected virtual void Dispose(bool disposing) + { + if (!IsDisposed) + { + if (disposing) + { + // TODO: dispose managed state (managed objects) + foreach (var weakReference in streamingSounds) + { + if (weakReference.TryGetTarget(out var streamingSound)) + { + streamingSound.Dispose(); + } + } + streamingSounds.Clear(); + } + + FAudio.FAudio_Release(Handle); + + IsDisposed = true; + } + } + + // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources + ~AudioDevice() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: false); + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } } } diff --git a/SoundInstance.cs b/SoundInstance.cs index 0f00779..7514f1a 100644 --- a/SoundInstance.cs +++ b/SoundInstance.cs @@ -228,6 +228,10 @@ namespace MoonWorks.Audio State = SoundState.Stopped; } + public abstract void Play(); + public abstract void Pause(); + public abstract void Stop(bool immediate); + private void InitDSPSettings(uint srcChannels) { dspSettings = new FAudio.F3DAUDIO_DSP_SETTINGS(); @@ -314,6 +318,7 @@ namespace MoonWorks.Audio if (disposing) { // dispose managed state (managed objects) + Stop(true); } FAudio.FAudioVoice_DestroyVoice(Handle); diff --git a/StaticSoundInstance.cs b/StaticSoundInstance.cs index c514204..646adc5 100644 --- a/StaticSoundInstance.cs +++ b/StaticSoundInstance.cs @@ -40,7 +40,7 @@ namespace MoonWorks.Audio Parent = parent; } - public void Play() + public override void Play() { if (State == SoundState.Playing) { @@ -70,7 +70,7 @@ namespace MoonWorks.Audio State = SoundState.Playing; } - public void Pause() + public override void Pause() { if (State == SoundState.Paused) { @@ -79,7 +79,7 @@ namespace MoonWorks.Audio } } - public void Stop(bool immediate = true) + public override void Stop(bool immediate = true) { if (immediate) { diff --git a/StreamingSound.cs b/StreamingSound.cs index df2c765..3909cad 100644 --- a/StreamingSound.cs +++ b/StreamingSound.cs @@ -5,7 +5,7 @@ using System.Runtime.InteropServices; namespace MoonWorks.Audio { /// - /// For streaming long playback. + /// For streaming long playback. /// Can be extended to support custom decoders. /// public abstract class StreamingSound : SoundInstance @@ -26,7 +26,7 @@ namespace MoonWorks.Audio bool loop ) : base(device, channels, samplesPerSecond, is3D, loop) { } - public void Play() + public override void Play() { if (State == SoundState.Playing) { @@ -38,7 +38,7 @@ namespace MoonWorks.Audio FAudio.FAudioSourceVoice_Start(Handle, 0, 0); } - public void Pause() + public override void Pause() { if (State == SoundState.Playing) { @@ -47,7 +47,7 @@ namespace MoonWorks.Audio } } - public void Stop(bool immediate = true) + public override void Stop(bool immediate = true) { if (immediate) { @@ -110,8 +110,8 @@ namespace MoonWorks.Audio protected void AddBuffer() { AddBuffer( - out var buffer, - out var bufferOffset, + out var buffer, + out var bufferOffset, out var bufferLength, out var reachedEnd );