fix crash caused by audio weak references

pull/50/head
cosmonaut 2023-06-14 18:22:49 -07:00
parent c83997609f
commit fc0937b2ff
4 changed files with 56 additions and 72 deletions

View File

@ -28,8 +28,8 @@ namespace MoonWorks.Audio
}
private readonly HashSet<WeakReference> resources = new HashSet<WeakReference>();
private readonly List<WeakReference> autoUpdateStreamingSoundReferences = new List<WeakReference>();
private readonly List<WeakReference> autoFreeStaticSoundInstanceReferences = new List<WeakReference>();
private readonly List<StreamingSound> autoUpdateStreamingSoundReferences = new List<StreamingSound>();
private readonly List<StaticSoundInstance> autoFreeStaticSoundInstanceReferences = new List<StaticSoundInstance>();
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)

View File

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

View File

@ -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<AudioTween> DelayedAudioTweens = new List<AudioTween>();
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;
}

View File

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