properly destroy audio

pull/14/head
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 namespace MoonWorks.Audio
{ {
public class AudioDevice public class AudioDevice : IDisposable
{ {
public IntPtr Handle { get; } public IntPtr Handle { get; }
public byte[] Handle3D { get; } public byte[] Handle3D { get; }
@ -17,9 +17,10 @@ namespace MoonWorks.Audio
public float SpeedOfSound = 343.5f; public float SpeedOfSound = 343.5f;
internal FAudio.FAudioVoiceSends ReverbSends; internal FAudio.FAudioVoiceSends ReverbSends;
private readonly List<WeakReference<StreamingSound>> streamingSounds = new List<WeakReference<StreamingSound>>(); private readonly List<WeakReference<StreamingSound>> streamingSounds = new List<WeakReference<StreamingSound>>();
private bool IsDisposed;
public unsafe AudioDevice() public unsafe AudioDevice()
{ {
FAudio.FAudioCreate(out var handle, 0, 0); FAudio.FAudioCreate(out var handle, 0, 0);
@ -214,5 +215,42 @@ namespace MoonWorks.Audio
{ {
streamingSounds.Add(new WeakReference<StreamingSound>(instance)); 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; State = SoundState.Stopped;
} }
public abstract void Play();
public abstract void Pause();
public abstract void Stop(bool immediate);
private void InitDSPSettings(uint srcChannels) private void InitDSPSettings(uint srcChannels)
{ {
dspSettings = new FAudio.F3DAUDIO_DSP_SETTINGS(); dspSettings = new FAudio.F3DAUDIO_DSP_SETTINGS();
@ -314,6 +318,7 @@ namespace MoonWorks.Audio
if (disposing) if (disposing)
{ {
// dispose managed state (managed objects) // dispose managed state (managed objects)
Stop(true);
} }
FAudio.FAudioVoice_DestroyVoice(Handle); FAudio.FAudioVoice_DestroyVoice(Handle);

View File

@ -40,7 +40,7 @@ namespace MoonWorks.Audio
Parent = parent; Parent = parent;
} }
public void Play() public override void Play()
{ {
if (State == SoundState.Playing) if (State == SoundState.Playing)
{ {
@ -70,7 +70,7 @@ namespace MoonWorks.Audio
State = SoundState.Playing; State = SoundState.Playing;
} }
public void Pause() public override void Pause()
{ {
if (State == SoundState.Paused) 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) if (immediate)
{ {

View File

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
namespace MoonWorks.Audio namespace MoonWorks.Audio
{ {
/// <summary> /// <summary>
/// For streaming long playback. /// For streaming long playback.
/// Can be extended to support custom decoders. /// Can be extended to support custom decoders.
/// </summary> /// </summary>
public abstract class StreamingSound : SoundInstance public abstract class StreamingSound : SoundInstance
@ -26,7 +26,7 @@ namespace MoonWorks.Audio
bool loop bool loop
) : base(device, channels, samplesPerSecond, is3D, loop) { } ) : base(device, channels, samplesPerSecond, is3D, loop) { }
public void Play() public override void Play()
{ {
if (State == SoundState.Playing) if (State == SoundState.Playing)
{ {
@ -38,7 +38,7 @@ namespace MoonWorks.Audio
FAudio.FAudioSourceVoice_Start(Handle, 0, 0); FAudio.FAudioSourceVoice_Start(Handle, 0, 0);
} }
public void Pause() public override void Pause()
{ {
if (State == SoundState.Playing) 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) if (immediate)
{ {
@ -110,8 +110,8 @@ namespace MoonWorks.Audio
protected void AddBuffer() protected void AddBuffer()
{ {
AddBuffer( AddBuffer(
out var buffer, out var buffer,
out var bufferOffset, out var bufferOffset,
out var bufferLength, out var bufferLength,
out var reachedEnd out var reachedEnd
); );

View File

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

View File

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