diff --git a/src/Audio/AudioEngine.cs b/src/Audio/AudioEngine.cs index 513c2574d..4bcd07fdf 100644 --- a/src/Audio/AudioEngine.cs +++ b/src/Audio/AudioEngine.cs @@ -226,6 +226,15 @@ ref notificationDesc #endregion + #region Static Constructor + + static AudioEngine() + { + AppDomain.CurrentDomain.ProcessExit += ProgramExit; + } + + #endregion + #region Destructor ~AudioEngine() @@ -423,5 +432,14 @@ private static unsafe void OnXACTNotification(IntPtr notification) } #endregion + + #region Internal Static Methods + + internal static void ProgramExit(object sender, EventArgs e) + { + ProgramExiting = true; + } + + #endregion } } diff --git a/src/Audio/SoundEffect.cs b/src/Audio/SoundEffect.cs index 8f9cc0a0a..3be0165d5 100644 --- a/src/Audio/SoundEffect.cs +++ b/src/Audio/SoundEffect.cs @@ -289,7 +289,7 @@ int loopLength ~SoundEffect() { - if (Instances.Count > 0) + if (!FAudioContext.ProgramExiting && Instances.Count > 0) { // STOP LEAKING YOUR INSTANCES, ARGH GC.ReRegisterForFinalize(this); @@ -534,6 +534,7 @@ public static SoundEffect FromStream(Stream stream) internal class FAudioContext { public static FAudioContext Context = null; + public static bool ProgramExiting = false; public readonly IntPtr Handle; public readonly byte[] Handle3D; @@ -758,6 +759,20 @@ out devices } Context = context; + + AppDomain.CurrentDomain.ProcessExit += ProgramExit; + } + + private static void ProgramExit(object sender, EventArgs e) + { + ProgramExiting = true; + + if (Context != null) + { + GC.Collect(); // Desperate last bid to collect SoundEffectInstances + + SoundEffect.FAudioContext.Context.Dispose(); + } } } diff --git a/src/Audio/SoundEffectInstance.cs b/src/Audio/SoundEffectInstance.cs index cad980dc7..b0afd04cc 100644 --- a/src/Audio/SoundEffectInstance.cs +++ b/src/Audio/SoundEffectInstance.cs @@ -195,7 +195,7 @@ internal SoundEffectInstance(SoundEffect parent = null) ~SoundEffectInstance() { - if (!IsDisposed && State == SoundState.Playing) + if (!SoundEffect.FAudioContext.ProgramExiting && !IsDisposed && State == SoundState.Playing) { // STOP LEAKING YOUR INSTANCES, ARGH GC.ReRegisterForFinalize(this); diff --git a/src/FNAPlatform/SDL2_FNAPlatform.cs b/src/FNAPlatform/SDL2_FNAPlatform.cs index df1da8f81..9a3e91ff3 100644 --- a/src/FNAPlatform/SDL2_FNAPlatform.cs +++ b/src/FNAPlatform/SDL2_FNAPlatform.cs @@ -375,16 +375,6 @@ out prevUserData public static void ProgramExit(object sender, EventArgs e) { - AudioEngine.ProgramExiting = true; - - if (SoundEffect.FAudioContext.Context != null) - { - GC.Collect(); // Desperate last bid to collect SoundEffectInstances - - SoundEffect.FAudioContext.Context.Dispose(); - } - Media.MediaPlayer.DisposeIfNecessary(); - // This _should_ be the last SDL call we make... SDL.SDL_QuitSubSystem( SDL.SDL_INIT_VIDEO | diff --git a/src/FNAPlatform/SDL3_FNAPlatform.cs b/src/FNAPlatform/SDL3_FNAPlatform.cs index 657ad6764..4a2443078 100644 --- a/src/FNAPlatform/SDL3_FNAPlatform.cs +++ b/src/FNAPlatform/SDL3_FNAPlatform.cs @@ -280,16 +280,6 @@ out prevUserData public static void ProgramExit(object sender, EventArgs e) { - AudioEngine.ProgramExiting = true; - - if (SoundEffect.FAudioContext.Context != null) - { - GC.Collect(); // Desperate last bid to collect SoundEffectInstances - - SoundEffect.FAudioContext.Context.Dispose(); - } - Media.MediaPlayer.DisposeIfNecessary(); - // This _should_ be the last SDL call we make... SDL.SDL_QuitSubSystem( SDL.SDL_InitFlags.SDL_INIT_VIDEO | diff --git a/src/Media/MediaPlayer.cs b/src/Media/MediaPlayer.cs index ba8c4331a..e33fd0b55 100644 --- a/src/Media/MediaPlayer.cs +++ b/src/Media/MediaPlayer.cs @@ -162,6 +162,7 @@ public static bool IsVisualizationEnabled static MediaPlayer() { Queue = new MediaQueue(); + AppDomain.CurrentDomain.ProcessExit += ProgramExit; } #endregion @@ -305,15 +306,6 @@ internal static void Update() MoveNext(); } - internal static void DisposeIfNecessary() - { - if (initialized) - { - FAudio.XNA_SongQuit(); - initialized = false; - } - } - internal static void OnActiveSongChanged() { if (ActiveSongChanged != null) @@ -392,6 +384,15 @@ private static void PlaySong(Song song) State = MediaState.Playing; } + private static void ProgramExit(object sender, EventArgs e) + { + if (initialized) + { + FAudio.XNA_SongQuit(); + initialized = false; + } + } + #endregion }