using System; using System.Runtime.InteropServices; namespace Susurrus.XAudio2 { /// /// A voice the engine made, which stays valid until it is destroyed. /// public abstract class XAudio2Voice { [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void DestroyCall(IntPtr self); private readonly DestroyCall destroy; private IntPtr handle; /// /// Gets the native object's address, which is zero once the voice is destroyed. /// protected IntPtr Handle => handle; public bool IsDestroyed => handle == IntPtr.Zero; protected XAudio2Voice(IntPtr handle) { this.destroy = Vtable.Bind(handle, VoiceSlots.DestroyVoice); this.handle = handle; } /// /// Throws if the voice has been destroyed, since its native object is then gone. /// protected void ThrowIfDestroyed() { if (handle == IntPtr.Zero) { throw new ObjectDisposedException(GetType().Name, "This voice has been destroyed."); } } /// /// Frees the native voice. Does nothing if it is already destroyed. /// public void Destroy() { if (handle == IntPtr.Zero) { return; } IntPtr native = handle; handle = IntPtr.Zero; destroy(native); } } }