From 7014400d1209c0bca97bbc2a4f5544c40dd72a22 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 7 Mar 2023 01:36:07 -0800 Subject: [PATCH] disable threaded upate for theora streaming sound --- src/Audio/AudioDevice.cs | 28 +++++----- src/Audio/AudioTweenManager.cs | 2 + src/Audio/StreamingSound.cs | 3 ++ src/Audio/StreamingSoundOgg.cs | 1 + src/Video/StreamingSoundTheora.cs | 2 + src/Video/VideoPlayer.cs | 90 +++++++++++++++---------------- 6 files changed, 66 insertions(+), 60 deletions(-) diff --git a/src/Audio/AudioDevice.cs b/src/Audio/AudioDevice.cs index 7413df1..85d4d09 100644 --- a/src/Audio/AudioDevice.cs +++ b/src/Audio/AudioDevice.cs @@ -27,7 +27,7 @@ namespace MoonWorks.Audio } private readonly HashSet resources = new HashSet(); - private readonly HashSet streamingSoundReferences = new HashSet(); + private readonly HashSet autoUpdateStreamingSoundReferences = new HashSet(); private AudioTweenManager AudioTweenManager; @@ -150,16 +150,15 @@ namespace MoonWorks.Audio previousTickTime = TickStopwatch.Elapsed.Ticks; float elapsedSeconds = (float) tickDelta / System.TimeSpan.TicksPerSecond; - foreach (var weakReference in streamingSoundReferences) + foreach (var weakReference in autoUpdateStreamingSoundReferences) { - var target = weakReference.Target; - if (target == null) + if (weakReference.Target is StreamingSound streamingSound) { - streamingSoundReferences.Remove(weakReference); + streamingSound.Update(); } else { - (target as StreamingSound).Update(); + autoUpdateStreamingSoundReferences.Remove(weakReference); } } @@ -171,7 +170,6 @@ namespace MoonWorks.Audio FAudio.FAudio_CommitChanges(Handle, 1); } - internal void CreateTween( SoundInstance soundInstance, AudioTweenProperty property, @@ -206,9 +204,9 @@ namespace MoonWorks.Audio { resources.Add(resource.weakReference); - if (resource is StreamingSound streamingSound) + if (resource is StreamingSound streamingSound && streamingSound.AutoUpdate) { - AddDynamicSoundInstance(streamingSound); + AddAutoUpdateStreamingSoundInstance(streamingSound); } } } @@ -219,21 +217,21 @@ namespace MoonWorks.Audio { resources.Remove(resource.weakReference); - if (resource is StreamingSound streamingSound) + if (resource is StreamingSound streamingSound && streamingSound.AutoUpdate) { - RemoveDynamicSoundInstance(streamingSound); + RemoveAutoUpdateStreamingSoundInstance(streamingSound); } } } - private void AddDynamicSoundInstance(StreamingSound instance) + private void AddAutoUpdateStreamingSoundInstance(StreamingSound instance) { - streamingSoundReferences.Add(instance.weakReference); + autoUpdateStreamingSoundReferences.Add(instance.weakReference); } - private void RemoveDynamicSoundInstance(StreamingSound instance) + private void RemoveAutoUpdateStreamingSoundInstance(StreamingSound instance) { - streamingSoundReferences.Remove(instance.weakReference); + autoUpdateStreamingSoundReferences.Remove(instance.weakReference); } protected virtual void Dispose(bool disposing) diff --git a/src/Audio/AudioTweenManager.cs b/src/Audio/AudioTweenManager.cs index f4cd618..f74f43f 100644 --- a/src/Audio/AudioTweenManager.cs +++ b/src/Audio/AudioTweenManager.cs @@ -20,6 +20,7 @@ namespace MoonWorks.Audio if (audioTween.Time >= audioTween.DelayTime) { + // set the tween start value to the current value of the property switch (audioTween.Property) { case AudioTweenProperty.Pan: @@ -104,6 +105,7 @@ namespace MoonWorks.Audio 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)) { AudioTweenPool.Free(currentTween); diff --git a/src/Audio/StreamingSound.cs b/src/Audio/StreamingSound.cs index 8412753..5d503b9 100644 --- a/src/Audio/StreamingSound.cs +++ b/src/Audio/StreamingSound.cs @@ -13,6 +13,9 @@ namespace MoonWorks.Audio // How big should each buffer we consume be? protected abstract int BUFFER_SIZE { get; } + // Should the AudioDevice thread automatically update this class? + public abstract bool AutoUpdate { get; } + // Are we actively consuming buffers? protected bool ConsumingBuffers = false; diff --git a/src/Audio/StreamingSoundOgg.cs b/src/Audio/StreamingSoundOgg.cs index d79370e..882d00e 100644 --- a/src/Audio/StreamingSoundOgg.cs +++ b/src/Audio/StreamingSoundOgg.cs @@ -11,6 +11,7 @@ namespace MoonWorks.Audio private FAudio.stb_vorbis_info Info; protected override int BUFFER_SIZE => 32768; + public override bool AutoUpdate => true; public unsafe static StreamingSoundOgg Load(AudioDevice device, string filePath) { diff --git a/src/Video/StreamingSoundTheora.cs b/src/Video/StreamingSoundTheora.cs index 04d999f..2b111b5 100644 --- a/src/Video/StreamingSoundTheora.cs +++ b/src/Video/StreamingSoundTheora.cs @@ -7,6 +7,8 @@ namespace MoonWorks.Video { private IntPtr VideoHandle; protected override int BUFFER_SIZE => 8192; + // Theorafile is not thread safe, so let's update on the main thread. + public override bool AutoUpdate => false; internal StreamingSoundTheora( AudioDevice device, diff --git a/src/Video/VideoPlayer.cs b/src/Video/VideoPlayer.cs index c5da121..d4c52ad 100644 --- a/src/Video/VideoPlayer.cs +++ b/src/Video/VideoPlayer.cs @@ -124,10 +124,7 @@ namespace MoonWorks.Video Video = video; - lock (AudioDevice.StateLock) - { - InitializeTheoraStream(); - } + InitializeTheoraStream(); } } @@ -184,12 +181,9 @@ namespace MoonWorks.Video lastTimestamp = 0; timeElapsed = 0; - lock (AudioDevice.StateLock) - { - DestroyAudioStream(); + DestroyAudioStream(); - Theorafile.tf_reset(Video.Handle); - } + Theorafile.tf_reset(Video.Handle); State = VideoState.Stopped; } @@ -200,6 +194,16 @@ namespace MoonWorks.Video Video = null; } + public void Update() + { + if (Video == null) { return; } + + if (audioStream != null) + { + audioStream.Update(); + } + } + public void Render() { if (Video == null || State == VideoState.Stopped) @@ -207,48 +211,44 @@ namespace MoonWorks.Video return; } - // Theorafile is not thread safe so we have to do this. Fun! - lock (AudioDevice.StateLock) + timeElapsed += (timer.Elapsed.TotalMilliseconds - lastTimestamp) * PlaybackSpeed; + lastTimestamp = timer.Elapsed.TotalMilliseconds; + + int thisFrame = ((int) (timeElapsed / (1000.0 / Video.FramesPerSecond))); + if (thisFrame > currentFrame) { - timeElapsed += (timer.Elapsed.TotalMilliseconds - lastTimestamp) * PlaybackSpeed; - lastTimestamp = timer.Elapsed.TotalMilliseconds; - - int thisFrame = ((int) (timeElapsed / (1000.0 / Video.FramesPerSecond))); - if (thisFrame > currentFrame) + if (Theorafile.tf_readvideo( + Video.Handle, + (IntPtr) yuvData, + thisFrame - currentFrame + ) == 1 || currentFrame == -1) { - if (Theorafile.tf_readvideo( - Video.Handle, - (IntPtr) yuvData, - thisFrame - currentFrame - ) == 1 || currentFrame == -1) - { - UpdateRenderTexture(); - } - - currentFrame = thisFrame; + UpdateRenderTexture(); } - bool ended = Theorafile.tf_eos(Video.Handle) == 1; - if (ended) + currentFrame = thisFrame; + } + + bool ended = Theorafile.tf_eos(Video.Handle) == 1; + if (ended) + { + timer.Stop(); + timer.Reset(); + + DestroyAudioStream(); + + Theorafile.tf_reset(Video.Handle); + + if (Loop) { - timer.Stop(); - timer.Reset(); + // Start over! + InitializeTheoraStream(); - DestroyAudioStream(); - - Theorafile.tf_reset(Video.Handle); - - if (Loop) - { - // Start over! - InitializeTheoraStream(); - - timer.Start(); - } - else - { - State = VideoState.Stopped; - } + timer.Start(); + } + else + { + State = VideoState.Stopped; } } }