From 14bc7baeb79f537cde9574934bee290908c43fb8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 17 Apr 2017 21:16:01 -0700 Subject: Store the source prop updates with the mixer voice Also move its declaration and rename it for consistency. --- OpenAL32/Include/alSource.h | 57 ------------------------------------- OpenAL32/Include/alu.h | 61 ++++++++++++++++++++++++++++++++++++++-- OpenAL32/alSource.c | 68 +++++++++++++++++---------------------------- 3 files changed, 84 insertions(+), 102 deletions(-) (limited to 'OpenAL32') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 5b1e2547..265a8f47 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -15,7 +15,6 @@ extern "C" { struct ALbuffer; struct ALsource; -struct ALsourceProps; typedef struct ALbufferlistitem { @@ -24,59 +23,6 @@ typedef struct ALbufferlistitem { } ALbufferlistitem; -struct ALsourceProps { - ATOMIC(struct ALsourceProps*) next; - - ALfloat Pitch; - ALfloat Gain; - ALfloat OuterGain; - ALfloat MinGain; - ALfloat MaxGain; - ALfloat InnerAngle; - ALfloat OuterAngle; - ALfloat RefDistance; - ALfloat MaxDistance; - ALfloat RollOffFactor; - ALfloat Position[3]; - ALfloat Velocity[3]; - ALfloat Direction[3]; - ALfloat Orientation[2][3]; - ALboolean HeadRelative; - enum DistanceModel DistanceModel; - ALboolean DirectChannels; - - ALboolean DryGainHFAuto; - ALboolean WetGainAuto; - ALboolean WetGainHFAuto; - ALfloat OuterGainHF; - - ALfloat AirAbsorptionFactor; - ALfloat RoomRolloffFactor; - ALfloat DopplerFactor; - - ALfloat StereoPan[2]; - - ALfloat Radius; - - /** Direct filter and auxiliary send info. */ - struct { - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - } Direct; - struct { - struct ALeffectslot *Slot; - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - } Send[]; -}; - - typedef struct ALsource { /** Source properties. */ ALfloat Pitch; @@ -151,9 +97,6 @@ typedef struct ALsource { ATOMIC_FLAG PropsClean; - ATOMIC(struct ALsourceProps*) Update; - ATOMIC(struct ALsourceProps*) FreeList; - /** Self ID */ ALuint id; } ALsource; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 6c3f3499..a2ba4fae 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -35,7 +35,6 @@ extern "C" { #endif struct ALsource; -struct ALsourceProps; struct ALbufferlistitem; struct ALvoice; struct ALeffectslot; @@ -153,13 +152,69 @@ typedef struct SendParams { } Gains; } SendParams; + +struct ALvoiceProps { + ATOMIC(struct ALvoiceProps*) next; + + ALfloat Pitch; + ALfloat Gain; + ALfloat OuterGain; + ALfloat MinGain; + ALfloat MaxGain; + ALfloat InnerAngle; + ALfloat OuterAngle; + ALfloat RefDistance; + ALfloat MaxDistance; + ALfloat RollOffFactor; + ALfloat Position[3]; + ALfloat Velocity[3]; + ALfloat Direction[3]; + ALfloat Orientation[2][3]; + ALboolean HeadRelative; + enum DistanceModel DistanceModel; + ALboolean DirectChannels; + + ALboolean DryGainHFAuto; + ALboolean WetGainAuto; + ALboolean WetGainHFAuto; + ALfloat OuterGainHF; + + ALfloat AirAbsorptionFactor; + ALfloat RoomRolloffFactor; + ALfloat DopplerFactor; + + ALfloat StereoPan[2]; + + ALfloat Radius; + + /** Direct filter and auxiliary send info. */ + struct { + ALfloat Gain; + ALfloat GainHF; + ALfloat HFReference; + ALfloat GainLF; + ALfloat LFReference; + } Direct; + struct { + struct ALeffectslot *Slot; + ALfloat Gain; + ALfloat GainHF; + ALfloat HFReference; + ALfloat GainLF; + ALfloat LFReference; + } Send[]; +}; + /* If not 'moving', gain targets are used directly without fading. */ #define VOICE_IS_MOVING (1<<0) #define VOICE_IS_HRTF (1<<1) #define VOICE_HAS_NFC (1<<2) typedef struct ALvoice { - struct ALsourceProps *Props; + struct ALvoiceProps *Props; + + ATOMIC(struct ALvoiceProps*) Update; + ATOMIC(struct ALvoiceProps*) FreeList; ATOMIC(struct ALsource*) Source; ATOMIC(bool) Playing; @@ -209,6 +264,8 @@ typedef struct ALvoice { } Send[]; } ALvoice; +void DeinitVoice(ALvoice *voice); + typedef const ALfloat* (*ResamplerFunc)(const InterpState *state, const ALfloat *restrict src, ALsizei frac, ALint increment, diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 040078df..dcf9821e 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -49,7 +49,7 @@ extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); static void InitSourceParams(ALsource *Source, ALsizei num_sends); static void DeinitSource(ALsource *source, ALsizei num_sends); -static void UpdateSourceProps(ALsource *source, ALsizei num_sends); +static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends); static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime); static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime); static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context); @@ -430,8 +430,10 @@ static ALint Int64ValsByProp(ALenum prop) } while(0) #define DO_UPDATEPROPS() do { \ - if(SourceShouldUpdate(Source, Context)) \ - UpdateSourceProps(Source, device->NumAuxSends); \ + ALvoice *voice; \ + if(SourceShouldUpdate(Source, Context) && \ + (voice=GetSourceVoice(Source, Context)) != NULL) \ + UpdateSourceProps(Source, voice, device->NumAuxSends); \ else \ ATOMIC_FLAG_CLEAR(&Source->PropsClean, almemory_order_release); \ } while(0) @@ -896,16 +898,20 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p if(slot != Source->Send[values[1]].Slot && IsPlayingOrPaused(Source)) { + ALvoice *voice; /* Add refcount on the new slot, and release the previous slot */ if(slot) IncrementRef(&slot->ref); if(Source->Send[values[1]].Slot) DecrementRef(&Source->Send[values[1]].Slot->ref); Source->Send[values[1]].Slot = slot; - /* We must force an update if the auxiliary slot changed on a - * playing source, in case the slot is about to be deleted. + /* We must force an update if the auxiliary slot changed on an + * active source, in case the slot is about to be deleted. */ - UpdateSourceProps(Source, device->NumAuxSends); + if((voice=GetSourceVoice(Source, Context)) != NULL) + UpdateSourceProps(Source, voice, device->NumAuxSends); + else + ATOMIC_FLAG_CLEAR(&Source->PropsClean, almemory_order_release); } else { @@ -2450,9 +2456,6 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) break; } - ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acquire); - UpdateSourceProps(source, device->NumAuxSends); - /* Make sure this source isn't already active, and if not, look for an * unused voice to put it in. */ @@ -2468,7 +2471,9 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) if(voice == NULL) voice = context->Voices[context->VoiceCount++]; ATOMIC_STORE(&voice->Playing, false, almemory_order_release); - ATOMIC_THREAD_FENCE(almemory_order_acquire); + + ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acquire); + UpdateSourceProps(source, voice, device->NumAuxSends); /* A source that's not playing or paused has any offset applied when it * starts playing. @@ -2973,36 +2978,13 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) * ignore the test. */ ATOMIC_FLAG_TEST_AND_SET(&Source->PropsClean, almemory_order_relaxed); - - ATOMIC_INIT(&Source->Update, NULL); - ATOMIC_INIT(&Source->FreeList, NULL); } static void DeinitSource(ALsource *source, ALsizei num_sends) { ALbufferlistitem *BufferList; - struct ALsourceProps *props; - size_t count = 0; ALsizei i; - props = ATOMIC_LOAD_SEQ(&source->Update); - if(props) al_free(props); - - props = ATOMIC_LOAD(&source->FreeList, almemory_order_relaxed); - while(props) - { - struct ALsourceProps *next; - next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - al_free(props); - props = next; - ++count; - } - /* This is excessively spammy if it traces every source destruction, so - * just warn if it was unexpectedly large. - */ - if(count > 3) - WARN("Freed "SZFMT" Source property objects\n", count); - BufferList = ATOMIC_EXCHANGE_PTR_SEQ(&source->queue, NULL); while(BufferList != NULL) { @@ -3026,21 +3008,21 @@ static void DeinitSource(ALsource *source, ALsizei num_sends) } } -static void UpdateSourceProps(ALsource *source, ALsizei num_sends) +static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_sends) { - struct ALsourceProps *props; + struct ALvoiceProps *props; ALsizei i; /* Get an unused property container, or allocate a new one as needed. */ - props = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire); + props = ATOMIC_LOAD(&voice->FreeList, almemory_order_acquire); if(!props) - props = al_calloc(16, offsetof(struct ALsourceProps, Send[num_sends])); + props = al_calloc(16, offsetof(struct ALvoiceProps, Send[num_sends])); else { - struct ALsourceProps *next; + struct ALvoiceProps *next; do { next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&source->FreeList, &props, next, + } while(ATOMIC_COMPARE_EXCHANGE_PTR_WEAK(&voice->FreeList, &props, next, almemory_order_acq_rel, almemory_order_acquire) == 0); } @@ -3102,13 +3084,13 @@ static void UpdateSourceProps(ALsource *source, ALsizei num_sends) } /* Set the new container for updating internal parameters. */ - props = ATOMIC_EXCHANGE_PTR(&source->Update, props, almemory_order_acq_rel); + props = ATOMIC_EXCHANGE_PTR(&voice->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 ALsourceProps*, &source->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props); } } @@ -3121,8 +3103,8 @@ void UpdateAllSourceProps(ALCcontext *context) { ALvoice *voice = context->Voices[pos]; ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire); - if(source != NULL && !ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acq_rel)) - UpdateSourceProps(source, num_sends); + if(source && !ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acq_rel)) + UpdateSourceProps(source, voice, num_sends); } } -- cgit v1.2.3