From fc0937b2ffe141f0b5da4d93a3cbc3f76f5d17b8 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 14 Jun 2023 18:22:49 -0700 Subject: [PATCH] fix crash caused by audio weak references --- src/Audio/AudioDevice.cs | 27 ++++------- src/Audio/AudioTween.cs | 3 +- src/Audio/AudioTweenManager.cs | 88 +++++++++++++++------------------- src/Audio/SoundInstance.cs | 10 ++-- 4 files changed, 56 insertions(+), 72 deletions(-) diff --git a/src/Audio/AudioDevice.cs b/src/Audio/AudioDevice.cs index b61975f7..81c522ce 100644 --- a/src/Audio/AudioDevice.cs +++ b/src/Audio/AudioDevice.cs @@ -28,8 +28,8 @@ namespace MoonWorks.Audio } private readonly HashSet resources = new HashSet(); - private readonly List autoUpdateStreamingSoundReferences = new List(); - private readonly List autoFreeStaticSoundInstanceReferences = new List(); + private readonly List autoUpdateStreamingSoundReferences = new List(); + private readonly List autoFreeStaticSoundInstanceReferences = new List(); private AudioTweenManager AudioTweenManager; @@ -154,9 +154,9 @@ namespace MoonWorks.Audio for (var i = autoUpdateStreamingSoundReferences.Count - 1; i >= 0; i -= 1) { - var weakReference = autoUpdateStreamingSoundReferences[i]; + var streamingSound = autoUpdateStreamingSoundReferences[i]; - if (weakReference.Target is StreamingSound streamingSound && streamingSound.Loaded) + if (streamingSound.Loaded) { streamingSound.Update(); } @@ -168,18 +168,11 @@ namespace MoonWorks.Audio for (var i = autoFreeStaticSoundInstanceReferences.Count - 1; i >= 0; i -= 1) { - var weakReference = autoFreeStaticSoundInstanceReferences[i]; + var staticSoundInstance = autoFreeStaticSoundInstanceReferences[i]; - if (weakReference.Target is StaticSoundInstance staticSoundInstance) - { - if (staticSoundInstance.State == SoundState.Stopped) - { - staticSoundInstance.Free(); - autoFreeStaticSoundInstanceReferences.RemoveAt(i); - } - } - else + if (staticSoundInstance.State == SoundState.Stopped) { + staticSoundInstance.Free(); autoFreeStaticSoundInstanceReferences.RemoveAt(i); } } @@ -216,7 +209,7 @@ namespace MoonWorks.Audio } internal void ClearTweens( - WeakReference soundReference, + SoundInstance soundReference, AudioTweenProperty property ) { lock (StateLock) @@ -248,12 +241,12 @@ namespace MoonWorks.Audio internal void AddAutoUpdateStreamingSoundInstance(StreamingSound instance) { - autoUpdateStreamingSoundReferences.Add(instance.weakReference); + autoUpdateStreamingSoundReferences.Add(instance); } internal void AddAutoFreeStaticSoundInstance(StaticSoundInstance instance) { - autoFreeStaticSoundInstanceReferences.Add(instance.weakReference); + autoFreeStaticSoundInstanceReferences.Add(instance); } protected virtual void Dispose(bool disposing) diff --git a/src/Audio/AudioTween.cs b/src/Audio/AudioTween.cs index 45853908..dc71fef7 100644 --- a/src/Audio/AudioTween.cs +++ b/src/Audio/AudioTween.cs @@ -14,7 +14,7 @@ namespace MoonWorks.Audio internal class AudioTween { - public System.WeakReference SoundInstanceReference; + public SoundInstance SoundInstance; public AudioTweenProperty Property; public EasingFunction EasingFunction; public float Time; @@ -51,6 +51,7 @@ namespace MoonWorks.Audio public void Free(AudioTween tween) { + tween.SoundInstance = null; Tweens.Enqueue(tween); } } diff --git a/src/Audio/AudioTweenManager.cs b/src/Audio/AudioTweenManager.cs index 2f5932c0..f98adcc8 100644 --- a/src/Audio/AudioTweenManager.cs +++ b/src/Audio/AudioTweenManager.cs @@ -6,7 +6,7 @@ namespace MoonWorks.Audio internal class AudioTweenManager { private AudioTweenPool AudioTweenPool = new AudioTweenPool(); - private readonly Dictionary<(WeakReference, AudioTweenProperty), AudioTween> AudioTweens = new Dictionary<(WeakReference, AudioTweenProperty), AudioTween>(); + private readonly Dictionary<(SoundInstance, AudioTweenProperty), AudioTween> AudioTweens = new Dictionary<(SoundInstance, AudioTweenProperty), AudioTween>(); private readonly List DelayedAudioTweens = new List(); public void Update(float elapsedSeconds) @@ -14,56 +14,46 @@ namespace MoonWorks.Audio for (var i = DelayedAudioTweens.Count - 1; i >= 0; i--) { var audioTween = DelayedAudioTweens[i]; - if (audioTween.SoundInstanceReference.Target is SoundInstance soundInstance) - { - audioTween.Time += elapsedSeconds; + var soundInstance = audioTween.SoundInstance; - if (audioTween.Time >= audioTween.DelayTime) + audioTween.Time += elapsedSeconds; + + if (audioTween.Time >= audioTween.DelayTime) + { + // set the tween start value to the current value of the property + switch (audioTween.Property) { - // set the tween start value to the current value of the property - switch (audioTween.Property) - { - case AudioTweenProperty.Pan: - audioTween.StartValue = soundInstance.Pan; - break; + case AudioTweenProperty.Pan: + audioTween.StartValue = soundInstance.Pan; + break; - case AudioTweenProperty.Pitch: - audioTween.StartValue = soundInstance.Pitch; - break; + case AudioTweenProperty.Pitch: + audioTween.StartValue = soundInstance.Pitch; + break; - case AudioTweenProperty.Volume: - audioTween.StartValue = soundInstance.Volume; - break; + case AudioTweenProperty.Volume: + audioTween.StartValue = soundInstance.Volume; + break; - case AudioTweenProperty.FilterFrequency: - audioTween.StartValue = soundInstance.FilterFrequency; - break; + case AudioTweenProperty.FilterFrequency: + audioTween.StartValue = soundInstance.FilterFrequency; + break; - case AudioTweenProperty.Reverb: - audioTween.StartValue = soundInstance.Reverb; - break; - } - - audioTween.Time = 0; - DelayedAudioTweens.RemoveAt(i); - - AddTween(audioTween); + case AudioTweenProperty.Reverb: + audioTween.StartValue = soundInstance.Reverb; + break; } - } - else - { - AudioTweenPool.Free(audioTween); + + audioTween.Time = 0; DelayedAudioTweens.RemoveAt(i); + + AddTween(audioTween); } } foreach (var (key, audioTween) in AudioTweens) { - bool finished = true; - if (audioTween.SoundInstanceReference.Target is SoundInstance soundInstance) - { - finished = UpdateAudioTween(audioTween, soundInstance, elapsedSeconds); - } + bool finished = UpdateAudioTween(audioTween, elapsedSeconds); if (finished) { @@ -83,7 +73,7 @@ namespace MoonWorks.Audio float delayTime ) { var tween = AudioTweenPool.Obtain(); - tween.SoundInstanceReference = soundInstance.weakReference; + tween.SoundInstance = soundInstance; tween.Property = property; tween.EasingFunction = easingFunction; tween.StartValue = start; @@ -102,24 +92,24 @@ namespace MoonWorks.Audio } } - public void ClearTweens(WeakReference soundReference, AudioTweenProperty property) + public void ClearTweens(SoundInstance soundInstance, AudioTweenProperty property) { - AudioTweens.Remove((soundReference, property)); + AudioTweens.Remove((soundInstance, property)); } private void AddTween( AudioTween audioTween ) { // if a tween with the same sound and property already exists, get rid of it - if (AudioTweens.TryGetValue((audioTween.SoundInstanceReference, audioTween.Property), out var currentTween)) + if (AudioTweens.TryGetValue((audioTween.SoundInstance, audioTween.Property), out var currentTween)) { AudioTweenPool.Free(currentTween); } - AudioTweens[(audioTween.SoundInstanceReference, audioTween.Property)] = audioTween; + AudioTweens[(audioTween.SoundInstance, audioTween.Property)] = audioTween; } - private static bool UpdateAudioTween(AudioTween audioTween, SoundInstance soundInstance, float delta) + private static bool UpdateAudioTween(AudioTween audioTween, float delta) { float value; audioTween.Time += delta; @@ -143,23 +133,23 @@ namespace MoonWorks.Audio switch (audioTween.Property) { case AudioTweenProperty.Pan: - soundInstance.Pan = value; + audioTween.SoundInstance.Pan = value; break; case AudioTweenProperty.Pitch: - soundInstance.Pitch = value; + audioTween.SoundInstance.Pitch = value; break; case AudioTweenProperty.Volume: - soundInstance.Volume = value; + audioTween.SoundInstance.Volume = value; break; case AudioTweenProperty.FilterFrequency: - soundInstance.FilterFrequency = value; + audioTween.SoundInstance.FilterFrequency = value; break; case AudioTweenProperty.Reverb: - soundInstance.Reverb = value; + audioTween.SoundInstance.Reverb = value; break; } diff --git a/src/Audio/SoundInstance.cs b/src/Audio/SoundInstance.cs index 10e36503..11d320ee 100644 --- a/src/Audio/SoundInstance.cs +++ b/src/Audio/SoundInstance.cs @@ -308,7 +308,7 @@ namespace MoonWorks.Audio public void SetPan(float targetValue) { Pan = targetValue; - Device.ClearTweens(weakReference, AudioTweenProperty.Pan); + Device.ClearTweens(this, AudioTweenProperty.Pan); } public void SetPan(float targetValue, float duration, EasingFunction easingFunction) @@ -324,7 +324,7 @@ namespace MoonWorks.Audio public void SetPitch(float targetValue) { Pitch = targetValue; - Device.ClearTweens(weakReference, AudioTweenProperty.Pitch); + Device.ClearTweens(this, AudioTweenProperty.Pitch); } public void SetPitch(float targetValue, float duration, EasingFunction easingFunction) @@ -340,7 +340,7 @@ namespace MoonWorks.Audio public void SetVolume(float targetValue) { Volume = targetValue; - Device.ClearTweens(weakReference, AudioTweenProperty.Volume); + Device.ClearTweens(this, AudioTweenProperty.Volume); } public void SetVolume(float targetValue, float duration, EasingFunction easingFunction) @@ -356,7 +356,7 @@ namespace MoonWorks.Audio public void SetFilterFrequency(float targetValue) { FilterFrequency = targetValue; - Device.ClearTweens(weakReference, AudioTweenProperty.FilterFrequency); + Device.ClearTweens(this, AudioTweenProperty.FilterFrequency); } public void SetFilterFrequency(float targetValue, float duration, EasingFunction easingFunction) @@ -377,7 +377,7 @@ namespace MoonWorks.Audio public void SetReverb(float targetValue) { Reverb = targetValue; - Device.ClearTweens(weakReference, AudioTweenProperty.Reverb); + Device.ClearTweens(this, AudioTweenProperty.Reverb); } public void SetReverb(float targetValue, float duration, EasingFunction easingFunction)