working on thread safety
parent
f70caa1a42
commit
52c4fa26c7
|
@ -163,8 +163,6 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
}
|
||||
|
||||
lock (AudioTweens)
|
||||
{
|
||||
for (var i = AudioTweens.Count - 1; i >= 0; i--)
|
||||
{
|
||||
bool finished = true;
|
||||
|
@ -182,7 +180,6 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SyncPlay()
|
||||
{
|
||||
|
@ -206,7 +203,7 @@ namespace MoonWorks.Audio
|
|||
tween.Duration = duration;
|
||||
tween.Time = 0;
|
||||
|
||||
lock (AudioTweens)
|
||||
lock (StateLock)
|
||||
{
|
||||
AudioTweens.Add(tween);
|
||||
}
|
||||
|
@ -263,19 +260,21 @@ namespace MoonWorks.Audio
|
|||
WakeSignal.Set();
|
||||
}
|
||||
|
||||
internal void AddDynamicSoundInstance(StreamingSound instance)
|
||||
{
|
||||
lock (StateLock)
|
||||
private void AddDynamicSoundInstance(StreamingSound instance)
|
||||
{
|
||||
streamingSounds.Add(new WeakReference<StreamingSound>(instance));
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddResourceReference(WeakReference<AudioResource> resourceReference)
|
||||
internal void AddResourceReference(AudioResource resource, WeakReference<AudioResource> resourceReference)
|
||||
{
|
||||
lock (StateLock)
|
||||
{
|
||||
resources.Add(resourceReference);
|
||||
|
||||
if (resource is StreamingSound streamingSound)
|
||||
{
|
||||
AddDynamicSoundInstance(streamingSound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace MoonWorks.Audio
|
|||
Device = device;
|
||||
|
||||
selfReference = new WeakReference<AudioResource>(this);
|
||||
Device.AddResourceReference(selfReference);
|
||||
Device.AddResourceReference(this, selfReference);
|
||||
}
|
||||
|
||||
protected abstract void Destroy();
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace MoonWorks.Audio
|
|||
private int nextBufferIndex = 0;
|
||||
private uint queuedBufferCount = 0;
|
||||
protected abstract int BUFFER_SIZE { get; }
|
||||
private readonly object StateLock = new object();
|
||||
|
||||
public unsafe StreamingSound(
|
||||
AudioDevice device,
|
||||
|
@ -25,8 +26,6 @@ namespace MoonWorks.Audio
|
|||
uint samplesPerSecond
|
||||
) : base(device, formatTag, bitsPerSample, blockAlign, channels, samplesPerSecond)
|
||||
{
|
||||
device.AddDynamicSoundInstance(this);
|
||||
|
||||
buffers = new IntPtr[BUFFER_COUNT];
|
||||
for (int i = 0; i < BUFFER_COUNT; i += 1)
|
||||
{
|
||||
|
@ -45,6 +44,8 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
|
||||
private void PlayUsingOperationSet(uint operationSet)
|
||||
{
|
||||
lock (StateLock)
|
||||
{
|
||||
if (State == SoundState.Playing)
|
||||
{
|
||||
|
@ -53,11 +54,14 @@ namespace MoonWorks.Audio
|
|||
|
||||
State = SoundState.Playing;
|
||||
|
||||
Update();
|
||||
QueueBuffers();
|
||||
FAudio.FAudioSourceVoice_Start(Voice, 0, operationSet);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Pause()
|
||||
{
|
||||
lock (StateLock)
|
||||
{
|
||||
if (State == SoundState.Playing)
|
||||
{
|
||||
|
@ -65,6 +69,7 @@ namespace MoonWorks.Audio
|
|||
State = SoundState.Paused;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
|
@ -72,6 +77,8 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
|
||||
public override void StopImmediate()
|
||||
{
|
||||
lock (StateLock)
|
||||
{
|
||||
FAudio.FAudioSourceVoice_Stop(Voice, 0, 0);
|
||||
FAudio.FAudioSourceVoice_FlushSourceBuffers(Voice);
|
||||
|
@ -79,14 +86,23 @@ namespace MoonWorks.Audio
|
|||
|
||||
State = SoundState.Stopped;
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe void Update()
|
||||
{
|
||||
lock (StateLock)
|
||||
{
|
||||
if (State != SoundState.Playing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QueueBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
protected void QueueBuffers()
|
||||
{
|
||||
FAudio.FAudioSourceVoice_GetState(
|
||||
Voice,
|
||||
out var state,
|
||||
|
@ -95,11 +111,6 @@ namespace MoonWorks.Audio
|
|||
|
||||
queuedBufferCount = state.BuffersQueued;
|
||||
|
||||
QueueBuffers();
|
||||
}
|
||||
|
||||
protected void QueueBuffers()
|
||||
{
|
||||
for (int i = 0; i < BUFFER_COUNT - queuedBufferCount; i += 1)
|
||||
{
|
||||
AddBuffer();
|
||||
|
@ -124,6 +135,8 @@ namespace MoonWorks.Audio
|
|||
out bool reachedEnd
|
||||
);
|
||||
|
||||
if (filledLengthInBytes > 0)
|
||||
{
|
||||
FAudio.FAudioBuffer buf = new FAudio.FAudioBuffer
|
||||
{
|
||||
AudioBytes = (uint) filledLengthInBytes,
|
||||
|
@ -142,19 +155,20 @@ namespace MoonWorks.Audio
|
|||
);
|
||||
|
||||
queuedBufferCount += 1;
|
||||
}
|
||||
else if (queuedBufferCount == 0)
|
||||
{
|
||||
// no more data, nothing queued, we're done
|
||||
Stop();
|
||||
}
|
||||
|
||||
/* We have reached the end of the file, what do we do? */
|
||||
if (reachedEnd)
|
||||
{
|
||||
/* We have reached the end of the data, what do we do? */
|
||||
OnReachedEnd();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnReachedEnd()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
protected unsafe abstract void FillBuffer(
|
||||
void* buffer,
|
||||
int bufferLengthInBytes, /* in bytes */
|
||||
|
@ -162,7 +176,11 @@ namespace MoonWorks.Audio
|
|||
out bool reachedEnd
|
||||
);
|
||||
|
||||
protected abstract void OnReachedEnd();
|
||||
|
||||
protected unsafe override void Destroy()
|
||||
{
|
||||
lock (StateLock)
|
||||
{
|
||||
StopImmediate();
|
||||
|
||||
|
@ -172,4 +190,5 @@ namespace MoonWorks.Audio
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace MoonWorks.Audio
|
|||
);
|
||||
}
|
||||
|
||||
internal StreamingSoundOgg(
|
||||
internal unsafe StreamingSoundOgg(
|
||||
AudioDevice device,
|
||||
IntPtr fileDataPtr, // MUST BE A NATIVE MEMORY HANDLE!!
|
||||
IntPtr vorbisHandle,
|
||||
|
@ -47,8 +47,7 @@ namespace MoonWorks.Audio
|
|||
(ushort) (4 * info.channels),
|
||||
(ushort) info.channels,
|
||||
info.sample_rate
|
||||
)
|
||||
{
|
||||
) {
|
||||
FileDataPtr = fileDataPtr;
|
||||
VorbisHandle = vorbisHandle;
|
||||
Info = info;
|
||||
|
@ -64,8 +63,7 @@ namespace MoonWorks.Audio
|
|||
int bufferLengthInBytes,
|
||||
out int filledLengthInBytes,
|
||||
out bool reachedEnd
|
||||
)
|
||||
{
|
||||
) {
|
||||
var lengthInFloats = bufferLengthInBytes / sizeof(float);
|
||||
|
||||
/* NOTE: this function returns samples per channel, not total samples */
|
||||
|
@ -81,6 +79,14 @@ namespace MoonWorks.Audio
|
|||
filledLengthInBytes = sampleCount * sizeof(float);
|
||||
}
|
||||
|
||||
protected override void OnReachedEnd()
|
||||
{
|
||||
if (Loop)
|
||||
{
|
||||
Seek(0);
|
||||
}
|
||||
}
|
||||
|
||||
protected unsafe override void Destroy()
|
||||
{
|
||||
FAudio.stb_vorbis_close(VorbisHandle);
|
||||
|
|
|
@ -41,5 +41,7 @@ namespace MoonWorks.Video
|
|||
filledLengthInBytes = samples * sizeof(float);
|
||||
reachedEnd = Theorafile.tf_eos(VideoHandle) == 1;
|
||||
}
|
||||
|
||||
protected override void OnReachedEnd() { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,6 +130,8 @@ namespace MoonWorks.Video
|
|||
|
||||
public void Play()
|
||||
{
|
||||
if (Video == null) { return; }
|
||||
|
||||
if (State == VideoState.Playing)
|
||||
{
|
||||
return;
|
||||
|
@ -147,6 +149,8 @@ namespace MoonWorks.Video
|
|||
|
||||
public void Pause()
|
||||
{
|
||||
if (Video == null) { return; }
|
||||
|
||||
if (State != VideoState.Playing)
|
||||
{
|
||||
return;
|
||||
|
@ -164,6 +168,8 @@ namespace MoonWorks.Video
|
|||
|
||||
public void Stop()
|
||||
{
|
||||
if (Video == null) { return; }
|
||||
|
||||
if (State == VideoState.Stopped)
|
||||
{
|
||||
return;
|
||||
|
@ -172,7 +178,6 @@ namespace MoonWorks.Video
|
|||
timer.Stop();
|
||||
timer.Reset();
|
||||
|
||||
Theorafile.tf_reset(Video.Handle);
|
||||
lastTimestamp = 0;
|
||||
timeElapsed = 0;
|
||||
|
||||
|
@ -183,6 +188,8 @@ namespace MoonWorks.Video
|
|||
audioStream = null;
|
||||
}
|
||||
|
||||
Theorafile.tf_reset(Video.Handle);
|
||||
|
||||
State = VideoState.Stopped;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue