summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c8
-rw-r--r--Alc/ALu.c24
-rw-r--r--Alc/mixer.c3
-rw-r--r--OpenAL32/Include/alSource.h7
-rw-r--r--OpenAL32/Include/alu.h10
-rw-r--r--OpenAL32/alSource.c54
-rw-r--r--OpenAL32/alState.c10
7 files changed, 64 insertions, 52 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index e03e3655..53295fa0 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1927,6 +1927,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
ALactivesource *src = context->ActiveSources[pos];
ALsource *source = src->Source;
ALuint s = device->NumAuxSends;
+
while(s < MAX_SENDS)
{
src->Send[s].Moving = AL_FALSE;
@@ -1934,8 +1935,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
s++;
}
- src->Update(src, context);
- ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
+ if(source)
+ {
+ src->Update(src, source, context);
+ ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE);
+ }
}
context = context->next;
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 86c21cd2..c4a03fec 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -166,7 +166,7 @@ static ALvoid CalcListenerParams(ALlistener *Listener)
aluMatrixVector(Listener->Params.Velocity, 0.0f, Listener->Params.Matrix);
}
-ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
+ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALsource *ALSource, const ALCcontext *ALContext)
{
static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f } };
static const struct ChanMap StereoMap[2] = {
@@ -216,7 +216,6 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
};
ALCdevice *Device = ALContext->Device;
- const ALsource *ALSource = src->Source;
ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume;
ALbufferlistitem *BufferListItem;
enum FmtChannels Channels;
@@ -563,10 +562,9 @@ ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext)
}
}
-ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext)
+ALvoid CalcSourceParams(ALactivesource *src, const ALsource *ALSource, const ALCcontext *ALContext)
{
ALCdevice *Device = ALContext->Device;
- const ALsource *ALSource = src->Source;
ALfloat Velocity[3],Direction[3],Position[3],SourceToListener[3];
ALfloat InnerAngle,OuterAngle,Angle,Distance,ClampedDist;
ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff;
@@ -1178,22 +1176,21 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
while(src != src_end)
{
ALsource *source = (*src)->Source;
+ if(!source) goto next;
if(source->state != AL_PLAYING && source->state != AL_PAUSED)
{
- ALactivesource *temp = *(--src_end);
- *src_end = *src;
- *src = temp;
- --(ctx->ActiveSourceCount);
- continue;
+ (*src)->Source = NULL;
+ goto next;
}
if(!DeferUpdates && (ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) ||
UpdateSources))
- (*src)->Update(*src, ctx);
+ (*src)->Update(*src, source, ctx);
if(source->state != AL_PAUSED)
- MixSource(*src, device, SamplesToDo);
+ MixSource(*src, source, device, SamplesToDo);
+ next:
src++;
}
@@ -1305,13 +1302,16 @@ ALvoid aluHandleDisconnect(ALCdevice *device)
while(src != src_end)
{
ALsource *source = (*src)->Source;
- if(source->state == AL_PLAYING)
+ (*src)->Source = NULL;
+
+ if(source && source->state == AL_PLAYING)
{
source->state = AL_STOPPED;
ATOMIC_STORE(&source->current_buffer, NULL);
source->position = 0;
source->position_fraction = 0;
}
+
src++;
}
Context->ActiveSourceCount = 0;
diff --git a/Alc/mixer.c b/Alc/mixer.c
index 1ca4d664..e4c7a39e 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -178,12 +178,11 @@ static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter
}
-ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
+ALvoid MixSource(ALactivesource *src, ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
{
MixerFunc Mix;
HrtfMixerFunc HrtfMix;
ResamplerFunc Resample;
- ALsource *Source = src->Source;
ALbufferlistitem *BufferListItem;
ALuint DataPosInt, DataPosFrac;
ALboolean Looping;
diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h
index 8d74fc54..173db94e 100644
--- a/OpenAL32/Include/alSource.h
+++ b/OpenAL32/Include/alSource.h
@@ -11,6 +11,9 @@
extern "C" {
#endif
+struct ALbuffer;
+struct ALsource;
+
extern enum Resampler DefaultResampler;
extern const ALsizei ResamplerPadding[ResamplerMax];
@@ -25,10 +28,10 @@ typedef struct ALbufferlistitem {
typedef struct ALactivesource {
- struct ALsource *Source;
+ struct ALsource *volatile Source;
/** Method to update mixing parameters. */
- ALvoid (*Update)(struct ALactivesource *self, const ALCcontext *context);
+ ALvoid (*Update)(struct ALactivesource *self, const struct ALsource *source, const ALCcontext *context);
/** Current target parameters used for mixing. */
ALint Step;
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index 7727c666..ac09f89f 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -41,6 +41,10 @@
extern "C" {
#endif
+struct ALsource;
+struct ALactivesource;
+
+
enum ActiveFilters {
AF_None = 0,
AF_LowPass = 1,
@@ -216,10 +220,10 @@ inline void SetGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MaxC
}
-ALvoid CalcSourceParams(struct ALactivesource *src, const ALCcontext *ALContext);
-ALvoid CalcNonAttnSourceParams(struct ALactivesource *src, const ALCcontext *ALContext);
+ALvoid CalcSourceParams(struct ALactivesource *src, const struct ALsource *source, const ALCcontext *ALContext);
+ALvoid CalcNonAttnSourceParams(struct ALactivesource *src, const struct ALsource *source, const ALCcontext *ALContext);
-ALvoid MixSource(struct ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo);
+ALvoid MixSource(struct ALactivesource *src, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo);
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
/* Caller must lock the device. */
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 27f3eaa1..44969cbf 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -1400,14 +1400,9 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
srclistend = srclist + context->ActiveSourceCount;
while(srclist != srclistend)
{
- if((*srclist)->Source == Source)
- {
- ALactivesource *temp = *(--srclistend);
- *srclistend = *srclist;
- *srclist = temp;
- --(context->ActiveSourceCount);
+ ALsource *old = Source;
+ if(COMPARE_EXCHANGE(&(*srclist)->Source, &old, NULL))
break;
- }
srclist++;
}
UnlockContext(context);
@@ -2456,7 +2451,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
ALCdevice *device = Context->Device;
ALbufferlistitem *BufferList;
ALactivesource *src = NULL;
- ALsizei j, k;
+ ALsizei i;
/* Check that there is a queue containing at least one valid, non zero
* length Buffer. */
@@ -2488,44 +2483,53 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
if(!BufferList || !device->Connected)
goto do_stop;
- for(j = 0;j < Context->ActiveSourceCount;j++)
+ for(i = 0;i < Context->ActiveSourceCount;i++)
{
- if(Context->ActiveSources[j]->Source == Source)
+ if(Context->ActiveSources[i]->Source == Source)
{
- src = Context->ActiveSources[j];
+ src = Context->ActiveSources[i];
break;
}
}
if(src == NULL)
{
- src = Context->ActiveSources[Context->ActiveSourceCount];
- if(src == NULL)
+ for(i = 0;i < Context->ActiveSourceCount;i++)
{
- src = al_malloc(16, sizeof(src[0]));
- Context->ActiveSources[Context->ActiveSourceCount] = src;
+ ALsource *old = NULL;
+ src = Context->ActiveSources[i];
+ if(COMPARE_EXCHANGE(&src->Source, &old, Source))
+ break;
+ }
+ if(i == Context->ActiveSourceCount)
+ {
+ src = Context->ActiveSources[Context->ActiveSourceCount];
+ if(src == NULL)
+ {
+ src = al_malloc(16, sizeof(src[0]));
+ Context->ActiveSources[Context->ActiveSourceCount] = src;
+ }
+ Context->ActiveSourceCount++;
}
memset(src, 0, sizeof(*src));
- Context->ActiveSourceCount++;
src->Source = Source;
}
else
{
- ALuint i;
-
src->Direct.Moving = AL_FALSE;
src->Direct.Counter = 0;
- for(j = 0;j < MAX_INPUT_CHANNELS;j++)
+ for(i = 0;i < MAX_INPUT_CHANNELS;i++)
{
- for(k = 0;k < SRC_HISTORY_LENGTH;k++)
- src->Direct.Mix.Hrtf.State[j].History[k] = 0.0f;
- for(k = 0;k < HRIR_LENGTH;k++)
+ ALsizei j;
+ for(j = 0;j < SRC_HISTORY_LENGTH;j++)
+ src->Direct.Mix.Hrtf.State[i].History[j] = 0.0f;
+ for(j = 0;j < HRIR_LENGTH;j++)
{
- src->Direct.Mix.Hrtf.State[j].Values[k][0] = 0.0f;
- src->Direct.Mix.Hrtf.State[j].Values[k][1] = 0.0f;
+ src->Direct.Mix.Hrtf.State[i].Values[j][0] = 0.0f;
+ src->Direct.Mix.Hrtf.State[i].Values[j][1] = 0.0f;
}
}
- for(i = 0;i < device->NumAuxSends;i++)
+ for(i = 0;i < (ALsizei)device->NumAuxSends;i++)
{
src->Send[i].Counter = 0;
src->Send[i].Moving = AL_FALSE;
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index 4d7b00cf..699bea20 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -732,19 +732,17 @@ AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
while(src != src_end)
{
ALsource *source = (*src)->Source;
+ if(!source) goto next;
if(source->state != AL_PLAYING && source->state != AL_PAUSED)
{
- ALactivesource *temp = *(--src_end);
- *src_end = *src;
- *src = temp;
- --(context->ActiveSourceCount);
+ (*src)->Source = NULL;
continue;
}
if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || UpdateSources)
- (*src)->Update(*src, context);
-
+ (*src)->Update(*src, source, context);
+ next:
src++;
}