disable threaded upate for theora streaming sound

pull/47/head
cosmonaut 2023-03-07 01:36:07 -08:00
parent 93fe59fb15
commit 7014400d12
6 changed files with 66 additions and 60 deletions

View File

@ -27,7 +27,7 @@ namespace MoonWorks.Audio
} }
private readonly HashSet<WeakReference> resources = new HashSet<WeakReference>(); private readonly HashSet<WeakReference> resources = new HashSet<WeakReference>();
private readonly HashSet<WeakReference> streamingSoundReferences = new HashSet<WeakReference>(); private readonly HashSet<WeakReference> autoUpdateStreamingSoundReferences = new HashSet<WeakReference>();
private AudioTweenManager AudioTweenManager; private AudioTweenManager AudioTweenManager;
@ -150,16 +150,15 @@ namespace MoonWorks.Audio
previousTickTime = TickStopwatch.Elapsed.Ticks; previousTickTime = TickStopwatch.Elapsed.Ticks;
float elapsedSeconds = (float) tickDelta / System.TimeSpan.TicksPerSecond; float elapsedSeconds = (float) tickDelta / System.TimeSpan.TicksPerSecond;
foreach (var weakReference in streamingSoundReferences) foreach (var weakReference in autoUpdateStreamingSoundReferences)
{ {
var target = weakReference.Target; if (weakReference.Target is StreamingSound streamingSound)
if (target == null)
{ {
streamingSoundReferences.Remove(weakReference); streamingSound.Update();
} }
else else
{ {
(target as StreamingSound).Update(); autoUpdateStreamingSoundReferences.Remove(weakReference);
} }
} }
@ -171,7 +170,6 @@ namespace MoonWorks.Audio
FAudio.FAudio_CommitChanges(Handle, 1); FAudio.FAudio_CommitChanges(Handle, 1);
} }
internal void CreateTween( internal void CreateTween(
SoundInstance soundInstance, SoundInstance soundInstance,
AudioTweenProperty property, AudioTweenProperty property,
@ -206,9 +204,9 @@ namespace MoonWorks.Audio
{ {
resources.Add(resource.weakReference); 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); 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) protected virtual void Dispose(bool disposing)

View File

@ -20,6 +20,7 @@ namespace MoonWorks.Audio
if (audioTween.Time >= audioTween.DelayTime) if (audioTween.Time >= audioTween.DelayTime)
{ {
// set the tween start value to the current value of the property
switch (audioTween.Property) switch (audioTween.Property)
{ {
case AudioTweenProperty.Pan: case AudioTweenProperty.Pan:
@ -104,6 +105,7 @@ namespace MoonWorks.Audio
private void AddTween( private void AddTween(
AudioTween audioTween 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.SoundInstanceReference, audioTween.Property), out var currentTween))
{ {
AudioTweenPool.Free(currentTween); AudioTweenPool.Free(currentTween);

View File

@ -13,6 +13,9 @@ namespace MoonWorks.Audio
// How big should each buffer we consume be? // How big should each buffer we consume be?
protected abstract int BUFFER_SIZE { get; } protected abstract int BUFFER_SIZE { get; }
// Should the AudioDevice thread automatically update this class?
public abstract bool AutoUpdate { get; }
// Are we actively consuming buffers? // Are we actively consuming buffers?
protected bool ConsumingBuffers = false; protected bool ConsumingBuffers = false;

View File

@ -11,6 +11,7 @@ namespace MoonWorks.Audio
private FAudio.stb_vorbis_info Info; private FAudio.stb_vorbis_info Info;
protected override int BUFFER_SIZE => 32768; protected override int BUFFER_SIZE => 32768;
public override bool AutoUpdate => true;
public unsafe static StreamingSoundOgg Load(AudioDevice device, string filePath) public unsafe static StreamingSoundOgg Load(AudioDevice device, string filePath)
{ {

View File

@ -7,6 +7,8 @@ namespace MoonWorks.Video
{ {
private IntPtr VideoHandle; private IntPtr VideoHandle;
protected override int BUFFER_SIZE => 8192; 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( internal StreamingSoundTheora(
AudioDevice device, AudioDevice device,

View File

@ -124,10 +124,7 @@ namespace MoonWorks.Video
Video = video; Video = video;
lock (AudioDevice.StateLock) InitializeTheoraStream();
{
InitializeTheoraStream();
}
} }
} }
@ -184,12 +181,9 @@ namespace MoonWorks.Video
lastTimestamp = 0; lastTimestamp = 0;
timeElapsed = 0; timeElapsed = 0;
lock (AudioDevice.StateLock) DestroyAudioStream();
{
DestroyAudioStream();
Theorafile.tf_reset(Video.Handle); Theorafile.tf_reset(Video.Handle);
}
State = VideoState.Stopped; State = VideoState.Stopped;
} }
@ -200,6 +194,16 @@ namespace MoonWorks.Video
Video = null; Video = null;
} }
public void Update()
{
if (Video == null) { return; }
if (audioStream != null)
{
audioStream.Update();
}
}
public void Render() public void Render()
{ {
if (Video == null || State == VideoState.Stopped) if (Video == null || State == VideoState.Stopped)
@ -207,48 +211,44 @@ namespace MoonWorks.Video
return; return;
} }
// Theorafile is not thread safe so we have to do this. Fun! timeElapsed += (timer.Elapsed.TotalMilliseconds - lastTimestamp) * PlaybackSpeed;
lock (AudioDevice.StateLock) lastTimestamp = timer.Elapsed.TotalMilliseconds;
int thisFrame = ((int) (timeElapsed / (1000.0 / Video.FramesPerSecond)));
if (thisFrame > currentFrame)
{ {
timeElapsed += (timer.Elapsed.TotalMilliseconds - lastTimestamp) * PlaybackSpeed; if (Theorafile.tf_readvideo(
lastTimestamp = timer.Elapsed.TotalMilliseconds; Video.Handle,
(IntPtr) yuvData,
int thisFrame = ((int) (timeElapsed / (1000.0 / Video.FramesPerSecond))); thisFrame - currentFrame
if (thisFrame > currentFrame) ) == 1 || currentFrame == -1)
{ {
if (Theorafile.tf_readvideo( UpdateRenderTexture();
Video.Handle,
(IntPtr) yuvData,
thisFrame - currentFrame
) == 1 || currentFrame == -1)
{
UpdateRenderTexture();
}
currentFrame = thisFrame;
} }
bool ended = Theorafile.tf_eos(Video.Handle) == 1; currentFrame = thisFrame;
if (ended) }
bool ended = Theorafile.tf_eos(Video.Handle) == 1;
if (ended)
{
timer.Stop();
timer.Reset();
DestroyAudioStream();
Theorafile.tf_reset(Video.Handle);
if (Loop)
{ {
timer.Stop(); // Start over!
timer.Reset(); InitializeTheoraStream();
DestroyAudioStream(); timer.Start();
}
Theorafile.tf_reset(Video.Handle); else
{
if (Loop) State = VideoState.Stopped;
{
// Start over!
InitializeTheoraStream();
timer.Start();
}
else
{
State = VideoState.Stopped;
}
} }
} }
} }