aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-03-07 04:50:09 -0800
committerChris Robinson <[email protected]>2017-03-07 04:50:09 -0800
commitb64da108a9d1885ae70eaf733a388666ddb9ac2d (patch)
treefa813a267bc76ca511c5b77a84636a30deb04645 /OpenAL32
parent190120dfd7ae53e284944fa4971efcf999cc321e (diff)
Check that a source is actually playing before setting paused
Also slightly refactor setting playing state when the device is disconnected or there's no buffers to play.
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/alSource.c63
1 files changed, 35 insertions, 28 deletions
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index ca4f3811..57053083 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -2330,6 +2330,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlay(ALuint source)
}
AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
{
+ ALCdevice *device;
ALCcontext *context;
ALsource *source;
ALsizei i;
@@ -2346,16 +2347,30 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
}
- ALCdevice_Lock(context->Device);
+ device = context->Device;
+ ALCdevice_Lock(device);
+ /* If the device is disconnected, go right to stopped. */
+ if(!device->Connected)
+ {
+ for(i = 0;i < n;i++)
+ {
+ source = LookupSource(context, sources[i]);
+ ATOMIC_STORE(&source->state, AL_STOPPED, almemory_order_relaxed);
+ source->new_state = AL_NONE;
+ }
+ ALCdevice_Unlock(device);
+ goto done;
+ }
+
while(n > context->MaxVoices-context->VoiceCount)
{
ALsizei newcount = context->MaxVoices << 1;
if(context->MaxVoices >= newcount)
{
- ALCdevice_Unlock(context->Device);
+ ALCdevice_Unlock(device);
SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
}
- AllocateVoices(context, newcount, context->Device->NumAuxSends);
+ AllocateVoices(context, newcount, device->NumAuxSends);
}
if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll)
@@ -2374,7 +2389,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
SetSourceState(source, context, AL_PLAYING);
}
}
- ALCdevice_Unlock(context->Device);
+ ALCdevice_Unlock(device);
done:
UnlockSourcesRead(context);
@@ -2993,11 +3008,18 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
BufferList = BufferList->next;
}
- /* If there's nothing to play, or the device is disconnected, go right
- * to stopped.
- */
- if(!BufferList || !device->Connected)
- goto do_stop;
+ /* If there's nothing to play, go right to stopped. */
+ if(!BufferList)
+ {
+ /* NOTE: A source without any playable buffers should not have an
+ * ALvoice since it shouldn't be in a playing or paused state. So
+ * there's no need to look up its voice and clear the source.
+ */
+ ATOMIC_STORE(&Source->state, AL_STOPPED, almemory_order_relaxed);
+ Source->OffsetType = AL_NONE;
+ Source->Offset = 0.0;
+ goto done;
+ }
voice = GetSourceVoice(Source, Context);
switch(GetSourceState(Source, voice))
@@ -3084,31 +3106,16 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
}
else if(state == AL_PAUSED)
{
- ALenum playing = AL_PLAYING;
if((voice=GetSourceVoice(Source, Context)) != NULL)
{
ATOMIC_STORE(&voice->Playing, false, almemory_order_release);
while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1))
althrd_yield();
}
- ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &Source->state, &playing, AL_PAUSED);
- }
- else if(state == AL_STOPPED)
- {
- do_stop:
- if((voice=GetSourceVoice(Source, Context)) != NULL)
- {
- ATOMIC_STORE(&voice->Source, NULL, almemory_order_relaxed);
- ATOMIC_STORE(&voice->Playing, false, almemory_order_release);
- while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1))
- althrd_yield();
- }
- if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) != AL_INITIAL)
- ATOMIC_STORE(&Source->state, AL_STOPPED, almemory_order_relaxed);
- Source->OffsetType = AL_NONE;
- Source->Offset = 0.0;
+ if(GetSourceState(Source, voice) == AL_PLAYING)
+ ATOMIC_STORE(&Source->state, AL_PAUSED, almemory_order_release);
}
- else if(state == AL_INITIAL)
+ else /*if(state == AL_STOPPED || state == AL_INITIAL)*/
{
if((voice=GetSourceVoice(Source, Context)) != NULL)
{
@@ -3118,7 +3125,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
althrd_yield();
}
if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) != AL_INITIAL)
- ATOMIC_STORE(&Source->state, AL_INITIAL, almemory_order_relaxed);
+ ATOMIC_STORE(&Source->state, state, almemory_order_relaxed);
Source->OffsetType = AL_NONE;
Source->Offset = 0.0;
}