From c0ed7bc13d4627839e2c915cafedfb9d8238dc3b Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 6 Mar 2023 23:59:10 -0800 Subject: [PATCH] move tween logic to AudioTweenManager --- src/Audio/AudioDevice.cs | 146 +++-------------------------- src/Audio/AudioTween.cs | 2 +- src/Audio/AudioTweenManager.cs | 163 +++++++++++++++++++++++++++++++++ src/Audio/SoundInstance.cs | 1 - 4 files changed, 179 insertions(+), 133 deletions(-) create mode 100644 src/Audio/AudioTweenManager.cs diff --git a/src/Audio/AudioDevice.cs b/src/Audio/AudioDevice.cs index 4d79eca..7b6c634 100644 --- a/src/Audio/AudioDevice.cs +++ b/src/Audio/AudioDevice.cs @@ -30,9 +30,7 @@ namespace MoonWorks.Audio private readonly HashSet resources = new HashSet(); private readonly HashSet streamingSoundReferences = new HashSet(); - private AudioTweenPool AudioTweenPool = new AudioTweenPool(); - private readonly List AudioTweens = new List(); - private readonly List DelayedAudioTweens = new List(); + private AudioTweenManager AudioTweenManager; private const int Step = 200; private TimeSpan UpdateInterval; @@ -105,8 +103,8 @@ namespace MoonWorks.Audio ) != 0) { Logger.LogError("No mastering voice found!"); - Handle = IntPtr.Zero; FAudio.FAudio_Release(Handle); + Handle = IntPtr.Zero; return; } @@ -121,6 +119,8 @@ namespace MoonWorks.Audio Handle3D ); + AudioTweenManager = new AudioTweenManager(); + Logger.LogInfo("Setting up audio thread..."); WakeSignal = new AutoResetEvent(true); @@ -164,68 +164,7 @@ namespace MoonWorks.Audio } } - for (var i = DelayedAudioTweens.Count - 1; i >= 0; i--) - { - var audioTween = DelayedAudioTweens[i]; - - if (audioTween.SoundInstanceReference.TryGetTarget(out var soundInstance)) - { - audioTween.Time += elapsedSeconds; - - if (audioTween.Time >= audioTween.DelayTime) - { - switch (audioTween.Property) - { - case AudioTweenProperty.Pan: - audioTween.StartValue = soundInstance.Pan; - break; - - case AudioTweenProperty.Pitch: - audioTween.StartValue = soundInstance.Pitch; - break; - - case AudioTweenProperty.Volume: - audioTween.StartValue = soundInstance.Volume; - break; - - case AudioTweenProperty.FilterFrequency: - audioTween.StartValue = soundInstance.FilterFrequency; - break; - - case AudioTweenProperty.Reverb: - audioTween.StartValue = soundInstance.Reverb; - break; - } - - audioTween.Time = 0; - AudioTweens.Add(audioTween); - DelayedAudioTweens.RemoveAt(i); - } - } - else - { - AudioTweenPool.Free(audioTween); - DelayedAudioTweens.RemoveAt(i); - } - - } - - for (var i = AudioTweens.Count - 1; i >= 0; i--) - { - bool finished = true; - var audioTween = AudioTweens[i]; - - if (audioTween.SoundInstanceReference.TryGetTarget(out var soundInstance)) - { - finished = UpdateAudioTween(audioTween, soundInstance, elapsedSeconds); - } - - if (finished) - { - AudioTweenPool.Free(audioTween); - AudioTweens.RemoveAt(i); - } - } + AudioTweenManager.Update(elapsedSeconds); } public void SyncPlay() @@ -233,10 +172,11 @@ namespace MoonWorks.Audio FAudio.FAudio_CommitChanges(Handle, 1); } + internal void CreateTween( SoundInstance soundInstance, AudioTweenProperty property, - EasingFunction easingFunction, + System.Func easingFunction, float start, float end, float duration, @@ -244,72 +184,16 @@ namespace MoonWorks.Audio ) { lock (StateLock) { - var tween = AudioTweenPool.Obtain(); - tween.SoundInstanceReference = new WeakReference(soundInstance); - tween.Property = property; - tween.EasingFunction = easingFunction; - tween.StartValue = start; - tween.EndValue = end; - tween.Duration = duration; - tween.Time = 0; - tween.DelayTime = delayTime; - - if (delayTime == 0) - { - AudioTweens.Add(tween); - } - else - { - DelayedAudioTweens.Add(tween); - } - } - } - - private bool UpdateAudioTween(AudioTween audioTween, SoundInstance soundInstance, float delta) - { - float value; - audioTween.Time += delta; - - var finished = audioTween.Time >= audioTween.Duration; - if (finished) - { - value = audioTween.EndValue; - } - else - { - value = MoonWorks.Math.Easing.Interp( - audioTween.StartValue, - audioTween.EndValue, - audioTween.Time, - audioTween.Duration, - audioTween.EasingFunction + AudioTweenManager.CreateTween( + soundInstance, + property, + easingFunction, + start, + end, + duration, + delayTime ); } - - switch (audioTween.Property) - { - case AudioTweenProperty.Pan: - soundInstance.Pan = value; - break; - - case AudioTweenProperty.Pitch: - soundInstance.Pitch = value; - break; - - case AudioTweenProperty.Volume: - soundInstance.Volume = value; - break; - - case AudioTweenProperty.FilterFrequency: - soundInstance.FilterFrequency = value; - break; - - case AudioTweenProperty.Reverb: - soundInstance.Reverb = value; - break; - } - - return finished; } internal void WakeThread() diff --git a/src/Audio/AudioTween.cs b/src/Audio/AudioTween.cs index d92d7d5..5603e39 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 System.WeakReference SoundInstanceReference; public AudioTweenProperty Property; public EasingFunction EasingFunction; public float Time; diff --git a/src/Audio/AudioTweenManager.cs b/src/Audio/AudioTweenManager.cs new file mode 100644 index 0000000..99b48d2 --- /dev/null +++ b/src/Audio/AudioTweenManager.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; + +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 List DelayedAudioTweens = new List(); + + public void Update(float elapsedSeconds) + { + for (var i = DelayedAudioTweens.Count - 1; i >= 0; i--) + { + var audioTween = DelayedAudioTweens[i]; + if (audioTween.SoundInstanceReference.Target is SoundInstance soundInstance) + { + audioTween.Time += elapsedSeconds; + + if (audioTween.Time >= audioTween.DelayTime) + { + switch (audioTween.Property) + { + case AudioTweenProperty.Pan: + audioTween.StartValue = soundInstance.Pan; + break; + + case AudioTweenProperty.Pitch: + audioTween.StartValue = soundInstance.Pitch; + break; + + case AudioTweenProperty.Volume: + audioTween.StartValue = soundInstance.Volume; + 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); + } + } + else + { + AudioTweenPool.Free(audioTween); + DelayedAudioTweens.RemoveAt(i); + } + } + + foreach (var (key, audioTween) in AudioTweens) + { + bool finished = true; + if (audioTween.SoundInstanceReference.Target is SoundInstance soundInstance) + { + finished = UpdateAudioTween(audioTween, soundInstance, elapsedSeconds); + } + + if (finished) + { + AudioTweenPool.Free(audioTween); + AudioTweens.Remove(key); + } + } + } + + public void CreateTween( + SoundInstance soundInstance, + AudioTweenProperty property, + System.Func easingFunction, + float start, + float end, + float duration, + float delayTime + ) { + var tween = AudioTweenPool.Obtain(); + tween.SoundInstanceReference = soundInstance.weakReference; + tween.Property = property; + tween.EasingFunction = easingFunction; + tween.StartValue = start; + tween.EndValue = end; + tween.Duration = duration; + tween.Time = 0; + tween.DelayTime = delayTime; + + if (delayTime == 0) + { + AddTween(tween); + } + else + { + DelayedAudioTweens.Add(tween); + } + } + + private void AddTween( + AudioTween audioTween + ) { + if (AudioTweens.TryGetValue((audioTween.SoundInstanceReference, audioTween.Property), out var currentTween)) + { + Logger.LogInfo("overriding tween!"); + AudioTweenPool.Free(currentTween); + } + + AudioTweens[(audioTween.SoundInstanceReference, audioTween.Property)] = audioTween; + } + + private static bool UpdateAudioTween(AudioTween audioTween, SoundInstance soundInstance, float delta) + { + float value; + audioTween.Time += delta; + + var finished = audioTween.Time >= audioTween.Duration; + if (finished) + { + value = audioTween.EndValue; + } + else + { + value = MoonWorks.Math.Easing.Interp( + audioTween.StartValue, + audioTween.EndValue, + audioTween.Time, + audioTween.Duration, + audioTween.EasingFunction + ); + } + + switch (audioTween.Property) + { + case AudioTweenProperty.Pan: + soundInstance.Pan = value; + break; + + case AudioTweenProperty.Pitch: + soundInstance.Pitch = value; + break; + + case AudioTweenProperty.Volume: + soundInstance.Volume = value; + break; + + case AudioTweenProperty.FilterFrequency: + soundInstance.FilterFrequency = value; + break; + + case AudioTweenProperty.Reverb: + soundInstance.Reverb = value; + break; + } + + return finished; + } + } +} diff --git a/src/Audio/SoundInstance.cs b/src/Audio/SoundInstance.cs index e08833c..a2bc213 100644 --- a/src/Audio/SoundInstance.cs +++ b/src/Audio/SoundInstance.cs @@ -358,7 +358,6 @@ namespace MoonWorks.Audio public void SetFilterFrequency(float targetValue, float delayTime, float duration, EasingFunction easingFunction) { - Logger.LogInfo(duration.ToString()); Device.CreateTween(this, AudioTweenProperty.FilterFrequency, easingFunction, FilterFrequency, targetValue, duration, delayTime); }