diff options
-rw-r--r-- | Alc/ALc.c | 51 | ||||
-rw-r--r-- | Alc/ALu.c | 52 | ||||
-rw-r--r-- | OpenAL32/Include/alListener.h | 19 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 5 | ||||
-rw-r--r-- | OpenAL32/Include/alu.h | 2 | ||||
-rw-r--r-- | OpenAL32/alListener.c | 18 | ||||
-rw-r--r-- | OpenAL32/alState.c | 51 |
7 files changed, 138 insertions, 60 deletions
@@ -1669,6 +1669,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) while((ATOMIC_LOAD(&context->UpdateCount, almemory_order_acquire)&1) != 0) althrd_yield(); + UpdateContextProps(context); UpdateListenerProps(context); UpdateAllEffectSlotProps(context); UpdateAllSourceProps(context); @@ -2519,7 +2520,6 @@ static ALvoid InitContext(ALCcontext *Context) //Initialise listener listener->Gain = 1.0f; - listener->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT; listener->Position[0] = 0.0f; listener->Position[1] = 0.0f; listener->Position[2] = 0.0f; @@ -2533,19 +2533,6 @@ static ALvoid InitContext(ALCcontext *Context) listener->Up[1] = 1.0f; listener->Up[2] = 0.0f; - aluMatrixfSet(&listener->Params.Matrix, - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - ); - aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f); - listener->Params.Gain = 1.0f; - listener->Params.MetersPerUnit = listener->MetersPerUnit; - listener->Params.DopplerFactor = 1.0f; - listener->Params.SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; - listener->Params.ReverbSpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; - ATOMIC_INIT(&listener->Update, NULL); ATOMIC_INIT(&listener->FreeList, NULL); @@ -2577,9 +2564,28 @@ static ALvoid InitContext(ALCcontext *Context) Context->DopplerFactor = 1.0f; Context->DopplerVelocity = 1.0f; Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; + Context->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT; ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE); + ATOMIC_INIT(&Context->Update, NULL); + ATOMIC_INIT(&Context->FreeList, NULL); + Context->ExtensionList = alExtList; + + + aluMatrixfSet(&listener->Params.Matrix, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ); + aluVectorSet(&listener->Params.Velocity, 0.0f, 0.0f, 0.0f, 0.0f); + listener->Params.Gain = listener->Gain; + listener->Params.MetersPerUnit = Context->MetersPerUnit; + listener->Params.DopplerFactor = Context->DopplerFactor; + listener->Params.SpeedOfSound = Context->SpeedOfSound * Context->DopplerVelocity; + listener->Params.ReverbSpeedOfSound = listener->Params.SpeedOfSound * + listener->Params.MetersPerUnit; } @@ -2593,11 +2599,28 @@ static void FreeContext(ALCcontext *context) ALlistener *listener = context->Listener; struct ALeffectslotArray *auxslots; struct ALlistenerProps *lprops; + struct ALcontextProps *cprops; size_t count; ALsizei i; TRACE("%p\n", context); + if((cprops=ATOMIC_LOAD(&context->Update, almemory_order_acquire)) != NULL) + { + TRACE("Freed unapplied context update %p\n", cprops); + al_free(cprops); + } + count = 0; + cprops = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire); + while(cprops) + { + struct ALcontextProps *next = ATOMIC_LOAD(&cprops->next, almemory_order_acquire); + al_free(cprops); + cprops = next; + ++count; + } + TRACE("Freed "SZFMT" context property object%s\n", count, (count==1)?"":"s"); + if(context->DefaultSlot) { DeinitEffectSlot(context->DefaultSlot); @@ -271,7 +271,30 @@ ALboolean BsincPrepare(const ALuint increment, BsincState *state, const BSincTab } -static ALboolean CalcListenerParams(ALCcontext *Context) +static bool CalcContextParams(ALCcontext *Context) +{ + ALlistener *Listener = Context->Listener; + struct ALcontextProps *props; + + props = ATOMIC_EXCHANGE_PTR(&Context->Update, NULL, almemory_order_acq_rel); + if(!props) return false; + + Listener->Params.MetersPerUnit = props->MetersPerUnit; + + Listener->Params.DopplerFactor = props->DopplerFactor; + Listener->Params.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity; + if(!OverrideReverbSpeedOfSound) + Listener->Params.ReverbSpeedOfSound = Listener->Params.SpeedOfSound * + Listener->Params.MetersPerUnit; + + Listener->Params.SourceDistanceModel = props->SourceDistanceModel; + Listener->Params.DistanceModel = props->DistanceModel; + + ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &Context->FreeList, props); + return true; +} + +static bool CalcListenerParams(ALCcontext *Context) { ALlistener *Listener = Context->Listener; ALfloat N[3], V[3], U[3], P[3]; @@ -279,7 +302,7 @@ static ALboolean CalcListenerParams(ALCcontext *Context) aluVector vel; props = ATOMIC_EXCHANGE_PTR(&Listener->Update, NULL, almemory_order_acq_rel); - if(!props) return AL_FALSE; + if(!props) return false; /* AT then UP */ N[0] = props->Forward[0]; @@ -311,30 +334,18 @@ static ALboolean CalcListenerParams(ALCcontext *Context) Listener->Params.Velocity = aluMatrixfVector(&Listener->Params.Matrix, &vel); Listener->Params.Gain = props->Gain * Context->GainBoost; - Listener->Params.MetersPerUnit = props->MetersPerUnit; - - Listener->Params.DopplerFactor = props->DopplerFactor; - Listener->Params.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity; - if(OverrideReverbSpeedOfSound) - Listener->Params.ReverbSpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; - else - Listener->Params.ReverbSpeedOfSound = Listener->Params.SpeedOfSound * - Listener->Params.MetersPerUnit; - - Listener->Params.SourceDistanceModel = props->SourceDistanceModel; - Listener->Params.DistanceModel = props->DistanceModel; ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Listener->FreeList, props); - return AL_TRUE; + return true; } -static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context) +static bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context) { struct ALeffectslotProps *props; ALeffectState *state; props = ATOMIC_EXCHANGE_PTR(&slot->Update, NULL, almemory_order_acq_rel); - if(!props) return AL_FALSE; + if(!props) return false; slot->Params.Gain = props->Gain; slot->Params.AuxSendAuto = props->AuxSendAuto; @@ -366,7 +377,7 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context) V(state,update)(context, slot, &props->Props); ATOMIC_REPLACE_HEAD(struct ALeffectslotProps*, &slot->FreeList, props); - return AL_TRUE; + return true; } @@ -1430,7 +1441,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop WetGainLF, WetGainHF, SendSlots, ALBuffer, props, Listener, Device); } -static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force) +static void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force) { ALbufferlistitem *BufferListItem; struct ALvoiceProps *props; @@ -1475,7 +1486,8 @@ static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray IncrementRef(&ctx->UpdateCount); if(!ATOMIC_LOAD(&ctx->HoldUpdates, almemory_order_acquire)) { - ALboolean force = CalcListenerParams(ctx); + ALboolean cforce = CalcContextParams(ctx); + ALboolean force = CalcListenerParams(ctx) | cforce; for(i = 0;i < slots->count;i++) force |= CalcEffectSlotParams(slots->slot[i], ctx); diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index eb386f7f..ae66b0e3 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -8,19 +8,23 @@ extern "C" { #endif +struct ALcontextProps { + ALfloat DopplerFactor; + ALfloat DopplerVelocity; + ALfloat SpeedOfSound; + ALboolean SourceDistanceModel; + enum DistanceModel DistanceModel; + ALfloat MetersPerUnit; + + ATOMIC(struct ALcontextProps*) next; +}; + struct ALlistenerProps { ALfloat Position[3]; ALfloat Velocity[3]; ALfloat Forward[3]; ALfloat Up[3]; ALfloat Gain; - ALfloat MetersPerUnit; - - ALfloat DopplerFactor; - ALfloat DopplerVelocity; - ALfloat SpeedOfSound; - ALboolean SourceDistanceModel; - enum DistanceModel DistanceModel; ATOMIC(struct ALlistenerProps*) next; }; @@ -31,7 +35,6 @@ typedef struct ALlistener { ALfloat Forward[3]; ALfloat Up[3]; ALfloat Gain; - ALfloat MetersPerUnit; /* Pointer to the most recent property values that are awaiting an update. */ diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 614c3b43..95137972 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -382,6 +382,7 @@ struct Hrtf; struct HrtfEntry; struct FrontStablizer; struct Compressor; +struct ALcontextProps; #define DEFAULT_OUTPUT_RATE (44100) @@ -851,6 +852,7 @@ struct ALCcontext_struct { ALfloat DopplerFactor; ALfloat DopplerVelocity; ALfloat SpeedOfSound; + ALfloat MetersPerUnit; ATOMIC(ALenum) DeferUpdates; RWLock PropLock; @@ -863,6 +865,9 @@ struct ALCcontext_struct { ALfloat GainBoost; + ATOMIC(struct ALcontextProps*) Update; + ATOMIC(struct ALcontextProps*) FreeList; + struct ALvoice **Voices; ALsizei VoiceCount; ALsizei MaxVoices; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 1295fee3..2344cc6d 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -514,6 +514,8 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples); /* Caller must lock the device. */ void aluHandleDisconnect(ALCdevice *device); +void UpdateContextProps(ALCcontext *context); + extern ALfloat ConeScale; extern ALfloat ZScale; extern ALboolean OverrideReverbSpeedOfSound; diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 5a12673d..a4471539 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -21,7 +21,7 @@ #include "config.h" #include "alMain.h" -#include "AL/alc.h" +#include "alu.h" #include "alError.h" #include "alListener.h" #include "alSource.h" @@ -45,8 +45,10 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) case AL_METERS_PER_UNIT: if(!(value >= AL_MIN_METERS_PER_UNIT && value <= AL_MAX_METERS_PER_UNIT)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - context->Listener->MetersPerUnit = value; - break; + context->MetersPerUnit = value; + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + UpdateContextProps(context); + goto done; default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); @@ -266,7 +268,7 @@ AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) break; case AL_METERS_PER_UNIT: - *value = context->Listener->MetersPerUnit; + *value = context->MetersPerUnit; break; default: @@ -489,14 +491,6 @@ void UpdateListenerProps(ALCcontext *context) props->Up[2] = listener->Up[2]; props->Gain = listener->Gain; - props->MetersPerUnit = listener->MetersPerUnit; - - props->DopplerFactor = context->DopplerFactor; - props->DopplerVelocity = context->DopplerVelocity; - props->SpeedOfSound = context->SpeedOfSound; - - props->SourceDistanceModel = context->SourceDistanceModel; - props->DistanceModel = context->DistanceModel;; /* Set the new container for updating internal parameters. */ props = ATOMIC_EXCHANGE_PTR(&listener->Update, props, almemory_order_acq_rel); diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 48c3498a..86534efb 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -72,7 +72,7 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); + UpdateContextProps(context); done: WriteUnlock(&context->PropLock); @@ -97,7 +97,7 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); + UpdateContextProps(context); done: WriteUnlock(&context->PropLock); @@ -648,7 +648,7 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) WriteLock(&context->PropLock); context->DopplerFactor = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); + UpdateContextProps(context); WriteUnlock(&context->PropLock); done: @@ -668,7 +668,7 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) WriteLock(&context->PropLock); context->DopplerVelocity = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); + UpdateContextProps(context); WriteUnlock(&context->PropLock); done: @@ -688,7 +688,7 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) WriteLock(&context->PropLock); context->SpeedOfSound = value; if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); + UpdateContextProps(context); WriteUnlock(&context->PropLock); done: @@ -713,7 +713,7 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) if(!context->SourceDistanceModel) { if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateListenerProps(context); + UpdateContextProps(context); } WriteUnlock(&context->PropLock); @@ -779,3 +779,42 @@ done: return value; } + + +void UpdateContextProps(ALCcontext *context) +{ + struct ALcontextProps *props; + + /* Get an unused proprty container, or allocate a new one as needed. */ + props = ATOMIC_LOAD(&context->FreeList, almemory_order_acquire); + if(!props) + props = al_calloc(16, sizeof(*props)); + else + { + struct ALcontextProps *next; + do { + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&context->FreeList, &props, next, + almemory_order_seq_cst, almemory_order_acquire) == 0); + } + + /* Copy in current property values. */ + props->MetersPerUnit = context->MetersPerUnit; + + props->DopplerFactor = context->DopplerFactor; + props->DopplerVelocity = context->DopplerVelocity; + props->SpeedOfSound = context->SpeedOfSound; + + props->SourceDistanceModel = context->SourceDistanceModel; + props->DistanceModel = context->DistanceModel; + + /* Set the new container for updating internal parameters. */ + props = ATOMIC_EXCHANGE_PTR(&context->Update, props, almemory_order_acq_rel); + if(props) + { + /* If there was an unused update container, put it back in the + * freelist. + */ + ATOMIC_REPLACE_HEAD(struct ALcontextProps*, &context->FreeList, props); + } +} |