properly destroy audio

main
cosmonaut 2021-01-28 18:01:42 -08:00
parent c65485a31c
commit eda1efedbe
6 changed files with 61 additions and 19 deletions

View File

@ -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<WeakReference<StreamingSound>> streamingSounds = new List<WeakReference<StreamingSound>>();
private bool IsDisposed;
public unsafe AudioDevice()
{
FAudio.FAudioCreate(out var handle, 0, 0);
@ -214,5 +215,42 @@ namespace MoonWorks.Audio
{
streamingSounds.Add(new WeakReference<StreamingSound>(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);
}
}
}

View File

@ -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);

View File

@ -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)
{

View File

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
namespace MoonWorks.Audio
{
/// <summary>
/// For streaming long playback.
/// For streaming long playback.
/// Can be extended to support custom decoders.
/// </summary>
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
);

View File

@ -12,7 +12,7 @@ namespace MoonWorks.Graphics
private readonly Queue<CommandBuffer> commandBufferPool;
private readonly List<WeakReference> resources = new List<WeakReference>();
private readonly List<WeakReference<GraphicsResource>> resources = new List<WeakReference<GraphicsResource>>();
public GraphicsDevice(
IntPtr deviceWindowHandle,
@ -80,7 +80,7 @@ namespace MoonWorks.Graphics
Refresh.Refresh_Wait(Handle);
}
internal void AddResourceReference(WeakReference resourceReference)
internal void AddResourceReference(WeakReference<GraphicsResource> resourceReference)
{
lock (resources)
{
@ -88,7 +88,7 @@ namespace MoonWorks.Graphics
}
}
internal void RemoveResourceReference(WeakReference resourceReference)
internal void RemoveResourceReference(WeakReference<GraphicsResource> resourceReference)
{
lock (resources)
{
@ -106,10 +106,9 @@ namespace MoonWorks.Graphics
{
foreach (var resource in resources)
{
var target = resource.Target;
if (target != null)
if (resource.TryGetTarget(out var target))
{
(target as IDisposable).Dispose();
target.Dispose();
}
}
resources.Clear();

View File

@ -10,13 +10,13 @@ namespace MoonWorks.Graphics
public bool IsDisposed { get; private set; }
protected abstract Action<IntPtr, IntPtr> QueueDestroyFunction { get; }
private WeakReference selfReference;
private WeakReference<GraphicsResource> selfReference;
public GraphicsResource(GraphicsDevice device)
{
Device = device;
selfReference = new WeakReference(this);
selfReference = new WeakReference<GraphicsResource>(this);
Device.AddResourceReference(selfReference);
}