From d69dd6dc7aa50fa3bd77338065b381b57be05acd Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Jan 2016 00:42:58 -0800 Subject: Make the source's buffer queue a singly-linked list --- OpenAL32/Include/alSource.h | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 13596161..253cd05f 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -18,7 +18,6 @@ struct ALsource; typedef struct ALbufferlistitem { struct ALbuffer *buffer; struct ALbufferlistitem *volatile next; - struct ALbufferlistitem *volatile prev; } ALbufferlistitem; -- cgit v1.2.3 From 25732d0895cc4d320472fc50cd74302d91b24a0c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 14 Feb 2016 01:22:01 -0800 Subject: Calculate channel gain stepping just before mixing --- Alc/ALc.c | 8 -- Alc/ALu.c | 282 +++++++++----------------------------------- Alc/mixer.c | 99 ++++++++++++++-- OpenAL32/Include/alSource.h | 3 + OpenAL32/Include/alu.h | 20 ++-- OpenAL32/alSource.c | 9 +- 6 files changed, 165 insertions(+), 256 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index f69f6ecc..d116650f 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2155,14 +2155,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALvoice *voice = &context->Voices[pos]; ALsource *source = voice->Source; - ALuint s = device->NumAuxSends; - - while(s < MAX_SENDS) - { - voice->Send[s].Moving = AL_FALSE; - voice->Send[s].Counter = 0; - s++; - } if(source) { diff --git a/Alc/ALu.c b/Alc/ALu.c index e0c96175..4b1f0164 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -323,85 +323,6 @@ static ALfloat CalcFadeTime(ALfloat oldGain, ALfloat newGain, const aluVector *o } -static void UpdateDryStepping(DirectParams *params, ALuint num_chans, ALuint steps) -{ - ALfloat delta; - ALuint i, j; - - if(steps < 2) - { - for(i = 0;i < num_chans;i++) - { - MixGains *gains = params->Gains[i]; - for(j = 0;j < params->OutChannels;j++) - { - gains[j].Current = gains[j].Target; - gains[j].Step = 0.0f; - } - } - params->Counter = 0; - return; - } - - delta = 1.0f / (ALfloat)steps; - for(i = 0;i < num_chans;i++) - { - MixGains *gains = params->Gains[i]; - for(j = 0;j < params->OutChannels;j++) - { - ALfloat diff = gains[j].Target - gains[j].Current; - if(fabsf(diff) >= GAIN_SILENCE_THRESHOLD) - gains[j].Step = diff * delta; - else - { - gains[j].Current = gains[j].Target; - gains[j].Step = 0.0f; - } - } - } - params->Counter = steps; -} - -static void UpdateWetStepping(SendParams *params, ALuint num_chans, ALuint steps) -{ - ALfloat delta; - ALuint i, j; - - if(steps < 2) - { - for(i = 0;i < num_chans;i++) - { - MixGains *gains = params->Gains[i]; - for(j = 0;j < params->OutChannels;j++) - { - gains[j].Current = gains[j].Target; - gains[j].Step = 0.0f; - } - } - params->Counter = 0; - return; - } - - delta = 1.0f / (ALfloat)steps; - for(i = 0;i < num_chans;i++) - { - MixGains *gains = params->Gains[i]; - for(j = 0;j < params->OutChannels;j++) - { - ALfloat diff = gains[j].Target - gains[j].Current; - if(fabsf(diff) >= GAIN_SILENCE_THRESHOLD) - gains[j].Step = diff * delta; - else - { - gains[j].Current = gains[j].Target; - gains[j].Step = 0.0f; - } - } - } - params->Counter = steps; -} - - static ALvoid CalcListenerParams(ALlistener *Listener) { ALdouble N[3], V[3], U[3], P[3]; @@ -659,16 +580,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A ); for(c = 0;c < num_channels;c++) - { - MixGains *gains = voice->Direct.Gains[c]; - ALfloat Target[MAX_OUTPUT_CHANNELS]; - - ComputeFirstOrderGains(Device->AmbiCoeffs, Device->NumChannels, matrix.m[c], DryGain, Target); - for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) - gains[i].Target = Target[i]; - } - UpdateDryStepping(&voice->Direct, num_channels, (voice->Direct.Moving ? 64 : 0)); - voice->Direct.Moving = AL_TRUE; + ComputeFirstOrderGains(Device->AmbiCoeffs, Device->NumChannels, matrix.m[c], DryGain, + voice->Direct.Gains[c].Target); /* Rebuild the matrix, without the second- or third-order output * scaling (effects take first-order content, and will do the scaling @@ -684,9 +597,8 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A { for(c = 0;c < num_channels;c++) { - MixGains *gains = voice->Send[i].Gains[c]; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Send[i].Gains[c].Target[j] = 0.0f; } } else @@ -694,24 +606,18 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A for(c = 0;c < num_channels;c++) { const ALeffectslot *Slot = SendSlots[i]; - MixGains *gains = voice->Send[i].Gains[c]; - ALfloat Target[MAX_OUTPUT_CHANNELS]; - ALuint j; - - ComputeFirstOrderGains(Slot->AmbiCoeffs, Slot->NumChannels, - matrix.m[c], WetGain[i], Target); - for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = Target[j]; + ComputeFirstOrderGains(Slot->AmbiCoeffs, Slot->NumChannels, matrix.m[c], + WetGain[i], voice->Send[i].Gains[c].Target); } } - UpdateWetStepping(&voice->Send[i], num_channels, (voice->Send[i].Moving ? 64 : 0)); - voice->Send[i].Moving = AL_TRUE; } voice->IsHrtf = AL_FALSE; } else { + ALfloat coeffs[MAX_AMBI_COEFFS]; + if(DirectChannels) { if(Device->Hrtf) @@ -724,65 +630,46 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A voice->Direct.OutChannels = 2; for(c = 0;c < num_channels;c++) { - MixGains *gains = voice->Direct.Gains[c]; for(j = 0;j < MAX_OUTPUT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Direct.Gains[c].Target[j] = 0.0f; if(chans[c].channel == FrontLeft) - gains[0].Target = DryGain; + voice->Direct.Gains[c].Target[0] = DryGain; else if(chans[c].channel == FrontRight) - gains[1].Target = DryGain; + voice->Direct.Gains[c].Target[1] = DryGain; } } else for(c = 0;c < num_channels;c++) { - MixGains *gains = voice->Direct.Gains[c]; int idx; - for(j = 0;j < MAX_OUTPUT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Direct.Gains[c].Target[j] = 0.0f; if((idx=GetChannelIdxByName(Device, chans[c].channel)) != -1) - gains[idx].Target = DryGain; + voice->Direct.Gains[c].Target[idx] = DryGain; } /* Auxiliary sends still use normal panning since they mix to B-Format, which can't * channel-match. */ for(c = 0;c < num_channels;c++) { - ALfloat coeffs[MAX_AMBI_COEFFS]; - CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs); for(i = 0;i < NumSends;i++) { - MixGains *gains = voice->Send[i].Gains[c]; if(!SendSlots[i]) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Send[i].Gains[c].Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ALfloat Target[MAX_OUTPUT_CHANNELS]; - ALuint j; - - ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, - coeffs, WetGain[i], Target); - for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = Target[j]; + ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, coeffs, + WetGain[i], voice->Send[i].Gains[c].Target); } } } - UpdateDryStepping(&voice->Direct, num_channels, (voice->Direct.Moving ? 64 : 0)); - voice->Direct.Moving = AL_TRUE; - for(i = 0;i < NumSends;i++) - { - UpdateWetStepping(&voice->Send[i], num_channels, (voice->Send[i].Moving ? 64 : 0)); - voice->Send[i].Moving = AL_TRUE; - } - voice->IsHrtf = AL_FALSE; } else if(Device->Hrtf_Mode == FullHrtf) @@ -804,54 +691,42 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A voice->Direct.Hrtf[c].Params.Coeffs[i][0] = 0.0f; voice->Direct.Hrtf[c].Params.Coeffs[i][1] = 0.0f; } + + for(i = 0;i < NumSends;i++) + { + for(j = 0;j < MAX_EFFECT_CHANNELS;j++) + voice->Send[i].Gains[c].Target[j] = 0.0f; + } + + continue; } - else - { - /* Get the static HRIR coefficients and delays for this - * channel. */ - GetLerpedHrtfCoeffs(Device->Hrtf, - chans[c].elevation, chans[c].angle, 1.0f, DryGain, - voice->Direct.Hrtf[c].Params.Coeffs, - voice->Direct.Hrtf[c].Params.Delay - ); - } - } - voice->Direct.Counter = 0; - voice->Direct.Moving = AL_TRUE; - /* Normal panning for auxiliary sends. */ - for(c = 0;c < num_channels;c++) - { - ALfloat coeffs[MAX_AMBI_COEFFS]; + /* Get the static HRIR coefficients and delays for this channel. */ + GetLerpedHrtfCoeffs(Device->Hrtf, + chans[c].elevation, chans[c].angle, 1.0f, DryGain, + voice->Direct.Hrtf[c].Params.Coeffs, + voice->Direct.Hrtf[c].Params.Delay + ); + /* Normal panning for auxiliary sends. */ CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs); for(i = 0;i < NumSends;i++) { - MixGains *gains = voice->Send[i].Gains[c]; if(!SendSlots[i]) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Send[i].Gains[c].Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ALfloat Target[MAX_OUTPUT_CHANNELS]; - ALuint j; - - ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, - coeffs, WetGain[i], Target); - for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = Target[j]; + ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, coeffs, + WetGain[i], voice->Send[i].Gains[c].Target); } } } - for(i = 0;i < NumSends;i++) - { - UpdateWetStepping(&voice->Send[i], num_channels, (voice->Send[i].Moving ? 64 : 0)); - voice->Send[i].Moving = AL_TRUE; - } + voice->Direct.HrtfCounter = 0; voice->IsHrtf = AL_TRUE; } @@ -860,64 +735,45 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A /* Basic or no HRTF rendering. Use normal panning to the output. */ for(c = 0;c < num_channels;c++) { - MixGains *gains = voice->Direct.Gains[c]; - ALfloat Target[MAX_OUTPUT_CHANNELS]; - ALfloat coeffs[MAX_AMBI_COEFFS]; - /* Special-case LFE */ if(chans[c].channel == LFE) { int idx; - for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) - gains[i].Target = 0.0f; + for(j = 0;j < MAX_OUTPUT_CHANNELS;j++) + voice->Direct.Gains[c].Target[j] = 0.0f; if((idx=GetChannelIdxByName(Device, chans[c].channel)) != -1) - gains[idx].Target = DryGain; + voice->Direct.Gains[c].Target[idx] = DryGain; for(i = 0;i < NumSends;i++) { - MixGains *gains = voice->Send[i].Gains[c]; ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Send[i].Gains[c].Target[j] = 0.0f; } continue; } CalcAngleCoeffs(chans[c].angle, chans[c].elevation, coeffs); - ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, DryGain, Target); - for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) - gains[i].Target = Target[i]; + ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, DryGain, voice->Direct.Gains[c].Target); for(i = 0;i < NumSends;i++) { - MixGains *gains = voice->Send[i].Gains[c]; - ALuint j; - if(!SendSlots[i]) { + ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Send[i].Gains[c].Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, - coeffs, WetGain[i], Target); - for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = Target[j]; + ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, coeffs, + WetGain[i], voice->Send[i].Gains[c].Target); } } } - UpdateDryStepping(&voice->Direct, num_channels, (voice->Direct.Moving ? 64 : 0)); - voice->Direct.Moving = AL_TRUE; - for(i = 0;i < NumSends;i++) - { - UpdateWetStepping(&voice->Send[i], num_channels, (voice->Send[i].Moving ? 64 : 0)); - voice->Send[i].Moving = AL_TRUE; - } - voice->IsHrtf = AL_FALSE; } } @@ -995,7 +851,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte ALfloat Pitch; ALuint Frequency; ALint NumSends; - ALint i, j; + ALint i; DryGainHF = 1.0f; DryGainLF = 1.0f; @@ -1304,7 +1160,6 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte ALfloat ev = 0.0f, az = 0.0f; ALfloat radius = ALSource->Radius; ALfloat dirfact = 1.0f; - ALfloat Target[MAX_OUTPUT_CHANNELS]; ALfloat coeffs[MAX_AMBI_COEFFS]; voice->Direct.OutBuffer += voice->Direct.OutChannels; @@ -1332,7 +1187,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte } /* Check to see if the HRIR is already moving. */ - if(voice->Direct.Moving) + if(voice->Moving) { ALfloat delta; delta = CalcFadeTime(voice->Direct.LastGain, DryGain, @@ -1343,11 +1198,11 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte if(delta > 0.000015f) { ALuint counter = GetMovingHrtfCoeffs(Device->Hrtf, - ev, az, dirfact, DryGain, delta, voice->Direct.Counter, + ev, az, dirfact, DryGain, delta, voice->Direct.HrtfCounter, voice->Direct.Hrtf[0].Params.Coeffs, voice->Direct.Hrtf[0].Params.Delay, voice->Direct.Hrtf[0].Params.CoeffStep, voice->Direct.Hrtf[0].Params.DelayStep ); - voice->Direct.Counter = counter; + voice->Direct.HrtfCounter = counter; voice->Direct.LastGain = DryGain; voice->Direct.LastDir = dir; } @@ -1358,8 +1213,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, dirfact, DryGain, voice->Direct.Hrtf[0].Params.Coeffs, voice->Direct.Hrtf[0].Params.Delay); - voice->Direct.Counter = 0; - voice->Direct.Moving = AL_TRUE; + voice->Direct.HrtfCounter = 0; voice->Direct.LastGain = DryGain; voice->Direct.LastDir = dir; } @@ -1371,25 +1225,18 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte for(i = 0;i < NumSends;i++) { - MixGains *gains = voice->Send[i].Gains[0]; - ALuint j; - if(!SendSlots[i]) { + ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Send[i].Gains[0].Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, - coeffs, WetGain[i], Target); - for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = Target[j]; + ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, coeffs, + WetGain[i], voice->Send[i].Gains[0].Target); } - - UpdateWetStepping(&voice->Send[i], 1, (voice->Send[i].Moving ? 64 : 0)); - voice->Send[i].Moving = AL_TRUE; } voice->IsHrtf = AL_TRUE; @@ -1397,10 +1244,8 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte else { /* Basic or no HRTF rendering. Use normal panning to the output. */ - MixGains *gains = voice->Direct.Gains[0]; ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; ALfloat radius = ALSource->Radius; - ALfloat Target[MAX_OUTPUT_CHANNELS]; ALfloat coeffs[MAX_AMBI_COEFFS]; /* Get the localized direction, and compute panned gains. */ @@ -1423,34 +1268,23 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte } CalcDirectionCoeffs(dir, coeffs); - ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, DryGain, Target); - for(j = 0;j < MAX_OUTPUT_CHANNELS;j++) - gains[j].Target = Target[j]; - - UpdateDryStepping(&voice->Direct, 1, (voice->Direct.Moving ? 64 : 0)); - voice->Direct.Moving = AL_TRUE; + ComputePanningGains(Device->AmbiCoeffs, Device->NumChannels, coeffs, DryGain, + voice->Direct.Gains[0].Target); for(i = 0;i < NumSends;i++) { - MixGains *gains = voice->Send[i].Gains[0]; - ALuint j; - if(!SendSlots[i]) { + ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = 0.0f; + voice->Send[i].Gains[0].Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, - coeffs, WetGain[i], Target); - for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - gains[j].Target = Target[j]; + ComputePanningGains(Slot->AmbiCoeffs, Slot->NumChannels, coeffs, + WetGain[i], voice->Send[i].Gains[0].Target); } - - UpdateWetStepping(&voice->Send[i], 1, (voice->Send[i].Moving ? 64 : 0)); - voice->Send[i].Moving = AL_TRUE; } voice->IsHrtf = AL_FALSE; diff --git a/Alc/mixer.c b/Alc/mixer.c index ddcf6f6b..4688c89e 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -401,6 +401,19 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam OutPos = 0; do { ALuint SrcBufferSize, DstBufferSize; + ALuint Counter; + ALfloat Delta; + + if(!voice->Moving) + { + Counter = 0; + Delta = 0.0f; + } + else + { + Counter = SamplesToDo - OutPos; + Delta = 1.0f / (ALfloat)Counter; + } /* Figure out how many buffer samples will be needed */ DataSize64 = SamplesToDo-OutPos; @@ -549,10 +562,46 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam parms->Filters[chan].ActiveType ); if(!voice->IsHrtf) - MixSamples(samples, parms->OutChannels, parms->OutBuffer, parms->Gains[chan], - parms->Counter, OutPos, DstBufferSize); + { + ALfloat *restrict currents = parms->Gains[chan].Current; + const ALfloat *targets = parms->Gains[chan].Target; + MixGains gains[MAX_OUTPUT_CHANNELS]; + + if(!Counter) + { + for(j = 0;j < parms->OutChannels;j++) + { + gains[j].Target = targets[j]; + gains[j].Current = gains[j].Target; + gains[j].Step = 0.0f; + } + } + else + { + for(j = 0;j < parms->OutChannels;j++) + { + ALfloat diff; + gains[j].Target = targets[j]; + gains[j].Current = currents[j]; + diff = gains[j].Target - gains[j].Current; + if(fabsf(diff) >= GAIN_SILENCE_THRESHOLD) + gains[j].Step = diff * Delta; + else + { + gains[j].Current = gains[j].Target; + gains[j].Step = 0.0f; + } + } + } + + MixSamples(samples, parms->OutChannels, parms->OutBuffer, gains, + Counter, OutPos, DstBufferSize); + + for(j = 0;j < parms->OutChannels;j++) + currents[j] = gains[j].Current; + } else - MixHrtfSamples(parms->OutBuffer, samples, parms->Counter, voice->Offset, + MixHrtfSamples(parms->OutBuffer, samples, parms->HrtfCounter, voice->Offset, OutPos, IrSize, &parms->Hrtf[chan].Params, &parms->Hrtf[chan].State, DstBufferSize); } @@ -560,6 +609,9 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam for(j = 0;j < Device->NumAuxSends;j++) { SendParams *parms = &voice->Send[j]; + ALfloat *restrict currents = parms->Gains[chan].Current; + const ALfloat *targets = parms->Gains[chan].Target; + MixGains gains[MAX_OUTPUT_CHANNELS]; const ALfloat *samples; if(!parms->OutBuffer) @@ -570,8 +622,39 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam Device->FilteredData, ResampledData, DstBufferSize, parms->Filters[chan].ActiveType ); - MixSamples(samples, parms->OutChannels, parms->OutBuffer, parms->Gains[chan], - parms->Counter, OutPos, DstBufferSize); + + if(!Counter) + { + for(j = 0;j < parms->OutChannels;j++) + { + gains[j].Target = targets[j]; + gains[j].Current = gains[j].Target; + gains[j].Step = 0.0f; + } + } + else + { + for(j = 0;j < parms->OutChannels;j++) + { + ALfloat diff; + gains[j].Target = targets[j]; + gains[j].Current = currents[j]; + diff = gains[j].Target - gains[j].Current; + if(fabsf(diff) >= GAIN_SILENCE_THRESHOLD) + gains[j].Step = diff * Delta; + else + { + gains[j].Current = gains[j].Target; + gains[j].Step = 0.0f; + } + } + } + + MixSamples(samples, parms->OutChannels, parms->OutBuffer, gains, + Counter, OutPos, DstBufferSize); + + for(j = 0;j < parms->OutChannels;j++) + currents[j] = gains[j].Current; } } /* Update positions */ @@ -581,9 +664,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam OutPos += DstBufferSize; voice->Offset += DstBufferSize; - voice->Direct.Counter = maxu(voice->Direct.Counter, DstBufferSize) - DstBufferSize; - for(j = 0;j < Device->NumAuxSends;j++) - voice->Send[j].Counter = maxu(voice->Send[j].Counter, DstBufferSize) - DstBufferSize; + voice->Direct.HrtfCounter = maxu(voice->Direct.HrtfCounter, DstBufferSize) - DstBufferSize; /* Handle looping sources */ while(1) @@ -630,6 +711,8 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } } while(State == AL_PLAYING && OutPos < SamplesToDo); + voice->Moving = AL_TRUE; + /* Update source info */ Source->state = State; ATOMIC_STORE(&Source->current_buffer, BufferListItem); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 253cd05f..bf589e8d 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -30,6 +30,9 @@ typedef struct ALvoice { /** Current target parameters used for mixing. */ ALint Step; + /* If not 'moving', gain/coefficients are set directly without fading. */ + ALboolean Moving; + ALboolean IsHrtf; ALuint Offset; /* Number of output samples mixed since starting. */ diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index eb2ea534..50ef1f5e 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -143,13 +143,10 @@ typedef struct DirectParams { ALfloat (*OutBuffer)[BUFFERSIZE]; ALuint OutChannels; - /* If not 'moving', gain/coefficients are set directly without fading. */ - ALboolean Moving; - /* Stepping counter for gain/coefficient fading. */ - ALuint Counter; /* Last direction (relative to listener) and gain of a moving source. */ aluVector LastDir; ALfloat LastGain; + ALuint HrtfCounter; struct { enum ActiveFilters ActiveType; @@ -161,22 +158,27 @@ typedef struct DirectParams { HrtfParams Params; HrtfState State; } Hrtf[MAX_INPUT_CHANNELS]; - MixGains Gains[MAX_INPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; + + struct { + ALfloat Current[MAX_OUTPUT_CHANNELS]; + ALfloat Target[MAX_OUTPUT_CHANNELS]; + } Gains[MAX_INPUT_CHANNELS]; } DirectParams; typedef struct SendParams { ALfloat (*OutBuffer)[BUFFERSIZE]; ALuint OutChannels; - ALboolean Moving; - ALuint Counter; - struct { enum ActiveFilters ActiveType; ALfilterState LowPass; ALfilterState HighPass; } Filters[MAX_INPUT_CHANNELS]; - MixGains Gains[MAX_INPUT_CHANNELS][MAX_EFFECT_CHANNELS]; + + struct { + ALfloat Current[MAX_OUTPUT_CHANNELS]; + ALfloat Target[MAX_OUTPUT_CHANNELS]; + } Gains[MAX_INPUT_CHANNELS]; } SendParams; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index d31a0377..f742e1fe 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2640,8 +2640,8 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(discontinuity) memset(voice->PrevSamples, 0, sizeof(voice->PrevSamples)); - voice->Direct.Moving = AL_FALSE; - voice->Direct.Counter = 0; + voice->Moving = AL_FALSE; + voice->Direct.HrtfCounter = 0; for(i = 0;i < MAX_INPUT_CHANNELS;i++) { ALsizei j; @@ -2653,11 +2653,6 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) voice->Direct.Hrtf[i].State.Values[j][1] = 0.0f; } } - for(i = 0;i < (ALsizei)device->NumAuxSends;i++) - { - voice->Send[i].Moving = AL_FALSE; - voice->Send[i].Counter = 0; - } if(BufferList->buffer->FmtChannels == FmtMono) voice->Update = CalcSourceParams; -- cgit v1.2.3 From 31489861847dcb15a2f21ffb70d98f9da6051c8f Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 25 Mar 2016 14:40:44 -0700 Subject: Implement AL_EXT_STEREO_ANGLES support --- Alc/ALc.c | 10 ++++++---- Alc/ALu.c | 11 ++++++++--- OpenAL32/Include/alSource.h | 5 +++++ OpenAL32/alSource.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 7 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 7c3afa0c..e6c37546 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -523,6 +523,8 @@ static const ALCenums enumeration[] = { DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT), DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT), + DECL(AL_STEREO_ANGLES), + DECL(AL_UNUSED), DECL(AL_PENDING), DECL(AL_PROCESSED), @@ -712,10 +714,10 @@ static const ALchar alExtList[] = "AL_EXT_ALAW AL_EXT_BFORMAT AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE " "AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS " "AL_EXT_MULAW AL_EXT_MULAW_BFORMAT AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET " - "AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_block_alignment " - "AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates " - "AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_MSADPCM " - "AL_SOFT_source_latency AL_SOFT_source_length"; + "AL_EXT_source_distance_model AL_EXT_STEREO_ANGLES AL_LOKI_quadriphonic " + "AL_SOFT_block_alignment AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data " + "AL_SOFT_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points " + "AL_SOFT_MSADPCM AL_SOFT_source_latency AL_SOFT_source_length"; static ATOMIC(ALCenum) LastNullDeviceError = ATOMIC_INIT_STATIC(ALC_NO_ERROR); diff --git a/Alc/ALu.c b/Alc/ALu.c index cdb75e6a..b5791f53 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -303,9 +303,6 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A { static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f, 0.0f } - }, StereoMap[2] = { - { FrontLeft, DEG2RAD(-30.0f), DEG2RAD(0.0f) }, - { FrontRight, DEG2RAD( 30.0f), DEG2RAD(0.0f) } }, RearMap[2] = { { BackLeft, DEG2RAD(-150.0f), DEG2RAD(0.0f) }, { BackRight, DEG2RAD( 150.0f), DEG2RAD(0.0f) } @@ -352,6 +349,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A ALuint NumSends, Frequency; ALboolean Relative; const struct ChanMap *chans = NULL; + struct ChanMap StereoMap[2] = { + { FrontLeft, DEG2RAD(-30.0f), DEG2RAD(0.0f) }, + { FrontRight, DEG2RAD( 30.0f), DEG2RAD(0.0f) } + }; ALuint num_channels = 0; ALboolean DirectChannels; ALboolean isbformat = AL_FALSE; @@ -373,6 +374,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A Relative = ALSource->HeadRelative; DirectChannels = ALSource->DirectChannels; + /* Convert counter-clockwise to clockwise. */ + StereoMap[0].angle = -ALSource->StereoPan[0]; + StereoMap[1].angle = -ALSource->StereoPan[1]; + voice->Direct.OutBuffer = Device->Dry.Buffer; voice->Direct.OutChannels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index bf589e8d..b7c08fcd 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -76,6 +76,11 @@ typedef struct ALsource { volatile ALfloat RoomRolloffFactor; volatile ALfloat DopplerFactor; + /* NOTE: Stereo pan angles are specified in radians, counter-clockwise + * rather than clockwise. + */ + volatile ALfloat StereoPan[2]; + volatile ALfloat Radius; /** diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 250c9d1e..d7b68185 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -104,6 +104,9 @@ typedef enum SourceProp { srcSampleOffsetLatencySOFT = AL_SAMPLE_OFFSET_LATENCY_SOFT, srcSecOffsetLatencySOFT = AL_SEC_OFFSET_LATENCY_SOFT, + /* AL_EXT_STEREO_ANGLES */ + srcAngles = AL_STEREO_ANGLES, + /* AL_EXT_BFORMAT */ srcOrientation = AL_ORIENTATION, } SourceProp; @@ -157,6 +160,7 @@ static ALint FloatValsByProp(ALenum prop) case AL_SAMPLE_RW_OFFSETS_SOFT: case AL_BYTE_RW_OFFSETS_SOFT: + case AL_STEREO_ANGLES: return 2; case AL_POSITION: @@ -221,6 +225,7 @@ static ALint DoubleValsByProp(ALenum prop) case AL_SAMPLE_RW_OFFSETS_SOFT: case AL_BYTE_RW_OFFSETS_SOFT: case AL_SEC_OFFSET_LATENCY_SOFT: + case AL_STEREO_ANGLES: return 2; case AL_POSITION: @@ -299,6 +304,8 @@ static ALint IntValsByProp(ALenum prop) break; /* i64 only */ case AL_SEC_OFFSET_LATENCY_SOFT: break; /* Double only */ + case AL_STEREO_ANGLES: + break; /* Float/double only */ } return 0; } @@ -359,6 +366,8 @@ static ALint Int64ValsByProp(ALenum prop) case AL_SEC_OFFSET_LATENCY_SOFT: break; /* Double only */ + case AL_STEREO_ANGLES: + break; /* Float/double only */ } return 0; } @@ -507,6 +516,17 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; + case AL_STEREO_ANGLES: + CHECKVAL(isfinite(values[0]) && isfinite(values[1])); + + LockContext(Context); + Source->StereoPan[0] = values[0]; + Source->StereoPan[1] = values[1]; + UnlockContext(Context); + ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + return AL_TRUE; + + case AL_POSITION: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); @@ -830,6 +850,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SAMPLE_OFFSET_LATENCY_SOFT: case AL_SEC_OFFSET_LATENCY_SOFT: + case AL_STEREO_ANGLES: break; } @@ -931,6 +952,7 @@ static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp return SetSourcefv(Source, Context, (int)prop, fvals); case AL_SEC_OFFSET_LATENCY_SOFT: + case AL_STEREO_ANGLES: break; } @@ -1054,6 +1076,13 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p UnlockContext(Context); return AL_TRUE; + case AL_STEREO_ANGLES: + LockContext(Context); + values[0] = Source->StereoPan[0]; + values[1] = Source->StereoPan[1]; + UnlockContext(Context); + return AL_TRUE; + case AL_POSITION: LockContext(Context); values[0] = Source->Position.v[0]; @@ -1325,6 +1354,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p break; /* i64 only */ case AL_SEC_OFFSET_LATENCY_SOFT: break; /* Double only */ + case AL_STEREO_ANGLES: + break; /* Float/double only */ case AL_DIRECT_FILTER: case AL_AUXILIARY_SEND_FILTER: @@ -1446,6 +1477,8 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp case AL_SEC_OFFSET_LATENCY_SOFT: break; /* Double only */ + case AL_STEREO_ANGLES: + break; /* Float/double only */ } ERR("Unexpected property: 0x%04x\n", prop); @@ -2530,6 +2563,9 @@ static ALvoid InitSourceParams(ALsource *Source) Source->DopplerFactor = 1.0f; Source->DirectChannels = AL_FALSE; + Source->StereoPan[0] = DEG2RAD( 30.0f); + Source->StereoPan[1] = DEG2RAD(-30.0f); + Source->Radius = 0.0f; Source->DistanceModel = DefaultDistanceModel; -- cgit v1.2.3 From 182c0cb61abaff36554653d6a94c8a66fc263411 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 9 May 2016 14:22:26 -0700 Subject: Find a valid source buffer before updating the voice --- Alc/ALc.c | 17 +++++++-- Alc/ALu.c | 92 ++++++++++++++++++++++----------------------- OpenAL32/Include/alSource.h | 2 +- OpenAL32/Include/alu.h | 5 ++- 4 files changed, 63 insertions(+), 53 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index d083825b..f8eda9a5 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2106,11 +2106,22 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALvoice *voice = &context->Voices[pos]; ALsource *source = voice->Source; + ALbufferlistitem *BufferListItem; - if(source) + if(!source) + continue; + + BufferListItem = ATOMIC_LOAD(&source->queue); + while(BufferListItem != NULL) { - ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE); - voice->Update(voice, source, context); + ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE); + voice->Update(voice, source, buffer, context); + break; + } + BufferListItem = BufferListItem->next; } } diff --git a/Alc/ALu.c b/Alc/ALu.c index 4786c785..709b7127 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -306,7 +306,7 @@ static ALvoid CalcListenerParams(ALCcontext *Context) Listener->Params.SpeedOfSound = Context->SpeedOfSound * Context->DopplerVelocity; } -ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCcontext *ALContext) +ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f, 0.0f } @@ -347,8 +347,6 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A const ALCdevice *Device = ALContext->Device; const ALlistener *Listener = ALContext->Listener; ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume; - ALbufferlistitem *BufferListItem; - enum FmtChannels Channels; ALfloat DryGain, DryGainHF, DryGainLF; ALfloat WetGain[MAX_SENDS]; ALfloat WetGainHF[MAX_SENDS]; @@ -407,25 +405,12 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } /* Calculate the stepping value */ - Channels = FmtMono; - BufferListItem = ATOMIC_LOAD(&ALSource->queue); - while(BufferListItem != NULL) - { - ALbuffer *ALBuffer; - if((ALBuffer=BufferListItem->buffer) != NULL) - { - Pitch = Pitch * ALBuffer->Frequency / Frequency; - if(Pitch > (ALfloat)MAX_PITCH) - voice->Step = MAX_PITCH<Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1); - BsincPrepare(voice->Step, &voice->SincState); - - Channels = ALBuffer->FmtChannels; - break; - } - BufferListItem = BufferListItem->next; - } + Pitch *= (ALfloat)ALBuffer->Frequency / Frequency; + if(Pitch > (ALfloat)MAX_PITCH) + voice->Step = MAX_PITCH<Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1); + BsincPrepare(voice->Step, &voice->SincState); /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); @@ -440,7 +425,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A WetGainLF[i] = ALSource->Send[i].GainLF; } - switch(Channels) + switch(ALBuffer->FmtChannels) { case FmtMono: chans = MonoMap; @@ -761,7 +746,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } } -ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCcontext *ALContext) +ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { const ALCdevice *Device = ALContext->Device; const ALlistener *Listener = ALContext->Listener; @@ -772,7 +757,6 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte ALfloat DopplerFactor, SpeedOfSound; ALfloat AirAbsorptionFactor; ALfloat RoomAirAbsorption[MAX_SENDS]; - ALbufferlistitem *BufferListItem; ALeffectslot *SendSlots[MAX_SENDS]; ALfloat Attenuation; ALfloat RoomAttenuation[MAX_SENDS]; @@ -1072,25 +1056,15 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALCconte clampf(SpeedOfSound-VSS, 1.0f, SpeedOfSound*2.0f - 1.0f); } - BufferListItem = ATOMIC_LOAD(&ALSource->queue); - while(BufferListItem != NULL) - { - ALbuffer *ALBuffer; - if((ALBuffer=BufferListItem->buffer) != NULL) - { - /* Calculate fixed-point stepping value, based on the pitch, buffer - * frequency, and output frequency. */ - Pitch = Pitch * ALBuffer->Frequency / Frequency; - if(Pitch > (ALfloat)MAX_PITCH) - voice->Step = MAX_PITCH<Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1); - BsincPrepare(voice->Step, &voice->SincState); - - break; - } - BufferListItem = BufferListItem->next; - } + /* Calculate fixed-point stepping value, based on the pitch, buffer + * frequency, and output frequency. + */ + Pitch *= (ALfloat)ALBuffer->Frequency / Frequency; + if(Pitch > (ALfloat)MAX_PITCH) + voice->Step = MAX_PITCH<Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1); + BsincPrepare(voice->Step, &voice->SincState); if(Device->Render_Mode == HrtfRender) { @@ -1262,8 +1236,19 @@ void UpdateContextSources(ALCcontext *ctx) voice->Source = NULL; else { - ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE); - voice->Update(voice, source, ctx); + ALbufferlistitem *BufferListItem; + BufferListItem = ATOMIC_LOAD(&source->queue); + while(BufferListItem != NULL) + { + ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE); + voice->Update(voice, source, buffer, ctx); + break; + } + BufferListItem = BufferListItem->next; + } } } } @@ -1277,7 +1262,20 @@ void UpdateContextSources(ALCcontext *ctx) if(source->state != AL_PLAYING && source->state != AL_PAUSED) voice->Source = NULL; else if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE)) - voice->Update(voice, source, ctx); + { + ALbufferlistitem *BufferListItem; + BufferListItem = ATOMIC_LOAD(&source->queue); + while(BufferListItem != NULL) + { + ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + voice->Update(voice, source, buffer, ctx); + break; + } + BufferListItem = BufferListItem->next; + } + } } } } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index b7c08fcd..6c821703 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -25,7 +25,7 @@ typedef struct ALvoice { struct ALsource *volatile Source; /** Method to update mixing parameters. */ - ALvoid (*Update)(struct ALvoice *self, const struct ALsource *source, const ALCcontext *context); + ALvoid (*Update)(struct ALvoice *self, const struct ALsource *source, const struct ALbuffer *ALBuffer, const ALCcontext *context); /** Current target parameters used for mixing. */ ALint Step; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 76a8a921..c20c6404 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -36,6 +36,7 @@ extern "C" { struct ALsource; struct ALvoice; struct ALeffectslot; +struct ALbuffer; /* The number of distinct scale and phase intervals within the filter table. */ @@ -374,8 +375,8 @@ void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, c ALvoid UpdateContextSources(ALCcontext *context); -ALvoid CalcSourceParams(struct ALvoice *voice, const struct ALsource *source, const ALCcontext *ALContext); -ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsource *source, const ALCcontext *ALContext); +ALvoid CalcSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext); +ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext); ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo); -- cgit v1.2.3 From 906a4bb22d6811615ccff417b6086fa36f310c00 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 10 May 2016 22:49:24 -0700 Subject: Hold the source map lock while handling it --- OpenAL32/Include/alSource.h | 13 +++++++-- OpenAL32/alSource.c | 68 +++++++++++++++++++++++++++++++++++++++++++++ common/uintmap.c | 47 +++++++++++++++++++++++++++++++ include/uintmap.h | 2 ++ 4 files changed, 128 insertions(+), 2 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 6c821703..187d7e07 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -138,10 +138,19 @@ typedef struct ALsource { ALuint id; } ALsource; +inline void LockSourcesRead(ALCcontext *context) +{ LockUIntMapRead(&context->SourceMap); } +inline void UnlockSourcesRead(ALCcontext *context) +{ UnlockUIntMapRead(&context->SourceMap); } +inline void LockSourcesWrite(ALCcontext *context) +{ LockUIntMapWrite(&context->SourceMap); } +inline void UnlockSourcesWrite(ALCcontext *context) +{ UnlockUIntMapWrite(&context->SourceMap); } + inline struct ALsource *LookupSource(ALCcontext *context, ALuint id) -{ return (struct ALsource*)LookupUIntMapKey(&context->SourceMap, id); } +{ return (struct ALsource*)LookupUIntMapKeyNoLock(&context->SourceMap, id); } inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) -{ return (struct ALsource*)RemoveUIntMapKey(&context->SourceMap, id); } +{ return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); } ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 749f2ec4..fc5d309b 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -40,6 +40,10 @@ #include "almalloc.h" +extern inline void LockSourcesRead(ALCcontext *context); +extern inline void UnlockSourcesRead(ALCcontext *context); +extern inline void LockSourcesWrite(ALCcontext *context); +extern inline void UnlockSourcesWrite(ALCcontext *context); extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); @@ -1509,6 +1513,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) context = GetContextRef(); if(!context) return; + LockSourcesWrite(context); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); @@ -1560,6 +1565,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) } done: + UnlockSourcesWrite(context); ALCcontext_DecRef(context); } @@ -1572,7 +1578,9 @@ AL_API ALboolean AL_APIENTRY alIsSource(ALuint source) context = GetContextRef(); if(!context) return AL_FALSE; + LockSourcesRead(context); ret = (LookupSource(context, source) ? AL_TRUE : AL_FALSE); + UnlockSourcesRead(context); ALCcontext_DecRef(context); @@ -1588,12 +1596,14 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(FloatValsByProp(param) == 1)) alSetError(Context, AL_INVALID_ENUM); else SetSourcefv(Source, Context, param, &value); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1606,6 +1616,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(FloatValsByProp(param) == 3)) @@ -1615,6 +1626,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 ALfloat fvals[3] = { value1, value2, value3 }; SetSourcefv(Source, Context, param, fvals); } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1627,6 +1639,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!values) @@ -1635,6 +1648,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat alSetError(Context, AL_INVALID_ENUM); else SetSourcefv(Source, Context, param, values); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1648,6 +1662,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(DoubleValsByProp(param) == 1)) @@ -1657,6 +1672,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va ALfloat fval = (ALfloat)value; SetSourcefv(Source, Context, param, &fval); } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1669,6 +1685,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(DoubleValsByProp(param) == 3)) @@ -1678,6 +1695,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v ALfloat fvals[3] = { (ALfloat)value1, (ALfloat)value2, (ALfloat)value3 }; SetSourcefv(Source, Context, param, fvals); } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1691,6 +1709,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!values) @@ -1706,6 +1725,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo fvals[i] = (ALfloat)values[i]; SetSourcefv(Source, Context, param, fvals); } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1719,12 +1739,14 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(IntValsByProp(param) == 1)) alSetError(Context, AL_INVALID_ENUM); else SetSourceiv(Source, Context, param, &value); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1737,6 +1759,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(IntValsByProp(param) == 3)) @@ -1746,6 +1769,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL ALint ivals[3] = { value1, value2, value3 }; SetSourceiv(Source, Context, param, ivals); } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1758,6 +1782,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!values) @@ -1766,6 +1791,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val alSetError(Context, AL_INVALID_ENUM); else SetSourceiv(Source, Context, param, values); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1779,12 +1805,14 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(Int64ValsByProp(param) == 1)) alSetError(Context, AL_INVALID_ENUM); else SetSourcei64v(Source, Context, param, &value); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1797,6 +1825,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(Int64ValsByProp(param) == 3)) @@ -1806,6 +1835,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF ALint64SOFT i64vals[3] = { value1, value2, value3 }; SetSourcei64v(Source, Context, param, i64vals); } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1818,6 +1848,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!values) @@ -1826,6 +1857,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin alSetError(Context, AL_INVALID_ENUM); else SetSourcei64v(Source, Context, param, values); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1839,6 +1871,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!value) @@ -1851,6 +1884,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val if(GetSourcedv(Source, Context, param, &dval)) *value = (ALfloat)dval; } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1864,6 +1898,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(value1 && value2 && value3)) @@ -1880,6 +1915,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va *value3 = (ALfloat)dvals[2]; } } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1894,6 +1930,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!values) @@ -1910,6 +1947,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va values[i] = (ALfloat)dvals[i]; } } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1923,6 +1961,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!value) @@ -1931,6 +1970,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * alSetError(Context, AL_INVALID_ENUM); else GetSourcedv(Source, Context, param, value); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1943,6 +1983,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(value1 && value2 && value3)) @@ -1959,6 +2000,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value3 = dvals[2]; } } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1971,6 +2013,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!values) @@ -1979,6 +2022,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble alSetError(Context, AL_INVALID_ENUM); else GetSourcedv(Source, Context, param, values); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -1992,6 +2036,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!value) @@ -2000,6 +2045,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value alSetError(Context, AL_INVALID_ENUM); else GetSourceiv(Source, Context, param, value); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -2013,6 +2059,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(value1 && value2 && value3)) @@ -2029,6 +2076,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 *value3 = ivals[2]; } } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -2042,6 +2090,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!values) @@ -2050,6 +2099,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values alSetError(Context, AL_INVALID_ENUM); else GetSourceiv(Source, Context, param, values); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -2063,6 +2113,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!value) @@ -2071,6 +2122,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S alSetError(Context, AL_INVALID_ENUM); else GetSourcei64v(Source, Context, param, value); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -2083,6 +2135,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!(value1 && value2 && value3)) @@ -2099,6 +2152,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 *value3 = i64vals[2]; } } + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -2111,6 +2165,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 Context = GetContextRef(); if(!Context) return; + LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); else if(!values) @@ -2119,6 +2174,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 alSetError(Context, AL_INVALID_ENUM); else GetSourcei64v(Source, Context, param, values); + UnlockSourcesRead(Context); ALCcontext_DecRef(Context); } @@ -2137,6 +2193,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) context = GetContextRef(); if(!context) return; + LockSourcesRead(context); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) @@ -2174,6 +2231,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) UnlockContext(context); done: + UnlockSourcesRead(context); ALCcontext_DecRef(context); } @@ -2190,6 +2248,7 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) context = GetContextRef(); if(!context) return; + LockSourcesRead(context); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) @@ -2208,6 +2267,7 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) UnlockContext(context); done: + UnlockSourcesRead(context); ALCcontext_DecRef(context); } @@ -2224,6 +2284,7 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) context = GetContextRef(); if(!context) return; + LockSourcesRead(context); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) @@ -2242,6 +2303,7 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) UnlockContext(context); done: + UnlockSourcesRead(context); ALCcontext_DecRef(context); } @@ -2258,6 +2320,7 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) context = GetContextRef(); if(!context) return; + LockSourcesRead(context); if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); for(i = 0;i < n;i++) @@ -2276,6 +2339,7 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) UnlockContext(context); done: + UnlockSourcesRead(context); ALCcontext_DecRef(context); } @@ -2298,6 +2362,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu device = context->Device; + LockSourcesRead(context); if(!(nb >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); if((source=LookupSource(context, src)) == NULL) @@ -2413,6 +2478,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu WriteUnlock(&source->queue_lock); done: + UnlockSourcesRead(context); ALCcontext_DecRef(context); } @@ -2431,6 +2497,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint context = GetContextRef(); if(!context) return; + LockSourcesRead(context); if(!(nb >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); @@ -2494,6 +2561,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } done: + UnlockSourcesRead(context); ALCcontext_DecRef(context); } diff --git a/common/uintmap.c b/common/uintmap.c index b7a9a29c..d5e7c9ae 100644 --- a/common/uintmap.c +++ b/common/uintmap.c @@ -120,6 +120,33 @@ ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key) return ptr; } +ALvoid *RemoveUIntMapKeyNoLock(UIntMap *map, ALuint key) +{ + if(map->size > 0) + { + ALsizei low = 0; + ALsizei high = map->size - 1; + while(low < high) + { + ALsizei mid = low + (high-low)/2; + if(map->array[mid].key < key) + low = mid + 1; + else + high = mid; + } + if(map->array[low].key == key) + { + ALvoid *ptr = map->array[low].value; + if(low < map->size-1) + memmove(&map->array[low], &map->array[low+1], + (map->size-1-low)*sizeof(map->array[0])); + map->size--; + return ptr; + } + } + return NULL; +} + ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key) { ALvoid *ptr = NULL; @@ -142,3 +169,23 @@ ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key) ReadUnlock(&map->lock); return ptr; } + +ALvoid *LookupUIntMapKeyNoLock(UIntMap *map, ALuint key) +{ + if(map->size > 0) + { + ALsizei low = 0; + ALsizei high = map->size - 1; + while(low < high) + { + ALsizei mid = low + (high-low)/2; + if(map->array[mid].key < key) + low = mid + 1; + else + high = mid; + } + if(map->array[low].key == key) + return map->array[low].value; + } + return NULL; +} diff --git a/include/uintmap.h b/include/uintmap.h index 2c4c5e7a..c41c20ad 100644 --- a/include/uintmap.h +++ b/include/uintmap.h @@ -25,7 +25,9 @@ void InitUIntMap(UIntMap *map, ALsizei limit); void ResetUIntMap(UIntMap *map); ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value); ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key); +ALvoid *RemoveUIntMapKeyNoLock(UIntMap *map, ALuint key); ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key); +ALvoid *LookupUIntMapKeyNoLock(UIntMap *map, ALuint key); inline void LockUIntMapRead(UIntMap *map) { ReadLock(&map->lock); } -- cgit v1.2.3 From b3338d25f6d4fd02935ac83d0d3f227b145307d1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 14 May 2016 23:43:40 -0700 Subject: Provide asynchronous property updates for sources This necessitates a change in how source updates are handled. Rather than just being able to update sources when a dependent object state is changed (e.g. a listener gain change), now all source updates must be proactively provided. Consequently, apps that do not utilize any deferring (AL_SOFT_defer_updates or alcSuspendContext/alcProcessContext) may utilize more CPU since it'll be filling out more update containers for the mixer thread to use. The upside is that there's less blocking between the app's calling thread and the mixer thread, particularly for vectors and other multi-value properties (filters and sends). Deferring behavior when used is also improved, since updates that shouldn't be applied yet are simply not provided. And when they are provided, the mixer doesn't have to ignore them, meaning the actual deferring of a context doesn't have to synchrnously force an update -- the process call will send any pending updates, which the mixer will apply even if another deferral occurs before the mixer runs, because it'll still be there waiting on the next mixer invocation. There is one slight bug introduced by this commit. When a listener change is made, or changes to multiple sources while updates are being deferred, it is possible for the mixer to run while the sources are prepping their updates, causing some of the source updates to be seen before the other. This will be fixed in short order. --- Alc/ALc.c | 65 ++----- Alc/ALu.c | 267 +++++++++++++------------- Alc/mixer.c | 2 +- OpenAL32/Include/alMain.h | 2 +- OpenAL32/Include/alSource.h | 104 +++++++--- OpenAL32/Include/alu.h | 5 +- OpenAL32/alAuxEffectSlot.c | 2 + OpenAL32/alListener.c | 36 +++- OpenAL32/alSource.c | 452 +++++++++++++++++++++++++++++++------------- OpenAL32/alState.c | 48 +++-- 10 files changed, 627 insertions(+), 356 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 47aa0f04..e5c18d8c 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1558,22 +1558,7 @@ extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS */ void ALCcontext_DeferUpdates(ALCcontext *context) { - ALCdevice *device = context->Device; - FPUCtl oldMode; - - SetMixerFPUMode(&oldMode); - - V0(device->Backend,lock)(); - if(!context->DeferUpdates) - { - context->DeferUpdates = AL_TRUE; - - /* Make sure all pending updates are performed */ - UpdateContextSources(context); - } - V0(device->Backend,unlock)(); - - RestoreFPUMode(&oldMode); + ATOMIC_STORE(&context->DeferUpdates, AL_TRUE); } /* ALCcontext_ProcessUpdates @@ -1584,14 +1569,15 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) { ALCdevice *device = context->Device; - V0(device->Backend,lock)(); - if(context->DeferUpdates) + ReadLock(&context->PropLock); + if(ATOMIC_EXCHANGE(ALenum, &context->DeferUpdates, AL_FALSE)) { ALsizei pos; - context->DeferUpdates = AL_FALSE; + UpdateListenerProps(context); LockUIntMapRead(&context->SourceMap); + V0(device->Backend,lock)(); for(pos = 0;pos < context->SourceMap.size;pos++) { ALsource *Source = context->SourceMap.array[pos].value; @@ -1610,9 +1596,11 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) if(new_state) SetSourceState(Source, context, new_state); } + V0(device->Backend,unlock)(); UnlockUIntMapRead(&context->SourceMap); + UpdateAllSourceProps(context); } - V0(device->Backend,unlock)(); + ReadUnlock(&context->PropLock); } @@ -2052,7 +2040,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) } SetMixerFPUMode(&oldMode); - V0(device->Backend,lock)(); if(device->DefaultSlot) { ALeffectslot *slot = device->DefaultSlot; @@ -2062,7 +2049,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) state->OutChannels = device->Dry.NumChannels; if(V(state,deviceUpdate)(device) == AL_FALSE) { - V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } @@ -2074,6 +2060,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALsizei pos; + ReadLock(&context->PropLock); LockUIntMapRead(&context->EffectSlotMap); for(pos = 0;pos < context->EffectSlotMap.size;pos++) { @@ -2085,10 +2072,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(V(state,deviceUpdate)(device) == AL_FALSE) { UnlockUIntMapRead(&context->EffectSlotMap); - V0(device->Backend,unlock)(); + ReadUnlock(&context->PropLock); RestoreFPUMode(&oldMode); return ALC_INVALID_DEVICE; } + UpdateEffectSlotProps(slot, AL_FALSE); } UnlockUIntMapRead(&context->EffectSlotMap); @@ -2105,38 +2093,19 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) source->Send[s].Slot = NULL; source->Send[s].Gain = 1.0f; source->Send[s].GainHF = 1.0f; + source->Send[s].HFReference = LOWPASSFREQREF; + source->Send[s].GainLF = 1.0f; + source->Send[s].LFReference = HIGHPASSFREQREF; s++; } - ATOMIC_STORE(&source->NeedsUpdate, AL_TRUE); } UnlockUIntMapRead(&context->SourceMap); - for(pos = 0;pos < context->VoiceCount;pos++) - { - ALvoice *voice = &context->Voices[pos]; - ALsource *source = voice->Source; - ALbufferlistitem *BufferListItem; - - if(!source) - continue; - - BufferListItem = ATOMIC_LOAD(&source->queue); - while(BufferListItem != NULL) - { - ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) - { - ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE); - voice->Update(voice, source, buffer, context); - break; - } - BufferListItem = BufferListItem->next; - } - } + UpdateAllSourceProps(context); + ReadUnlock(&context->PropLock); context = context->next; } - V0(device->Backend,unlock)(); RestoreFPUMode(&oldMode); if(!(device->Flags&DEVICE_PAUSED)) @@ -2308,7 +2277,7 @@ static ALvoid InitContext(ALCcontext *Context) Context->DopplerFactor = 1.0f; Context->DopplerVelocity = 1.0f; Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; - Context->DeferUpdates = AL_FALSE; + ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE); Context->ExtensionList = alExtList; } diff --git a/Alc/ALu.c b/Alc/ALu.c index 4a9a59cf..2fffdcd9 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -266,7 +266,7 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state) } -static ALboolean CalcListenerParams(ALCcontext *Context) +static void CalcListenerParams(ALCcontext *Context) { ALlistener *Listener = Context->Listener; ALdouble N[3], V[3], U[3], P[3]; @@ -275,7 +275,7 @@ static ALboolean CalcListenerParams(ALCcontext *Context) aluVector vel; props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel); - if(!props) return AL_FALSE; + if(!props) return; /* AT then UP */ N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed); @@ -330,17 +330,15 @@ static ALboolean CalcListenerParams(ALCcontext *Context) ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, &Listener->FreeList, &first, props) == 0); - - return AL_TRUE; } -static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) +static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) { struct ALeffectslotProps *first; struct ALeffectslotProps *props; props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); - if(!props) return AL_FALSE; + if(!props) return; slot->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); @@ -377,11 +375,43 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALeffectslotProps*, &slot->FreeList, &first, props) == 0); +} + +static void CalcSourceParams(ALvoice *voice, ALCcontext *context) +{ + ALsource *source = voice->Source; + ALbufferlistitem *BufferListItem; + struct ALsourceProps *first; + struct ALsourceProps *props; + + props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel); + if(!props) return; + + BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); + while(BufferListItem != NULL) + { + ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + voice->Update(voice, props, buffer, context); + break; + } + BufferListItem = BufferListItem->next; + } - return AL_TRUE; + /* WARNING: A livelock is theoretically possible if another thread keeps + * changing the freelist head without giving this a chance to actually swap + * in the old container (practically impossible with this little code, + * but...). + */ + first = ATOMIC_LOAD(&source->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &first, props) == 0); } -ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +ALvoid CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f, 0.0f } @@ -448,22 +478,22 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A ListenerGain = Listener->Params.Gain; /* Get source properties */ - SourceVolume = ALSource->Gain; - MinVolume = ALSource->MinGain; - MaxVolume = ALSource->MaxGain; - Pitch = ALSource->Pitch; - Relative = ALSource->HeadRelative; - DirectChannels = ALSource->DirectChannels; + SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); + MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed); + MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed); + Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed); + Relative = ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed); + DirectChannels = ATOMIC_LOAD(&props->DirectChannels, almemory_order_relaxed); /* Convert counter-clockwise to clockwise. */ - StereoMap[0].angle = -ALSource->StereoPan[0]; - StereoMap[1].angle = -ALSource->StereoPan[1]; + StereoMap[0].angle = -ATOMIC_LOAD(&props->StereoPan[0], almemory_order_relaxed); + StereoMap[1].angle = -ATOMIC_LOAD(&props->StereoPan[1], almemory_order_relaxed); voice->Direct.OutBuffer = Device->Dry.Buffer; voice->Direct.OutChannels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { - SendSlots[i] = ALSource->Send[i].Slot; + SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) @@ -489,15 +519,15 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); - DryGain *= ALSource->Direct.Gain * ListenerGain; - DryGainHF = ALSource->Direct.GainHF; - DryGainLF = ALSource->Direct.GainLF; + DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain; + DryGainHF = ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed); + DryGainLF = ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed); for(i = 0;i < NumSends;i++) { WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume); - WetGain[i] *= ALSource->Send[i].Gain * ListenerGain; - WetGainHF[i] = ALSource->Send[i].GainHF; - WetGainLF[i] = ALSource->Send[i].GainLF; + WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain; + WetGainHF[i] = ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed); + WetGainLF[i] = ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed); } switch(ALBuffer->FmtChannels) @@ -557,13 +587,13 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A ALfloat scale; /* AT then UP */ - N[0] = ALSource->Orientation[0][0]; - N[1] = ALSource->Orientation[0][1]; - N[2] = ALSource->Orientation[0][2]; + N[0] = ATOMIC_LOAD(&props->Orientation[0][0], almemory_order_relaxed); + N[1] = ATOMIC_LOAD(&props->Orientation[0][1], almemory_order_relaxed); + N[2] = ATOMIC_LOAD(&props->Orientation[0][2], almemory_order_relaxed); aluNormalize(N); - V[0] = ALSource->Orientation[1][0]; - V[1] = ALSource->Orientation[1][1]; - V[2] = ALSource->Orientation[1][2]; + V[0] = ATOMIC_LOAD(&props->Orientation[1][0], almemory_order_relaxed); + V[1] = ATOMIC_LOAD(&props->Orientation[1][1], almemory_order_relaxed); + V[2] = ATOMIC_LOAD(&props->Orientation[1][2], almemory_order_relaxed); aluNormalize(V); if(!Relative) { @@ -779,8 +809,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } { - ALfloat hfscale = ALSource->Direct.HFReference / Frequency; - ALfloat lfscale = ALSource->Direct.LFReference / Frequency; + ALfloat hfscale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) / + Frequency; + ALfloat lfscale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) / + Frequency; DryGainHF = maxf(DryGainHF, 0.0001f); DryGainLF = maxf(DryGainLF, 0.0001f); for(c = 0;c < num_channels;c++) @@ -800,8 +832,10 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } for(i = 0;i < NumSends;i++) { - ALfloat hfscale = ALSource->Send[i].HFReference / Frequency; - ALfloat lfscale = ALSource->Send[i].LFReference / Frequency; + ALfloat hfscale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) / + Frequency; + ALfloat lfscale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) / + Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0001f); WetGainLF[i] = maxf(WetGainLF[i], 0.0001f); for(c = 0;c < num_channels;c++) @@ -821,7 +855,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const ALsource *ALSource, const A } } -ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +ALvoid CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { const ALCdevice *Device = ALContext->Device; const ALlistener *Listener = ALContext->Listener; @@ -862,7 +896,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } /* Get context/device properties */ - DopplerFactor = Listener->Params.DopplerFactor * ALSource->DopplerFactor; + DopplerFactor = Listener->Params.DopplerFactor; SpeedOfSound = Listener->Params.SpeedOfSound; NumSends = Device->NumAuxSends; Frequency = Device->Frequency; @@ -872,29 +906,39 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer MetersPerUnit = Listener->Params.MetersPerUnit; /* Get source properties */ - SourceVolume = ALSource->Gain; - MinVolume = ALSource->MinGain; - MaxVolume = ALSource->MaxGain; - Pitch = ALSource->Pitch; - Position = ALSource->Position; - Direction = ALSource->Direction; - Velocity = ALSource->Velocity; - MinDist = ALSource->RefDistance; - MaxDist = ALSource->MaxDistance; - Rolloff = ALSource->RollOffFactor; - InnerAngle = ALSource->InnerAngle; - OuterAngle = ALSource->OuterAngle; - AirAbsorptionFactor = ALSource->AirAbsorptionFactor; - DryGainHFAuto = ALSource->DryGainHFAuto; - WetGainAuto = ALSource->WetGainAuto; - WetGainHFAuto = ALSource->WetGainHFAuto; - RoomRolloffBase = ALSource->RoomRolloffFactor; + SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); + MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed); + MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed); + Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed); + aluVectorSet(&Position, ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed), + ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed), + ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed), + 1.0f); + aluVectorSet(&Direction, ATOMIC_LOAD(&props->Direction[0], almemory_order_relaxed), + ATOMIC_LOAD(&props->Direction[1], almemory_order_relaxed), + ATOMIC_LOAD(&props->Direction[2], almemory_order_relaxed), + 0.0f); + aluVectorSet(&Velocity, ATOMIC_LOAD(&props->Velocity[0], almemory_order_relaxed), + ATOMIC_LOAD(&props->Velocity[1], almemory_order_relaxed), + ATOMIC_LOAD(&props->Velocity[2], almemory_order_relaxed), + 0.0f); + MinDist = ATOMIC_LOAD(&props->RefDistance, almemory_order_relaxed); + MaxDist = ATOMIC_LOAD(&props->MaxDistance, almemory_order_relaxed); + Rolloff = ATOMIC_LOAD(&props->RollOffFactor, almemory_order_relaxed); + DopplerFactor *= ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed); + InnerAngle = ATOMIC_LOAD(&props->InnerAngle, almemory_order_relaxed); + OuterAngle = ATOMIC_LOAD(&props->OuterAngle, almemory_order_relaxed); + AirAbsorptionFactor = ATOMIC_LOAD(&props->AirAbsorptionFactor, almemory_order_relaxed); + DryGainHFAuto = ATOMIC_LOAD(&props->DryGainHFAuto, almemory_order_relaxed); + WetGainAuto = ATOMIC_LOAD(&props->WetGainAuto, almemory_order_relaxed); + WetGainHFAuto = ATOMIC_LOAD(&props->WetGainHFAuto, almemory_order_relaxed); + RoomRolloffBase = ATOMIC_LOAD(&props->RoomRolloffFactor, almemory_order_relaxed); voice->Direct.OutBuffer = Device->Dry.Buffer; voice->Direct.OutChannels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { - SendSlots[i] = ALSource->Send[i].Slot; + SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; @@ -905,7 +949,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer DecayDistance[i] = 0.0f; RoomAirAbsorption[i] = 1.0f; } - else if(SendSlots[i]->AuxSendAuto) + else if(SendSlots[i]->Params.AuxSendAuto) { RoomRolloff[i] = SendSlots[i]->Params.RoomRolloff + RoomRolloffBase; DecayDistance[i] = SendSlots[i]->Params.DecayTime * @@ -934,7 +978,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } /* Transform source to listener space (convert to head relative) */ - if(ALSource->HeadRelative == AL_FALSE) + if(ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed) == AL_FALSE) { const aluMatrixd *Matrix = &Listener->Params.Matrix; /* Transform source vectors */ @@ -964,8 +1008,9 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer Attenuation = 1.0f; for(i = 0;i < NumSends;i++) RoomAttenuation[i] = 1.0f; - switch(Listener->Params.SourceDistanceModel ? ALSource->DistanceModel : - Listener->Params.DistanceModel) + switch(Listener->Params.SourceDistanceModel ? + ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed) : + Listener->Params.DistanceModel) { case InverseDistanceClamped: ClampedDist = clampf(ClampedDist, MinDist, MaxDist); @@ -1059,13 +1104,15 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer if(Angle > InnerAngle && Angle <= OuterAngle) { ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle); - ConeVolume = lerp(1.0f, ALSource->OuterGain, scale); - ConeHF = lerp(1.0f, ALSource->OuterGainHF, scale); + ConeVolume = lerp(1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), + scale); + ConeHF = lerp(1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), + scale); } else if(Angle > OuterAngle) { - ConeVolume = ALSource->OuterGain; - ConeHF = ALSource->OuterGainHF; + ConeVolume = ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed); + ConeHF = ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed); } else { @@ -1093,14 +1140,14 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer WetGain[i] = clampf(WetGain[i], MinVolume, MaxVolume); /* Apply gain and frequency filters */ - DryGain *= ALSource->Direct.Gain * ListenerGain; - DryGainHF *= ALSource->Direct.GainHF; - DryGainLF *= ALSource->Direct.GainLF; + DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain; + DryGainHF *= ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed); + DryGainLF *= ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed); for(i = 0;i < NumSends;i++) { - WetGain[i] *= ALSource->Send[i].Gain * ListenerGain; - WetGainHF[i] *= ALSource->Send[i].GainHF; - WetGainLF[i] *= ALSource->Send[i].GainLF; + WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain; + WetGainHF[i] *= ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed); + WetGainLF[i] *= ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed); } /* Calculate velocity-based doppler effect */ @@ -1139,7 +1186,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer */ ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; ALfloat ev = 0.0f, az = 0.0f; - ALfloat radius = ALSource->Radius; + ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed); ALfloat coeffs[MAX_AMBI_COEFFS]; ALfloat spread = 0.0f; @@ -1193,7 +1240,7 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer { /* Non-HRTF rendering. */ ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; - ALfloat radius = ALSource->Radius; + ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed); ALfloat coeffs[MAX_AMBI_COEFFS]; ALfloat spread = 0.0f; @@ -1247,8 +1294,10 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } { - ALfloat hfscale = ALSource->Direct.HFReference / Frequency; - ALfloat lfscale = ALSource->Direct.LFReference / Frequency; + ALfloat hfscale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) / + Frequency; + ALfloat lfscale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) / + Frequency; DryGainHF = maxf(DryGainHF, 0.0001f); DryGainLF = maxf(DryGainLF, 0.0001f); voice->Direct.Filters[0].ActiveType = AF_None; @@ -1265,8 +1314,10 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer } for(i = 0;i < NumSends;i++) { - ALfloat hfscale = ALSource->Send[i].HFReference / Frequency; - ALfloat lfscale = ALSource->Send[i].LFReference / Frequency; + ALfloat hfscale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) / + Frequency; + ALfloat lfscale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) / + Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0001f); WetGainLF[i] = maxf(WetGainLF[i], 0.0001f); voice->Send[i].Filters[0].ActiveType = AF_None; @@ -1287,69 +1338,22 @@ ALvoid CalcSourceParams(ALvoice *voice, const ALsource *ALSource, const ALbuffer void UpdateContextSources(ALCcontext *ctx) { ALvoice *voice, *voice_end; - ALboolean fullupdate; ALsource *source; - fullupdate = CalcListenerParams(ctx); -#define UPDATE_SLOT(iter) do { \ - if(CalcEffectSlotParams(*iter, ctx->Device)) \ - fullupdate = AL_TRUE; \ -} while(0) + CalcListenerParams(ctx); +#define UPDATE_SLOT(iter) CalcEffectSlotParams(*iter, ctx->Device) VECTOR_FOR_EACH(ALeffectslot*, ctx->ActiveAuxSlots, UPDATE_SLOT); #undef UPDATE_SLOT - if(fullupdate) + voice = ctx->Voices; + voice_end = voice + ctx->VoiceCount; + for(;voice != voice_end;++voice) { - voice = ctx->Voices; - voice_end = voice + ctx->VoiceCount; - for(;voice != voice_end;++voice) - { - if(!(source=voice->Source)) continue; - if(source->state != AL_PLAYING && source->state != AL_PAUSED) - voice->Source = NULL; - else - { - ALbufferlistitem *BufferListItem; - BufferListItem = ATOMIC_LOAD(&source->queue); - while(BufferListItem != NULL) - { - ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) - { - ATOMIC_STORE(&source->NeedsUpdate, AL_FALSE); - voice->Update(voice, source, buffer, ctx); - break; - } - BufferListItem = BufferListItem->next; - } - } - } - } - else - { - voice = ctx->Voices; - voice_end = voice + ctx->VoiceCount; - for(;voice != voice_end;++voice) - { - if(!(source=voice->Source)) continue; - if(source->state != AL_PLAYING && source->state != AL_PAUSED) - voice->Source = NULL; - else if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE)) - { - ALbufferlistitem *BufferListItem; - BufferListItem = ATOMIC_LOAD(&source->queue); - while(BufferListItem != NULL) - { - ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) - { - voice->Update(voice, source, buffer, ctx); - break; - } - BufferListItem = BufferListItem->next; - } - } - } + if(!(source=voice->Source)) continue; + if(source->state != AL_PLAYING && source->state != AL_PAUSED) + voice->Source = NULL; + else + CalcSourceParams(voice, ctx); } } @@ -1447,8 +1451,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) ctx = ATOMIC_LOAD(&device->ContextList); while(ctx) { - if(!ctx->DeferUpdates) - UpdateContextSources(ctx); + UpdateContextSources(ctx); #define CLEAR_WET_BUFFER(iter) do { \ for(i = 0;i < (*iter)->NumChannels;i++) \ memset((*iter)->WetBuffer[i], 0, SamplesToDo*sizeof(ALfloat)); \ diff --git a/Alc/mixer.c b/Alc/mixer.c index 44495d72..38ec295c 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -388,9 +388,9 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam BufferListItem = ATOMIC_LOAD(&Source->current_buffer); DataPosInt = Source->position; DataPosFrac = Source->position_fraction; - Looping = Source->Looping; NumChannels = Source->NumChannels; SampleSize = Source->SampleSize; + Looping = voice->Looping; increment = voice->Step; IrSize = (Device->Hrtf ? GetHrtfIrSize(Device->Hrtf) : 0); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 44ce4fe0..a624e078 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -695,7 +695,7 @@ struct ALCcontext_struct { volatile ALfloat DopplerFactor; volatile ALfloat DopplerVelocity; volatile ALfloat SpeedOfSound; - volatile ALenum DeferUpdates; + ATOMIC(ALenum) DeferUpdates; RWLock PropLock; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 187d7e07..6d915153 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -13,6 +13,7 @@ extern "C" { struct ALbuffer; struct ALsource; +struct ALsourceProps; typedef struct ALbufferlistitem { @@ -25,11 +26,13 @@ typedef struct ALvoice { struct ALsource *volatile Source; /** Method to update mixing parameters. */ - ALvoid (*Update)(struct ALvoice *self, const struct ALsource *source, const struct ALbuffer *ALBuffer, const ALCcontext *context); + ALvoid (*Update)(struct ALvoice *self, const struct ALsourceProps *props, const struct ALbuffer *ALBuffer, const ALCcontext *context); /** Current target parameters used for mixing. */ ALint Step; + ALboolean Looping; + /* If not 'moving', gain/coefficients are set directly without fading. */ ALboolean Moving; @@ -46,6 +49,59 @@ typedef struct ALvoice { } ALvoice; +struct ALsourceProps { + ATOMIC(ALfloat) Pitch; + ATOMIC(ALfloat) Gain; + ATOMIC(ALfloat) OuterGain; + ATOMIC(ALfloat) MinGain; + ATOMIC(ALfloat) MaxGain; + ATOMIC(ALfloat) InnerAngle; + ATOMIC(ALfloat) OuterAngle; + ATOMIC(ALfloat) RefDistance; + ATOMIC(ALfloat) MaxDistance; + ATOMIC(ALfloat) RollOffFactor; + ATOMIC(ALfloat) Position[3]; + ATOMIC(ALfloat) Velocity[3]; + ATOMIC(ALfloat) Direction[3]; + ATOMIC(ALfloat) Orientation[2][3]; + ATOMIC(ALboolean) HeadRelative; + ATOMIC(ALboolean) Looping; + ATOMIC(enum DistanceModel) DistanceModel; + ATOMIC(ALboolean) DirectChannels; + + ATOMIC(ALboolean) DryGainHFAuto; + ATOMIC(ALboolean) WetGainAuto; + ATOMIC(ALboolean) WetGainHFAuto; + ATOMIC(ALfloat) OuterGainHF; + + ATOMIC(ALfloat) AirAbsorptionFactor; + ATOMIC(ALfloat) RoomRolloffFactor; + ATOMIC(ALfloat) DopplerFactor; + + ATOMIC(ALfloat) StereoPan[2]; + + ATOMIC(ALfloat) Radius; + + /** Direct filter and auxiliary send info. */ + struct { + ATOMIC(ALfloat) Gain; + ATOMIC(ALfloat) GainHF; + ATOMIC(ALfloat) HFReference; + ATOMIC(ALfloat) GainLF; + ATOMIC(ALfloat) LFReference; + } Direct; + struct { + ATOMIC(struct ALeffectslot*) Slot; + ATOMIC(ALfloat) Gain; + ATOMIC(ALfloat) GainHF; + ATOMIC(ALfloat) HFReference; + ATOMIC(ALfloat) GainLF; + ATOMIC(ALfloat) LFReference; + } Send[MAX_SENDS]; + + ATOMIC(struct ALsourceProps*) next; +}; + typedef struct ALsource { /** Source properties. */ volatile ALfloat Pitch; @@ -58,9 +114,9 @@ typedef struct ALsource { volatile ALfloat RefDistance; volatile ALfloat MaxDistance; volatile ALfloat RollOffFactor; - aluVector Position; - aluVector Velocity; - aluVector Direction; + volatile ALfloat Position[3]; + volatile ALfloat Velocity[3]; + volatile ALfloat Direction[3]; volatile ALfloat Orientation[2][3]; volatile ALboolean HeadRelative; volatile ALboolean Looping; @@ -83,6 +139,23 @@ typedef struct ALsource { volatile 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[MAX_SENDS]; + /** * Last user-specified offset, and the offset type (bytes, samples, or * seconds). @@ -114,25 +187,8 @@ typedef struct ALsource { ALuint NumChannels; ALuint SampleSize; - /** 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[MAX_SENDS]; - - /** Source needs to update its mixing parameters. */ - ATOMIC(ALenum) NeedsUpdate; + ATOMIC(struct ALsourceProps*) Update; + ATOMIC(struct ALsourceProps*) FreeList; /** Self ID */ ALuint id; @@ -152,6 +208,8 @@ inline struct ALsource *LookupSource(ALCcontext *context, ALuint id) inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) { return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); } +void UpdateSourceProps(ALsource *source, ALuint num_sends); +void UpdateAllSourceProps(ALCcontext *context); ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source); diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index c20c6404..8e93dc6e 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -34,6 +34,7 @@ extern "C" { #endif struct ALsource; +struct ALsourceProps; struct ALvoice; struct ALeffectslot; struct ALbuffer; @@ -375,8 +376,8 @@ void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, c ALvoid UpdateContextSources(ALCcontext *context); -ALvoid CalcSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext); -ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsource *source, const struct ALbuffer *buffer, const ALCcontext *ALContext); +ALvoid CalcAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext); +ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext); ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo); diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index 98ee9328..6d1423db 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -202,6 +202,8 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); slot->AuxSendAuto = value; UpdateEffectSlotProps(slot, AL_FALSE); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + UpdateAllSourceProps(context); break; default: diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 1c40c399..c59d644b 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -51,7 +51,11 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -88,7 +92,11 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -140,7 +148,11 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -161,7 +173,11 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -190,7 +206,11 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -235,7 +255,11 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a62bf59e..e2d6ca4f 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -48,6 +48,7 @@ extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); static ALvoid InitSourceParams(ALsource *Source); +static ALvoid DeinitSource(ALsource *source); static ALint64 GetSourceSampleOffset(ALsource *Source); static ALdouble GetSourceSecOffset(ALsource *Source); static ALdouble GetSourceOffset(ALsource *Source, ALenum name); @@ -123,6 +124,12 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint *values); static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values); +static inline bool SourceShouldUpdate(const ALsource *source, const ALCcontext *context) +{ + return (source->state == AL_PLAYING || source->state == AL_PAUSED) && + !ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); +} + static ALint FloatValsByProp(ALenum prop) { if(prop != (ALenum)((SourceProp)prop)) @@ -376,8 +383,14 @@ static ALint Int64ValsByProp(ALenum prop) SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); \ } while(0) +#define DO_UPDATEPROPS() do { \ + if(SourceShouldUpdate(Source, Context)) \ + UpdateSourceProps(Source, device->NumAuxSends); \ +} while(0) + static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALfloat *values) { + ALCdevice *device = Context->Device; ALint ival; switch(prop) @@ -393,98 +406,98 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p CHECKVAL(*values >= 0.0f); Source->Pitch = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_CONE_INNER_ANGLE: CHECKVAL(*values >= 0.0f && *values <= 360.0f); Source->InnerAngle = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_CONE_OUTER_ANGLE: CHECKVAL(*values >= 0.0f && *values <= 360.0f); Source->OuterAngle = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_GAIN: CHECKVAL(*values >= 0.0f); Source->Gain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_MAX_DISTANCE: CHECKVAL(*values >= 0.0f); Source->MaxDistance = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_ROLLOFF_FACTOR: CHECKVAL(*values >= 0.0f); Source->RollOffFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_REFERENCE_DISTANCE: CHECKVAL(*values >= 0.0f); Source->RefDistance = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_MIN_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->MinGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_MAX_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->MaxGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_CONE_OUTER_GAIN: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->OuterGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_CONE_OUTER_GAINHF: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->OuterGainHF = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_AIR_ABSORPTION_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 10.0f); Source->AirAbsorptionFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_ROOM_ROLLOFF_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 10.0f); Source->RoomRolloffFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_DOPPLER_FACTOR: CHECKVAL(*values >= 0.0f && *values <= 1.0f); Source->DopplerFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_SEC_OFFSET: @@ -492,13 +505,13 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BYTE_OFFSET: CHECKVAL(*values >= 0.0f); - LockContext(Context); Source->OffsetType = prop; Source->Offset = *values; if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - !Context->DeferUpdates) + !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) { + LockContext(Context); WriteLock(&Source->queue_lock); if(ApplyOffset(Source) == AL_FALSE) { @@ -507,68 +520,64 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } WriteUnlock(&Source->queue_lock); + UnlockContext(Context); } - UnlockContext(Context); return AL_TRUE; case AL_SOURCE_RADIUS: CHECKVAL(*values >= 0.0f && isfinite(*values)); Source->Radius = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_STEREO_ANGLES: CHECKVAL(isfinite(values[0]) && isfinite(values[1])); - LockContext(Context); Source->StereoPan[0] = values[0]; Source->StereoPan[1] = values[1]; - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_POSITION: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - LockContext(Context); - aluVectorSet(&Source->Position, values[0], values[1], values[2], 1.0f); - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + Source->Position[0] = values[0]; + Source->Position[1] = values[1]; + Source->Position[2] = values[2]; + DO_UPDATEPROPS(); return AL_TRUE; case AL_VELOCITY: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - LockContext(Context); - aluVectorSet(&Source->Velocity, values[0], values[1], values[2], 0.0f); - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + Source->Velocity[0] = values[0]; + Source->Velocity[1] = values[1]; + Source->Velocity[2] = values[2]; + DO_UPDATEPROPS(); return AL_TRUE; case AL_DIRECTION: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - LockContext(Context); - aluVectorSet(&Source->Direction, values[0], values[1], values[2], 0.0f); - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + Source->Direction[0] = values[0]; + Source->Direction[1] = values[1]; + Source->Direction[2] = values[2]; + DO_UPDATEPROPS(); return AL_TRUE; case AL_ORIENTATION: CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2]) && isfinite(values[3]) && isfinite(values[4]) && isfinite(values[5])); - LockContext(Context); Source->Orientation[0][0] = values[0]; Source->Orientation[0][1] = values[1]; Source->Orientation[0][2] = values[2]; Source->Orientation[1][0] = values[3]; Source->Orientation[1][1] = values[4]; Source->Orientation[1][2] = values[5]; - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; @@ -626,13 +635,14 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->HeadRelative = (ALboolean)*values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_LOOPING: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->Looping = (ALboolean)*values; + DO_UPDATEPROPS(); return AL_TRUE; case AL_BUFFER: @@ -695,13 +705,13 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BYTE_OFFSET: CHECKVAL(*values >= 0); - LockContext(Context); Source->OffsetType = prop; Source->Offset = *values; if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - !Context->DeferUpdates) + !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) { + LockContext(Context); WriteLock(&Source->queue_lock); if(ApplyOffset(Source) == AL_FALSE) { @@ -710,8 +720,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } WriteUnlock(&Source->queue_lock); + UnlockContext(Context); } - UnlockContext(Context); return AL_TRUE; case AL_DIRECT_FILTER: @@ -722,7 +732,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } - LockContext(Context); if(!filter) { Source->Direct.Gain = 1.0f; @@ -739,37 +748,36 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Direct.GainLF = filter->GainLF; Source->Direct.LFReference = filter->LFReference; } - UnlockContext(Context); UnlockFiltersRead(device); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_DIRECT_FILTER_GAINHF_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->DryGainHFAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->WetGainAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->WetGainHFAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_DIRECT_CHANNELS_SOFT: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); Source->DirectChannels = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_DISTANCE_MODEL: @@ -783,27 +791,20 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->DistanceModel = *values; if(Context->SourceDistanceModel) - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + DO_UPDATEPROPS(); return AL_TRUE; case AL_AUXILIARY_SEND_FILTER: LockFiltersRead(device); - LockContext(Context); if(!((ALuint)values[1] < device->NumAuxSends && (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) && (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) { - UnlockContext(Context); UnlockFiltersRead(device); SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } - /* Add refcount on the new slot, and release the previous slot */ - if(slot) IncrementRef(&slot->ref); - slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot); - if(slot) DecrementRef(&slot->ref); - if(!filter) { /* Disable filter */ @@ -821,9 +822,28 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->Send[values[1]].GainLF = filter->GainLF; Source->Send[values[1]].LFReference = filter->LFReference; } - UnlockContext(Context); UnlockFiltersRead(device); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + + if(slot != Source->Send[values[1]].Slot && + (Source->state == AL_PLAYING || Source->state == AL_PAUSED)) + { + /* Add refcount on the new slot, and release the previous slot */ + if(slot) IncrementRef(&slot->ref); + slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot); + if(slot) DecrementRef(&slot->ref); + /* We must force an update if the auxiliary slot changed on a + * playing source, in case the slot is about to be deleted. + */ + UpdateSourceProps(Source, device->NumAuxSends); + } + else + { + if(slot) IncrementRef(&slot->ref); + slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot); + if(slot) DecrementRef(&slot->ref); + DO_UPDATEPROPS(); + } + return AL_TRUE; @@ -1078,10 +1098,8 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_STEREO_ANGLES: - LockContext(Context); values[0] = Source->StereoPan[0]; values[1] = Source->StereoPan[1]; - UnlockContext(Context); return AL_TRUE; case AL_SEC_OFFSET_LATENCY_SOFT: @@ -1093,38 +1111,30 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_POSITION: - LockContext(Context); - values[0] = Source->Position.v[0]; - values[1] = Source->Position.v[1]; - values[2] = Source->Position.v[2]; - UnlockContext(Context); + values[0] = Source->Position[0]; + values[1] = Source->Position[1]; + values[2] = Source->Position[2]; return AL_TRUE; case AL_VELOCITY: - LockContext(Context); - values[0] = Source->Velocity.v[0]; - values[1] = Source->Velocity.v[1]; - values[2] = Source->Velocity.v[2]; - UnlockContext(Context); + values[0] = Source->Velocity[0]; + values[1] = Source->Velocity[1]; + values[2] = Source->Velocity[2]; return AL_TRUE; case AL_DIRECTION: - LockContext(Context); - values[0] = Source->Direction.v[0]; - values[1] = Source->Direction.v[1]; - values[2] = Source->Direction.v[2]; - UnlockContext(Context); + values[0] = Source->Direction[0]; + values[1] = Source->Direction[1]; + values[2] = Source->Direction[2]; return AL_TRUE; case AL_ORIENTATION: - LockContext(Context); values[0] = Source->Orientation[0][0]; values[1] = Source->Orientation[0][1]; values[2] = Source->Orientation[0][2]; values[3] = Source->Orientation[1][0]; values[4] = Source->Orientation[1][1]; values[5] = Source->Orientation[1][2]; - UnlockContext(Context); return AL_TRUE; /* 1x int */ @@ -1522,9 +1532,8 @@ done: AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) { ALCcontext *context; - ALbufferlistitem *BufferList; ALsource *Source; - ALsizei i, j; + ALsizei i; context = GetContextRef(); if(!context) return; @@ -1559,22 +1568,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) } UnlockContext(context); - BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, NULL); - while(BufferList != NULL) - { - ALbufferlistitem *next = BufferList->next; - if(BufferList->buffer != NULL) - DecrementRef(&BufferList->buffer->ref); - free(BufferList); - BufferList = next; - } - - for(j = 0;j < MAX_SENDS;++j) - { - if(Source->Send[j].Slot) - DecrementRef(&Source->Send[j].Slot->ref); - Source->Send[j].Slot = NULL; - } + DeinitSource(Source); memset(Source, 0, sizeof(*Source)); al_free(Source); @@ -1612,6 +1606,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1620,6 +1615,7 @@ AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) else SetSourcefv(Source, Context, param, &value); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1632,6 +1628,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1643,6 +1640,7 @@ AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1 SetSourcefv(Source, Context, param, fvals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1655,6 +1653,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1665,6 +1664,7 @@ AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat else SetSourcefv(Source, Context, param, values); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1678,6 +1678,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1689,6 +1690,7 @@ AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble va SetSourcefv(Source, Context, param, &fval); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1701,6 +1703,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1712,6 +1715,7 @@ AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble v SetSourcefv(Source, Context, param, fvals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1725,6 +1729,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1742,6 +1747,7 @@ AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdo SetSourcefv(Source, Context, param, fvals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1755,6 +1761,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1763,6 +1770,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) else SetSourceiv(Source, Context, param, &value); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1775,6 +1783,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1786,6 +1795,7 @@ AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, AL SetSourceiv(Source, Context, param, ivals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1798,6 +1808,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1808,6 +1819,7 @@ AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *val else SetSourceiv(Source, Context, param, values); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1821,6 +1833,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1829,6 +1842,7 @@ AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SO else SetSourcei64v(Source, Context, param, &value); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1841,6 +1855,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1852,6 +1867,7 @@ AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOF SetSourcei64v(Source, Context, param, i64vals); } UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1864,6 +1880,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin Context = GetContextRef(); if(!Context) return; + WriteLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1874,6 +1891,7 @@ AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALin else SetSourcei64v(Source, Context, param, values); UnlockSourcesRead(Context); + WriteUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1887,6 +1905,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1901,6 +1920,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *val *value = (ALfloat)dval; } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1914,6 +1934,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1932,6 +1953,7 @@ AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *va } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1946,6 +1968,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1964,6 +1987,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *va } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1977,6 +2001,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -1987,6 +2012,7 @@ AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble * else GetSourcedv(Source, Context, param, value); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -1999,6 +2025,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2017,6 +2044,7 @@ AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2029,6 +2057,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2039,6 +2068,7 @@ AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble else GetSourcedv(Source, Context, param, values); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2052,6 +2082,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2062,6 +2093,7 @@ AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value else GetSourceiv(Source, Context, param, value); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2075,6 +2107,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2093,6 +2126,7 @@ AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1 } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2106,6 +2140,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2116,6 +2151,7 @@ AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values else GetSourceiv(Source, Context, param, values); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2129,6 +2165,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2139,6 +2176,7 @@ AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64S else GetSourcei64v(Source, Context, param, value); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2151,6 +2189,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2169,6 +2208,7 @@ AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64 } } UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2181,6 +2221,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 Context = GetContextRef(); if(!Context) return; + ReadLock(&Context->PropLock); LockSourcesRead(Context); if((Source=LookupSource(Context, source)) == NULL) alSetError(Context, AL_INVALID_NAME); @@ -2191,6 +2232,7 @@ AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64 else GetSourcei64v(Source, Context, param, values); UnlockSourcesRead(Context); + ReadUnlock(&Context->PropLock); ALCcontext_DecRef(Context); } @@ -2241,8 +2283,10 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - if(context->DeferUpdates) source->new_state = AL_PLAYING; - else SetSourceState(source, context, AL_PLAYING); + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + source->new_state = AL_PLAYING; + else + SetSourceState(source, context, AL_PLAYING); } UnlockContext(context); @@ -2277,8 +2321,10 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - if(context->DeferUpdates) source->new_state = AL_PAUSED; - else SetSourceState(source, context, AL_PAUSED); + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + source->new_state = AL_PAUSED; + else + SetSourceState(source, context, AL_PAUSED); } UnlockContext(context); @@ -2594,9 +2640,15 @@ static ALvoid InitSourceParams(ALsource *Source) Source->InnerAngle = 360.0f; Source->OuterAngle = 360.0f; Source->Pitch = 1.0f; - aluVectorSet(&Source->Position, 0.0f, 0.0f, 0.0f, 1.0f); - aluVectorSet(&Source->Velocity, 0.0f, 0.0f, 0.0f, 0.0f); - aluVectorSet(&Source->Direction, 0.0f, 0.0f, 0.0f, 0.0f); + Source->Position[0] = 0.0f; + Source->Position[1] = 0.0f; + Source->Position[2] = 0.0f; + Source->Velocity[0] = 0.0f; + Source->Velocity[1] = 0.0f; + Source->Velocity[2] = 0.0f; + Source->Direction[0] = 0.0f; + Source->Direction[1] = 0.0f; + Source->Direction[2] = 0.0f; Source->Orientation[0][0] = 0.0f; Source->Orientation[0][1] = 0.0f; Source->Orientation[0][2] = -1.0f; @@ -2628,15 +2680,6 @@ static ALvoid InitSourceParams(ALsource *Source) Source->DistanceModel = DefaultDistanceModel; - Source->state = AL_INITIAL; - Source->new_state = AL_NONE; - Source->SourceType = AL_UNDETERMINED; - Source->OffsetType = AL_NONE; - Source->Offset = 0.0; - - ATOMIC_INIT(&Source->queue, NULL); - ATOMIC_INIT(&Source->current_buffer, NULL); - Source->Direct.Gain = 1.0f; Source->Direct.GainHF = 1.0f; Source->Direct.HFReference = LOWPASSFREQREF; @@ -2651,7 +2694,170 @@ static ALvoid InitSourceParams(ALsource *Source) Source->Send[i].LFReference = HIGHPASSFREQREF; } - ATOMIC_INIT(&Source->NeedsUpdate, AL_TRUE); + Source->state = AL_INITIAL; + Source->new_state = AL_NONE; + Source->SourceType = AL_UNDETERMINED; + Source->OffsetType = AL_NONE; + Source->Offset = 0.0; + + ATOMIC_INIT(&Source->queue, NULL); + ATOMIC_INIT(&Source->current_buffer, NULL); + + ATOMIC_INIT(&Source->Update, NULL); + ATOMIC_INIT(&Source->FreeList, NULL); +} + +static ALvoid DeinitSource(ALsource *source) +{ + ALbufferlistitem *BufferList; + struct ALsourceProps *props; + size_t count = 0; + size_t i; + + props = ATOMIC_LOAD(&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(ALbufferlistitem*, &source->queue, NULL); + while(BufferList != NULL) + { + ALbufferlistitem *next = BufferList->next; + if(BufferList->buffer != NULL) + DecrementRef(&BufferList->buffer->ref); + free(BufferList); + BufferList = next; + } + + for(i = 0;i < MAX_SENDS;++i) + { + if(source->Send[i].Slot) + DecrementRef(&source->Send[i].Slot->ref); + source->Send[i].Slot = NULL; + } +} + +void UpdateSourceProps(ALsource *source, ALuint num_sends) +{ + struct ALsourceProps *props; + size_t i; + + /* Get an unused property container, or allocate a new one as needed. */ + props = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire); + if(!props) + props = al_calloc(16, sizeof(*props)); + else + { + struct ALsourceProps *next; + do { + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &props, next, almemory_order_seq_cst, + almemory_order_consume) == 0); + } + + /* Copy in current property values. */ + ATOMIC_STORE(&props->Pitch, source->Pitch, almemory_order_relaxed); + ATOMIC_STORE(&props->Gain, source->Gain, almemory_order_relaxed); + ATOMIC_STORE(&props->OuterGain, source->OuterGain, almemory_order_relaxed); + ATOMIC_STORE(&props->MinGain, source->MinGain, almemory_order_relaxed); + ATOMIC_STORE(&props->MaxGain, source->MaxGain, almemory_order_relaxed); + ATOMIC_STORE(&props->InnerAngle, source->InnerAngle, almemory_order_relaxed); + ATOMIC_STORE(&props->OuterAngle, source->OuterAngle, almemory_order_relaxed); + ATOMIC_STORE(&props->RefDistance, source->RefDistance, almemory_order_relaxed); + ATOMIC_STORE(&props->MaxDistance, source->MaxDistance, almemory_order_relaxed); + ATOMIC_STORE(&props->RollOffFactor, source->RollOffFactor, almemory_order_relaxed); + for(i = 0;i < 3;i++) + ATOMIC_STORE(&props->Position[i], source->Position[i], almemory_order_relaxed); + for(i = 0;i < 3;i++) + ATOMIC_STORE(&props->Velocity[i], source->Velocity[i], almemory_order_relaxed); + for(i = 0;i < 3;i++) + ATOMIC_STORE(&props->Direction[i], source->Direction[i], almemory_order_relaxed); + for(i = 0;i < 2;i++) + { + size_t j; + for(j = 0;j < 3;j++) + ATOMIC_STORE(&props->Orientation[i][j], source->Orientation[i][j], + almemory_order_relaxed); + } + ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed); + ATOMIC_STORE(&props->Looping, source->Looping, almemory_order_relaxed); + ATOMIC_STORE(&props->DistanceModel, source->DistanceModel, almemory_order_relaxed); + ATOMIC_STORE(&props->DirectChannels, source->DirectChannels, almemory_order_relaxed); + + ATOMIC_STORE(&props->DryGainHFAuto, source->DryGainHFAuto, almemory_order_relaxed); + ATOMIC_STORE(&props->WetGainAuto, source->WetGainAuto, almemory_order_relaxed); + ATOMIC_STORE(&props->WetGainHFAuto, source->WetGainHFAuto, almemory_order_relaxed); + ATOMIC_STORE(&props->OuterGainHF, source->OuterGainHF, almemory_order_relaxed); + + ATOMIC_STORE(&props->AirAbsorptionFactor, source->AirAbsorptionFactor, almemory_order_relaxed); + ATOMIC_STORE(&props->RoomRolloffFactor, source->RoomRolloffFactor, almemory_order_relaxed); + ATOMIC_STORE(&props->DopplerFactor, source->DopplerFactor, almemory_order_relaxed); + + ATOMIC_STORE(&props->StereoPan[0], source->StereoPan[0], almemory_order_relaxed); + ATOMIC_STORE(&props->StereoPan[1], source->StereoPan[1], almemory_order_relaxed); + + ATOMIC_STORE(&props->Radius, source->Radius, almemory_order_relaxed); + + ATOMIC_STORE(&props->Direct.Gain, source->Direct.Gain, almemory_order_relaxed); + ATOMIC_STORE(&props->Direct.GainHF, source->Direct.GainHF, almemory_order_relaxed); + ATOMIC_STORE(&props->Direct.HFReference, source->Direct.HFReference, almemory_order_relaxed); + ATOMIC_STORE(&props->Direct.GainLF, source->Direct.GainLF, almemory_order_relaxed); + ATOMIC_STORE(&props->Direct.LFReference, source->Direct.LFReference, almemory_order_relaxed); + + for(i = 0;i < num_sends;i++) + { + ATOMIC_STORE(&props->Send[i].Slot, source->Send[i].Slot, almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].Gain, source->Send[i].Gain, almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].GainHF, source->Send[i].GainHF, almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].HFReference, source->Send[i].HFReference, + almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].GainLF, source->Send[i].GainLF, almemory_order_relaxed); + ATOMIC_STORE(&props->Send[i].LFReference, source->Send[i].LFReference, + almemory_order_relaxed); + } + + /* Set the new container for updating internal parameters. */ + props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, props, almemory_order_acq_rel); + if(props) + { + /* If there was an unused update container, put it back in the + * freelist. + */ + struct ALsourceProps *first = ATOMIC_LOAD(&source->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &first, props) == 0); + } +} + +void UpdateAllSourceProps(ALCcontext *context) +{ + ALuint num_sends = context->Device->NumAuxSends; + ALsizei pos; + for(pos = 0;pos < context->VoiceCount;pos++) + { + ALvoice *voice = &context->Voices[pos]; + ALsource *source = voice->Source; + if(source != NULL && (source->state == AL_PLAYING || + source->state == AL_PAUSED)) + UpdateSourceProps(source, num_sends); + } + } @@ -2749,11 +2955,10 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } if(BufferList->buffer->FmtChannels == FmtMono) - voice->Update = CalcSourceParams; + voice->Update = CalcAttnSourceParams; else voice->Update = CalcNonAttnSourceParams; - - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); + UpdateSourceProps(Source, device->NumAuxSends); } else if(state == AL_PAUSED) { @@ -3084,30 +3289,13 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac) */ ALvoid ReleaseALSources(ALCcontext *Context) { - ALbufferlistitem *item; ALsizei pos; - ALuint j; for(pos = 0;pos < Context->SourceMap.size;pos++) { ALsource *temp = Context->SourceMap.array[pos].value; Context->SourceMap.array[pos].value = NULL; - item = ATOMIC_EXCHANGE(ALbufferlistitem*, &temp->queue, NULL); - while(item != NULL) - { - ALbufferlistitem *next = item->next; - if(item->buffer != NULL) - DecrementRef(&item->buffer->ref); - free(item); - item = next; - } - - for(j = 0;j < MAX_SENDS;++j) - { - if(temp->Send[j].Slot) - DecrementRef(&temp->Send[j].Slot->ref); - temp->Send[j].Slot = NULL; - } + DeinitSource(temp); FreeThunkEntry(temp->id); memset(temp, 0, sizeof(*temp)); diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index c0c2ca82..e8a8d391 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -62,7 +62,11 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -86,7 +90,11 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability) default: SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } done: WriteUnlock(&context->PropLock); @@ -148,7 +156,7 @@ AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = context->DeferUpdates; + value = ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -188,7 +196,7 @@ AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = (ALdouble)context->DeferUpdates; + value = (ALdouble)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -228,7 +236,7 @@ AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = (ALfloat)context->DeferUpdates; + value = (ALfloat)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -268,7 +276,7 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = (ALint)context->DeferUpdates; + value = (ALint)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -308,7 +316,7 @@ AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - value = (ALint64SOFT)context->DeferUpdates; + value = (ALint64SOFT)ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); break; default: @@ -554,7 +562,11 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value) WriteLock(&context->PropLock); context->DopplerFactor = value; - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } WriteUnlock(&context->PropLock); done: @@ -573,7 +585,11 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value) WriteLock(&context->PropLock); context->DopplerVelocity = value; - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } WriteUnlock(&context->PropLock); done: @@ -592,7 +608,11 @@ AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value) WriteLock(&context->PropLock); context->SpeedOfSound = value; - UpdateListenerProps(context); + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } WriteUnlock(&context->PropLock); done: @@ -615,7 +635,13 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) WriteLock(&context->PropLock); context->DistanceModel = value; if(!context->SourceDistanceModel) - UpdateListenerProps(context); + { + if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) + { + UpdateListenerProps(context); + UpdateAllSourceProps(context); + } + } WriteUnlock(&context->PropLock); done: -- cgit v1.2.3 From 56c6b3f56cfd300ce62b6dc932a241ac619cb086 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 16 May 2016 14:46:06 -0700 Subject: Don't store the source's update method with the voice --- Alc/ALu.c | 80 ++++++++++++++++++++++++--------------------- OpenAL32/Include/alSource.h | 3 -- OpenAL32/Include/alu.h | 3 -- OpenAL32/alSource.c | 4 --- 4 files changed, 42 insertions(+), 48 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 34c36d5b..4fb9d8e5 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -129,7 +129,7 @@ static inline ALfloat aluDotproduct(const aluVector *vec1, const aluVector *vec2 return vec1->v[0]*vec2->v[0] + vec1->v[1]*vec2->v[1] + vec1->v[2]*vec2->v[2]; } -static inline ALfloat aluNormalize(ALfloat *vec) +static ALfloat aluNormalize(ALfloat *vec) { ALfloat length = sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]); if(length > 0.0f) @@ -163,7 +163,7 @@ static inline ALdouble aluNormalized(ALdouble *vec) return length; } -static inline ALvoid aluMatrixdFloat3(ALfloat *vec, ALfloat w, const aluMatrixd *mtx) +static void aluMatrixdFloat3(ALfloat *vec, ALfloat w, const aluMatrixd *mtx) { ALdouble v[4] = { vec[0], vec[1], vec[2], w }; @@ -181,7 +181,7 @@ static inline ALvoid aluMatrixdDouble3(ALdouble *vec, ALdouble w, const aluMatri vec[2] = v[0]*mtx->m[0][2] + v[1]*mtx->m[1][2] + v[2]*mtx->m[2][2] + v[3]*mtx->m[3][2]; } -static inline aluVector aluMatrixdVector(const aluMatrixd *mtx, const aluVector *vec) +static aluVector aluMatrixdVector(const aluMatrixd *mtx, const aluVector *vec) { aluVector v; v.v[0] = (ALfloat)(vec->v[0]*mtx->m[0][0] + vec->v[1]*mtx->m[1][0] + vec->v[2]*mtx->m[2][0] + vec->v[3]*mtx->m[3][0]); @@ -381,41 +381,8 @@ static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) &slot->FreeList, &first, props) == 0); } -static void CalcSourceParams(ALvoice *voice, ALCcontext *context) -{ - ALsource *source = voice->Source; - ALbufferlistitem *BufferListItem; - struct ALsourceProps *first; - struct ALsourceProps *props; - - props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel); - if(!props) return; - BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); - while(BufferListItem != NULL) - { - ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) - { - voice->Update(voice, props, buffer, context); - break; - } - BufferListItem = BufferListItem->next; - } - - /* WARNING: A livelock is theoretically possible if another thread keeps - * changing the freelist head without giving this a chance to actually swap - * in the old container (practically impossible with this little code, - * but...). - */ - first = ATOMIC_LOAD(&source->FreeList); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, - &source->FreeList, &first, props) == 0); -} - -ALvoid CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f, 0.0f } @@ -859,7 +826,7 @@ ALvoid CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props } } -ALvoid CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { const ALCdevice *Device = ALContext->Device; const ALlistener *Listener = ALContext->Listener; @@ -1338,6 +1305,43 @@ ALvoid CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, c } } +static void CalcSourceParams(ALvoice *voice, ALCcontext *context) +{ + ALsource *source = voice->Source; + ALbufferlistitem *BufferListItem; + struct ALsourceProps *first; + struct ALsourceProps *props; + + props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel); + if(!props) return; + + BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); + while(BufferListItem != NULL) + { + ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + if(buffer->FmtChannels == FmtMono) + CalcAttnSourceParams(voice, props, buffer, context); + else + CalcNonAttnSourceParams(voice, props, buffer, context); + break; + } + BufferListItem = BufferListItem->next; + } + + /* WARNING: A livelock is theoretically possible if another thread keeps + * changing the freelist head without giving this a chance to actually swap + * in the old container (practically impossible with this little code, + * but...). + */ + first = ATOMIC_LOAD(&source->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &first, props) == 0); +} + static void UpdateContextSources(ALCcontext *ctx) { diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 6d915153..4a15cea1 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -25,9 +25,6 @@ typedef struct ALbufferlistitem { typedef struct ALvoice { struct ALsource *volatile Source; - /** Method to update mixing parameters. */ - ALvoid (*Update)(struct ALvoice *self, const struct ALsourceProps *props, const struct ALbuffer *ALBuffer, const ALCcontext *context); - /** Current target parameters used for mixing. */ ALint Step; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index fc58bfb1..c70c8cff 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -374,9 +374,6 @@ void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); -ALvoid CalcAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext); -ALvoid CalcNonAttnSourceParams(struct ALvoice *voice, const struct ALsourceProps *props, const struct ALbuffer *buffer, const ALCcontext *ALContext); - ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo); ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 1124c9c3..090b4659 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2965,10 +2965,6 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } } - if(BufferList->buffer->FmtChannels == FmtMono) - voice->Update = CalcAttnSourceParams; - else - voice->Update = CalcNonAttnSourceParams; UpdateSourceProps(Source, device->NumAuxSends); } else if(state == AL_PAUSED) -- cgit v1.2.3 From aff725cba3f64cb668acf64b8f547a128a8976d1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 17 May 2016 20:02:46 -0700 Subject: Avoid redundantly storing distance model settings --- Alc/ALu.c | 8 +------- OpenAL32/Include/alListener.h | 6 ------ OpenAL32/Include/alSource.h | 2 +- OpenAL32/alListener.c | 4 ---- OpenAL32/alSource.c | 15 +++++++++------ OpenAL32/alState.c | 9 --------- 6 files changed, 11 insertions(+), 33 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 4c7000d7..8be22e66 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -278,10 +278,6 @@ static void CalcListenerParams(ALCcontext *Context) Listener->Params.SpeedOfSound = ATOMIC_LOAD(&props->SpeedOfSound, almemory_order_relaxed) * ATOMIC_LOAD(&props->DopplerVelocity, almemory_order_relaxed); - Listener->Params.SourceDistanceModel = ATOMIC_LOAD(&props->SourceDistanceModel, - almemory_order_relaxed); - Listener->Params.DistanceModel = ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed); - /* WARNING: A livelock is theoretically possible if another thread keeps * changing the freelist head without giving this a chance to actually swap * in the old container (practically impossible with this little code, @@ -941,9 +937,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro Attenuation = 1.0f; for(i = 0;i < NumSends;i++) RoomAttenuation[i] = 1.0f; - switch(Listener->Params.SourceDistanceModel ? - ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed) : - Listener->Params.DistanceModel) + switch(ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed)) { case InverseDistanceClamped: ClampedDist = clampf(ClampedDist, MinDist, MaxDist); diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index 3008f7bc..a10d6728 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -20,9 +20,6 @@ struct ALlistenerProps { ATOMIC(ALfloat) DopplerVelocity; ATOMIC(ALfloat) SpeedOfSound; - ATOMIC(ALboolean) SourceDistanceModel; - ATOMIC(enum DistanceModel) DistanceModel; - ATOMIC(struct ALlistenerProps*) next; }; @@ -52,9 +49,6 @@ typedef struct ALlistener { ALfloat DopplerFactor; ALfloat SpeedOfSound; - - ALboolean SourceDistanceModel; - enum DistanceModel DistanceModel; } Params; } ALlistener; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 4a15cea1..fbd63ce2 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -205,7 +205,7 @@ inline struct ALsource *LookupSource(ALCcontext *context, ALuint id) inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) { return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); } -void UpdateSourceProps(ALsource *source, ALuint num_sends); +void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *context); void UpdateAllSourceProps(ALCcontext *context); ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source); diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index c59d644b..c7f4955a 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -514,10 +514,6 @@ void UpdateListenerProps(ALCcontext *context) ATOMIC_STORE(&props->DopplerVelocity, context->DopplerVelocity, almemory_order_relaxed); ATOMIC_STORE(&props->SpeedOfSound, context->SpeedOfSound, almemory_order_relaxed); - ATOMIC_STORE(&props->SourceDistanceModel, context->SourceDistanceModel, - almemory_order_relaxed); - ATOMIC_STORE(&props->DistanceModel, context->DistanceModel, almemory_order_relaxed); - /* Set the new container for updating internal parameters. */ props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &listener->Update, props, almemory_order_acq_rel); if(props) diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 090b4659..780e9061 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -385,7 +385,7 @@ static ALint Int64ValsByProp(ALenum prop) #define DO_UPDATEPROPS() do { \ if(SourceShouldUpdate(Source, Context)) \ - UpdateSourceProps(Source, device->NumAuxSends); \ + UpdateSourceProps(Source, device->NumAuxSends, Context); \ } while(0) static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALfloat *values) @@ -834,7 +834,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p /* We must force an update if the auxiliary slot changed on a * playing source, in case the slot is about to be deleted. */ - UpdateSourceProps(Source, device->NumAuxSends); + UpdateSourceProps(Source, device->NumAuxSends, Context); } else { @@ -2750,7 +2750,7 @@ static ALvoid DeinitSource(ALsource *source) } } -void UpdateSourceProps(ALsource *source, ALuint num_sends) +void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *context) { struct ALsourceProps *props; size_t i; @@ -2795,7 +2795,10 @@ void UpdateSourceProps(ALsource *source, ALuint num_sends) } ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed); ATOMIC_STORE(&props->Looping, source->Looping, almemory_order_relaxed); - ATOMIC_STORE(&props->DistanceModel, source->DistanceModel, almemory_order_relaxed); + ATOMIC_STORE(&props->DistanceModel, + context->SourceDistanceModel ? source->DistanceModel : context->DistanceModel, + almemory_order_relaxed + ); ATOMIC_STORE(&props->DirectChannels, source->DirectChannels, almemory_order_relaxed); ATOMIC_STORE(&props->DryGainHFAuto, source->DryGainHFAuto, almemory_order_relaxed); @@ -2863,7 +2866,7 @@ void UpdateAllSourceProps(ALCcontext *context) ALsource *source = voice->Source; if(source != NULL && (source->state == AL_PLAYING || source->state == AL_PAUSED)) - UpdateSourceProps(source, num_sends); + UpdateSourceProps(source, num_sends, context); } /* Now with all updates declared, let the mixer continue applying them so * they all happen at once. @@ -2965,7 +2968,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } } - UpdateSourceProps(Source, device->NumAuxSends); + UpdateSourceProps(Source, device->NumAuxSends, Context); } else if(state == AL_PAUSED) { diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index e8a8d391..443ab884 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -63,10 +63,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); UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -91,10 +88,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); UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -637,10 +631,7 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value) if(!context->SourceDistanceModel) { if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { - UpdateListenerProps(context); UpdateAllSourceProps(context); - } } WriteUnlock(&context->PropLock); -- cgit v1.2.3 From 7bf64eaee0788b7eb64c7410384a9ee66f75c4ce Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 19 May 2016 20:50:55 -0700 Subject: Make the source position calues atomic --- Alc/ALu.c | 4 ++-- Alc/mixer.c | 14 +++++++------- OpenAL32/Include/alSource.h | 4 ++-- OpenAL32/alSource.c | 39 ++++++++++++++++++++------------------- 4 files changed, 31 insertions(+), 30 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 44361979..ec0dd011 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1619,8 +1619,8 @@ ALvoid aluHandleDisconnect(ALCdevice *device) { source->state = AL_STOPPED; ATOMIC_STORE(&source->current_buffer, NULL); - source->position = 0; - source->position_fraction = 0; + ATOMIC_STORE(&source->position, 0); + ATOMIC_STORE(&source->position_fraction, 0); } voice++; diff --git a/Alc/mixer.c b/Alc/mixer.c index 38ec295c..1ee422be 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -384,10 +384,10 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam ALuint chan, j; /* Get source info */ - State = Source->state; + State = AL_PLAYING; /* Only called while playing. */ BufferListItem = ATOMIC_LOAD(&Source->current_buffer); - DataPosInt = Source->position; - DataPosFrac = Source->position_fraction; + DataPosInt = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); + DataPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); NumChannels = Source->NumChannels; SampleSize = Source->SampleSize; Looping = voice->Looping; @@ -752,8 +752,8 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam voice->Moving = AL_TRUE; /* Update source info */ - Source->state = State; - ATOMIC_STORE(&Source->current_buffer, BufferListItem); - Source->position = DataPosInt; - Source->position_fraction = DataPosFrac; + Source->state = State; + ATOMIC_STORE(&Source->current_buffer, BufferListItem, almemory_order_relaxed); + ATOMIC_STORE(&Source->position, DataPosInt, almemory_order_relaxed); + ATOMIC_STORE(&Source->position_fraction, DataPosFrac); } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index fbd63ce2..bb1e6434 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -172,8 +172,8 @@ typedef struct ALsource { * the whole queue, and the fractional (fixed-point) offset to the next * sample. */ - ALuint position; - ALuint position_fraction; + ATOMIC(ALuint) position; + ATOMIC(ALuint) position_fraction; /** Source Buffer Queue info. */ ATOMIC(ALbufferlistitem*) queue; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 780e9061..a0e40c1d 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2904,8 +2904,8 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_PAUSED) { Source->state = AL_PLAYING; - Source->position = 0; - Source->position_fraction = 0; + ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); + ATOMIC_STORE(&Source->position_fraction, 0, almemory_order_relaxed); ATOMIC_STORE(&Source->current_buffer, BufferList); discontinuity = AL_TRUE; } @@ -2991,8 +2991,8 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_INITIAL) { Source->state = AL_INITIAL; - Source->position = 0; - Source->position_fraction = 0; + ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); + ATOMIC_STORE(&Source->position_fraction, 0, almemory_order_relaxed); ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD(&Source->queue)); } Source->OffsetType = AL_NONE; @@ -3022,10 +3022,11 @@ ALint64 GetSourceSampleOffset(ALsource *Source) /* NOTE: This is the offset into the *current* buffer, so add the length of * any played buffers */ - readPos = (ALuint64)Source->position << 32; - readPos |= (ALuint64)Source->position_fraction << (32-FRACTIONBITS); - BufferList = ATOMIC_LOAD(&Source->queue); - Current = ATOMIC_LOAD(&Source->current_buffer); + readPos = (ALuint64)ATOMIC_LOAD(&Source->position) << 32; + readPos |= (ALuint64)ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed) << + (32-FRACTIONBITS); + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); + Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); while(BufferList && BufferList != Current) { if(BufferList->buffer) @@ -3058,10 +3059,10 @@ static ALdouble GetSourceSecOffset(ALsource *Source) /* NOTE: This is the offset into the *current* buffer, so add the length of * any played buffers */ - readPos = (ALuint64)Source->position << FRACTIONBITS; - readPos |= (ALuint64)Source->position_fraction; - BufferList = ATOMIC_LOAD(&Source->queue); - Current = ATOMIC_LOAD(&Source->current_buffer); + readPos = (ALuint64)ATOMIC_LOAD(&Source->position) << FRACTIONBITS; + readPos |= (ALuint64)ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); + Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); while(BufferList && BufferList != Current) { const ALbuffer *buffer = BufferList->buffer; @@ -3110,10 +3111,10 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name) /* NOTE: This is the offset into the *current* buffer, so add the length of * any played buffers */ totalBufferLen = 0; - readPos = Source->position; - readPosFrac = Source->position_fraction; - BufferList = ATOMIC_LOAD(&Source->queue); - Current = ATOMIC_LOAD(&Source->current_buffer); + readPos = ATOMIC_LOAD(&Source->position); + readPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); + Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); while(BufferList != NULL) { const ALbuffer *buffer; @@ -3205,10 +3206,10 @@ ALboolean ApplyOffset(ALsource *Source) if(bufferLen > offset-totalBufferLen) { /* Offset is in this buffer */ - ATOMIC_STORE(&Source->current_buffer, BufferList); + ATOMIC_STORE(&Source->current_buffer, BufferList, almemory_order_relaxed); - Source->position = offset - totalBufferLen; - Source->position_fraction = frac; + ATOMIC_STORE(&Source->position, offset - totalBufferLen, almemory_order_relaxed); + ATOMIC_STORE(&Source->position_fraction, frac); return AL_TRUE; } -- cgit v1.2.3 From a16d0b192e9833ae0abd6e1e7ef2305c34705497 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 1 Jun 2016 10:21:16 -0700 Subject: Make a function static --- OpenAL32/Include/alSource.h | 1 - OpenAL32/alSource.c | 13 +++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index bb1e6434..a3e84e0e 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -205,7 +205,6 @@ inline struct ALsource *LookupSource(ALCcontext *context, ALuint id) inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) { return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); } -void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *context); void UpdateAllSourceProps(ALCcontext *context); ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index c1824d5b..5cc6c34b 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -47,8 +47,9 @@ extern inline void UnlockSourcesWrite(ALCcontext *context); extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); -static ALvoid InitSourceParams(ALsource *Source); -static ALvoid DeinitSource(ALsource *source); +static void InitSourceParams(ALsource *Source); +static void DeinitSource(ALsource *source); +static void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *context); static ALint64 GetSourceSampleOffset(ALsource *Source, ALCdevice *device, ALuint64 *clocktime); static ALdouble GetSourceSecOffset(ALsource *Source, ALCdevice *device, ALuint64 *clocktime); static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device); @@ -2665,7 +2666,7 @@ done: } -static ALvoid InitSourceParams(ALsource *Source) +static void InitSourceParams(ALsource *Source) { ALuint i; @@ -2741,7 +2742,7 @@ static ALvoid InitSourceParams(ALsource *Source) ATOMIC_INIT(&Source->FreeList, NULL); } -static ALvoid DeinitSource(ALsource *source) +static void DeinitSource(ALsource *source) { ALbufferlistitem *BufferList; struct ALsourceProps *props; @@ -2784,7 +2785,7 @@ static ALvoid DeinitSource(ALsource *source) } } -void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *context) +static void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *context) { struct ALsourceProps *props; size_t i; @@ -2825,7 +2826,7 @@ void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *context) size_t j; for(j = 0;j < 3;j++) ATOMIC_STORE(&props->Orientation[i][j], source->Orientation[i][j], - almemory_order_relaxed); + almemory_order_relaxed); } ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed); ATOMIC_STORE(&props->Looping, source->Looping, almemory_order_relaxed); -- cgit v1.2.3 From ce676ab70a6b4c46869e4fa13e14b4da7ba6c008 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 3 Jun 2016 05:46:29 -0700 Subject: Remove some unnecessary volatile keywords --- OpenAL32/Include/alAuxEffectSlot.h | 4 +-- OpenAL32/Include/alSource.h | 62 +++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 33 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 8d2fc3d7..034ac217 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -86,8 +86,8 @@ struct ALeffectslotProps { typedef struct ALeffectslot { - volatile ALfloat Gain; - volatile ALboolean AuxSendAuto; + ALfloat Gain; + ALboolean AuxSendAuto; struct { ALenum Type; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index a3e84e0e..49bda7e4 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -101,40 +101,40 @@ struct ALsourceProps { typedef struct ALsource { /** Source properties. */ - volatile ALfloat Pitch; - volatile ALfloat Gain; - volatile ALfloat OuterGain; - volatile ALfloat MinGain; - volatile ALfloat MaxGain; - volatile ALfloat InnerAngle; - volatile ALfloat OuterAngle; - volatile ALfloat RefDistance; - volatile ALfloat MaxDistance; - volatile ALfloat RollOffFactor; - volatile ALfloat Position[3]; - volatile ALfloat Velocity[3]; - volatile ALfloat Direction[3]; - volatile ALfloat Orientation[2][3]; - volatile ALboolean HeadRelative; - volatile ALboolean Looping; - volatile enum DistanceModel DistanceModel; - volatile ALboolean DirectChannels; - - volatile ALboolean DryGainHFAuto; - volatile ALboolean WetGainAuto; - volatile ALboolean WetGainHFAuto; - volatile ALfloat OuterGainHF; - - volatile ALfloat AirAbsorptionFactor; - volatile ALfloat RoomRolloffFactor; - volatile ALfloat DopplerFactor; + 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; + ALboolean Looping; + enum DistanceModel DistanceModel; + ALboolean DirectChannels; + + ALboolean DryGainHFAuto; + ALboolean WetGainAuto; + ALboolean WetGainHFAuto; + ALfloat OuterGainHF; + + ALfloat AirAbsorptionFactor; + ALfloat RoomRolloffFactor; + ALfloat DopplerFactor; /* NOTE: Stereo pan angles are specified in radians, counter-clockwise * rather than clockwise. */ - volatile ALfloat StereoPan[2]; + ALfloat StereoPan[2]; - volatile ALfloat Radius; + ALfloat Radius; /** Direct filter and auxiliary send info. */ struct { @@ -161,10 +161,10 @@ typedef struct ALsource { ALenum OffsetType; /** Source type (static, streaming, or undetermined) */ - volatile ALint SourceType; + ALint SourceType; /** Source state (initial, playing, paused, or stopped) */ - volatile ALenum state; + ALenum state; ALenum new_state; /** -- cgit v1.2.3 From 0aae992f946c397dbed79b0b7dd41fb1f9fe0087 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 7 Jul 2016 19:48:21 -0700 Subject: Reorder some source fields --- OpenAL32/Include/alSource.h | 10 +++++----- OpenAL32/alSource.c | 41 ++++++++++++++++++++++------------------- 2 files changed, 27 insertions(+), 24 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 49bda7e4..4b047b80 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -167,6 +167,11 @@ typedef struct ALsource { ALenum state; ALenum new_state; + /** Source Buffer Queue info. */ + RWLock queue_lock; + ATOMIC(ALbufferlistitem*) queue; + ATOMIC(ALbufferlistitem*) current_buffer; + /** * Source offset in samples, relative to the currently playing buffer, NOT * the whole queue, and the fractional (fixed-point) offset to the next @@ -175,11 +180,6 @@ typedef struct ALsource { ATOMIC(ALuint) position; ATOMIC(ALuint) position_fraction; - /** Source Buffer Queue info. */ - ATOMIC(ALbufferlistitem*) queue; - ATOMIC(ALbufferlistitem*) current_buffer; - RWLock queue_lock; - /** Current buffer sample info. */ ALuint NumChannels; ALuint SampleSize; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 7d34f368..46467b01 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2729,15 +2729,18 @@ static void InitSourceParams(ALsource *Source) Source->Send[i].LFReference = HIGHPASSFREQREF; } + Source->Offset = 0.0; + Source->OffsetType = AL_NONE; + Source->SourceType = AL_UNDETERMINED; Source->state = AL_INITIAL; Source->new_state = AL_NONE; - Source->SourceType = AL_UNDETERMINED; - Source->OffsetType = AL_NONE; - Source->Offset = 0.0; ATOMIC_INIT(&Source->queue, NULL); ATOMIC_INIT(&Source->current_buffer, NULL); + ATOMIC_INIT(&Source->position, 0); + ATOMIC_INIT(&Source->position_fraction, 0); + ATOMIC_INIT(&Source->Update, NULL); ATOMIC_INIT(&Source->FreeList, NULL); } @@ -2939,9 +2942,9 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_PAUSED) { Source->state = AL_PLAYING; + ATOMIC_STORE(&Source->current_buffer, BufferList, almemory_order_relaxed); ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, 0, almemory_order_relaxed); - ATOMIC_STORE(&Source->current_buffer, BufferList); + ATOMIC_STORE(&Source->position_fraction, 0); discontinuity = AL_TRUE; } else @@ -3033,9 +3036,10 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->state != AL_INITIAL) { Source->state = AL_INITIAL; + ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD(&Source->queue), + almemory_order_relaxed); ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, 0, almemory_order_relaxed); - ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD(&Source->queue)); + ATOMIC_STORE(&Source->position_fraction, 0); } Source->OffsetType = AL_NONE; Source->Offset = 0.0; @@ -3072,13 +3076,13 @@ ALint64 GetSourceSampleOffset(ALsource *Source, ALCdevice *device, ALuint64 *clo while(((refcount=ReadRef(&device->MixCount))&1)) althrd_yield(); *clocktime = GetDeviceClockTime(device); - /* NOTE: This is the offset into the *current* buffer, so add the length of - * any played buffers */ + + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); + Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); + readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed) << 32; readPos |= (ALuint64)ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed) << (32-FRACTIONBITS); - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); - Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); } while(refcount != ReadRef(&device->MixCount)); while(BufferList && BufferList != Current) { @@ -3120,12 +3124,12 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCdevice *device, ALuint64 while(((refcount=ReadRef(&device->MixCount))&1)) althrd_yield(); *clocktime = GetDeviceClockTime(device); - /* NOTE: This is the offset into the *current* buffer, so add the length of - * any played buffers */ - readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed) << FRACTIONBITS; - readPos |= (ALuint64)ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); + + readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed)<position_fraction, almemory_order_relaxed); } while(refcount != ReadRef(&device->MixCount)); while(BufferList && BufferList != Current) { @@ -3177,12 +3181,11 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device do { while(((refcount=ReadRef(&device->MixCount))&1)) althrd_yield(); - /* NOTE: This is the offset into the *current* buffer, so add the length of - * any played buffers */ - readPos = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); - readPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); + + readPos = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); + readPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); } while(refcount != ReadRef(&device->MixCount)); while(BufferList != NULL) -- cgit v1.2.3 From 14166264d6fc59386d9cbbfcd12c78ffab5989fb Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 11 Jul 2016 23:30:32 -0700 Subject: Store the voice output buffers separate from the params --- Alc/ALu.c | 40 ++++++++++++++++++++-------------------- Alc/mixer.c | 28 ++++++++++++++-------------- OpenAL32/Include/alSource.h | 10 ++++++++++ OpenAL32/Include/alu.h | 6 ------ 4 files changed, 44 insertions(+), 40 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index ac958d41..ecf89d59 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -418,8 +418,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * StereoMap[0].angle = -ATOMIC_LOAD(&props->StereoPan[0], almemory_order_relaxed); StereoMap[1].angle = -ATOMIC_LOAD(&props->StereoPan[1], almemory_order_relaxed); - voice->Direct.OutBuffer = Device->Dry.Buffer; - voice->Direct.OutChannels = Device->Dry.NumChannels; + voice->DirectOut.Buffer = Device->Dry.Buffer; + voice->DirectOut.Channels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); @@ -428,13 +428,13 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) { SendSlots[i] = NULL; - voice->Send[i].OutBuffer = NULL; - voice->Send[i].OutChannels = 0; + voice->SendOut[i].Buffer = NULL; + voice->SendOut[i].Channels = 0; } else { - voice->Send[i].OutBuffer = SendSlots[i]->WetBuffer; - voice->Send[i].OutChannels = SendSlots[i]->NumChannels; + voice->SendOut[i].Buffer = SendSlots[i]->WetBuffer; + voice->SendOut[i].Channels = SendSlots[i]->NumChannels; } } voice->Looping = ATOMIC_LOAD(&props->Looping, almemory_order_relaxed); @@ -544,8 +544,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * 0.0f, -V[0]*scale, V[1]*scale, -V[2]*scale ); - voice->Direct.OutBuffer = Device->FOAOut.Buffer; - voice->Direct.OutChannels = Device->FOAOut.NumChannels; + voice->DirectOut.Buffer = Device->FOAOut.Buffer; + voice->DirectOut.Channels = Device->FOAOut.NumChannels; for(c = 0;c < num_channels;c++) ComputeFirstOrderGains(Device->FOAOut, matrix.m[c], DryGain, voice->Direct.Gains[c].Target); @@ -580,8 +580,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(DirectChannels) { /* Skip the virtual channels and write inputs to the real output. */ - voice->Direct.OutBuffer = Device->RealOut.Buffer; - voice->Direct.OutChannels = Device->RealOut.NumChannels; + voice->DirectOut.Buffer = Device->RealOut.Buffer; + voice->DirectOut.Channels = Device->RealOut.NumChannels; for(c = 0;c < num_channels;c++) { int idx; @@ -620,8 +620,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * /* Full HRTF rendering. Skip the virtual channels and render each * input channel to the real outputs. */ - voice->Direct.OutBuffer = Device->RealOut.Buffer; - voice->Direct.OutChannels = Device->RealOut.NumChannels; + voice->DirectOut.Buffer = Device->RealOut.Buffer; + voice->DirectOut.Channels = Device->RealOut.NumChannels; for(c = 0;c < num_channels;c++) { if(chans[c].channel == LFE) @@ -864,8 +864,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro WetGainHFAuto = ATOMIC_LOAD(&props->WetGainHFAuto, almemory_order_relaxed); RoomRolloffBase = ATOMIC_LOAD(&props->RoomRolloffFactor, almemory_order_relaxed); - voice->Direct.OutBuffer = Device->Dry.Buffer; - voice->Direct.OutChannels = Device->Dry.NumChannels; + voice->DirectOut.Buffer = Device->Dry.Buffer; + voice->DirectOut.Channels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); @@ -897,13 +897,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro if(!SendSlots[i]) { - voice->Send[i].OutBuffer = NULL; - voice->Send[i].OutChannels = 0; + voice->SendOut[i].Buffer = NULL; + voice->SendOut[i].Channels = 0; } else { - voice->Send[i].OutBuffer = SendSlots[i]->WetBuffer; - voice->Send[i].OutChannels = SendSlots[i]->NumChannels; + voice->SendOut[i].Buffer = SendSlots[i]->WetBuffer; + voice->SendOut[i].Channels = SendSlots[i]->NumChannels; } } voice->Looping = ATOMIC_LOAD(&props->Looping, almemory_order_relaxed); @@ -1138,8 +1138,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro ALfloat coeffs[MAX_AMBI_COEFFS]; ALfloat spread = 0.0f; - voice->Direct.OutBuffer = Device->RealOut.Buffer; - voice->Direct.OutChannels = Device->RealOut.NumChannels; + voice->DirectOut.Buffer = Device->RealOut.Buffer; + voice->DirectOut.Channels = Device->RealOut.NumChannels; if(Distance > FLT_EPSILON) { diff --git a/Alc/mixer.c b/Alc/mixer.c index 094d3768..748a2357 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -569,7 +569,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam if(!Counter) { - for(j = 0;j < parms->OutChannels;j++) + for(j = 0;j < voice->DirectOut.Channels;j++) { gains[j].Target = targets[j]; gains[j].Current = gains[j].Target; @@ -578,7 +578,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } else { - for(j = 0;j < parms->OutChannels;j++) + for(j = 0;j < voice->DirectOut.Channels;j++) { ALfloat diff; gains[j].Target = targets[j]; @@ -594,10 +594,10 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } } - MixSamples(samples, parms->OutChannels, parms->OutBuffer, gains, - Counter, OutPos, DstBufferSize); + MixSamples(samples, voice->DirectOut.Channels, voice->DirectOut.Buffer, + gains, Counter, OutPos, DstBufferSize); - for(j = 0;j < parms->OutChannels;j++) + for(j = 0;j < voice->DirectOut.Channels;j++) currents[j] = gains[j].Current; } else @@ -639,9 +639,9 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam ridx = GetChannelIdxByName(Device->RealOut, FrontRight); assert(lidx != -1 && ridx != -1); - MixHrtfSamples(parms->OutBuffer, lidx, ridx, samples, Counter, voice->Offset, - OutPos, IrSize, &hrtfparams, &parms->Hrtf[chan].State, - DstBufferSize); + MixHrtfSamples(voice->DirectOut.Buffer, lidx, ridx, samples, Counter, + voice->Offset, OutPos, IrSize, &hrtfparams, + &parms->Hrtf[chan].State, DstBufferSize); } } @@ -653,7 +653,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam MixGains gains[MAX_OUTPUT_CHANNELS]; const ALfloat *samples; - if(!parms->OutBuffer) + if(!voice->SendOut[j].Buffer) continue; samples = DoFilters( @@ -664,7 +664,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam if(!Counter) { - for(j = 0;j < parms->OutChannels;j++) + for(j = 0;j < voice->SendOut[j].Channels;j++) { gains[j].Target = targets[j]; gains[j].Current = gains[j].Target; @@ -673,7 +673,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } else { - for(j = 0;j < parms->OutChannels;j++) + for(j = 0;j < voice->SendOut[j].Channels;j++) { ALfloat diff; gains[j].Target = targets[j]; @@ -689,10 +689,10 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } } - MixSamples(samples, parms->OutChannels, parms->OutBuffer, gains, - Counter, OutPos, DstBufferSize); + MixSamples(samples, voice->SendOut[j].Channels, voice->SendOut[j].Buffer, + gains, Counter, OutPos, DstBufferSize); - for(j = 0;j < parms->OutChannels;j++) + for(j = 0;j < voice->SendOut[j].Channels;j++) currents[j] = gains[j].Current; } } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 4b047b80..2dd8229c 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -41,6 +41,16 @@ typedef struct ALvoice { BsincState SincState; + struct { + ALfloat (*Buffer)[BUFFERSIZE]; + ALuint Channels; + } DirectOut; + + struct { + ALfloat (*Buffer)[BUFFERSIZE]; + ALuint Channels; + } SendOut[MAX_SENDS]; + DirectParams Direct; SendParams Send[MAX_SENDS]; } ALvoice; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index fca60b15..266c0588 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -125,9 +125,6 @@ typedef struct MixHrtfParams { } MixHrtfParams; typedef struct DirectParams { - ALfloat (*OutBuffer)[BUFFERSIZE]; - ALuint OutChannels; - struct { enum ActiveFilters ActiveType; ALfilterState LowPass; @@ -147,9 +144,6 @@ typedef struct DirectParams { } DirectParams; typedef struct SendParams { - ALfloat (*OutBuffer)[BUFFERSIZE]; - ALuint OutChannels; - struct { enum ActiveFilters ActiveType; ALfilterState LowPass; -- cgit v1.2.3 From 5106f035df7153efa411feb090ba22b1d756998b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 13 Jul 2016 01:39:44 -0700 Subject: Move the input channel array out of the DirectParams and SendParams --- Alc/ALu.c | 111 ++++++++++++++++++++++---------------------- Alc/mixer.c | 38 +++++++-------- OpenAL32/Include/alSource.h | 6 ++- OpenAL32/Include/alu.h | 22 ++++----- OpenAL32/alSource.c | 6 +-- 5 files changed, 90 insertions(+), 93 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index ecf89d59..2a94d940 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -548,7 +548,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * voice->DirectOut.Channels = Device->FOAOut.NumChannels; for(c = 0;c < num_channels;c++) ComputeFirstOrderGains(Device->FOAOut, matrix.m[c], DryGain, - voice->Direct.Gains[c].Target); + voice->Chan[c].Direct.Gains.Target); for(i = 0;i < NumSends;i++) { @@ -557,7 +557,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * for(c = 0;c < num_channels;c++) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Send[i].Gains[c].Target[j] = 0.0f; + voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; } } else @@ -566,7 +566,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * { const ALeffectslot *Slot = SendSlots[i]; ComputeFirstOrderGainsBF(Slot->ChanMap, Slot->NumChannels, matrix.m[c], - WetGain[i], voice->Send[i].Gains[c].Target); + WetGain[i], voice->Chan[c].Send[i].Gains.Target); } } } @@ -586,9 +586,9 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * { int idx; for(j = 0;j < MAX_OUTPUT_CHANNELS;j++) - voice->Direct.Gains[c].Target[j] = 0.0f; + voice->Chan[c].Direct.Gains.Target[j] = 0.0f; if((idx=GetChannelIdxByName(Device->RealOut, chans[c].channel)) != -1) - voice->Direct.Gains[c].Target[idx] = DryGain; + voice->Chan[c].Direct.Gains.Target[idx] = DryGain; } /* Auxiliary sends still use normal panning since they mix to B-Format, which can't @@ -602,13 +602,13 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(!SendSlots[i]) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Send[i].Gains[c].Target[j] = 0.0f; + voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Send[i].Gains[c].Target); + WetGain[i], voice->Chan[c].Send[i].Gains.Target); } } } @@ -627,18 +627,18 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(chans[c].channel == LFE) { /* Skip LFE */ - voice->Direct.Hrtf[c].Target.Delay[0] = 0; - voice->Direct.Hrtf[c].Target.Delay[1] = 0; + voice->Chan[c].Direct.Hrtf.Target.Delay[0] = 0; + voice->Chan[c].Direct.Hrtf.Target.Delay[1] = 0; for(i = 0;i < HRIR_LENGTH;i++) { - voice->Direct.Hrtf[c].Target.Coeffs[i][0] = 0.0f; - voice->Direct.Hrtf[c].Target.Coeffs[i][1] = 0.0f; + voice->Chan[c].Direct.Hrtf.Target.Coeffs[i][0] = 0.0f; + voice->Chan[c].Direct.Hrtf.Target.Coeffs[i][1] = 0.0f; } for(i = 0;i < NumSends;i++) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Send[i].Gains[c].Target[j] = 0.0f; + voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; } continue; @@ -647,8 +647,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * /* Get the static HRIR coefficients and delays for this channel. */ GetLerpedHrtfCoeffs(Device->Hrtf, chans[c].elevation, chans[c].angle, 0.0f, DryGain, - voice->Direct.Hrtf[c].Target.Coeffs, - voice->Direct.Hrtf[c].Target.Delay + voice->Chan[c].Direct.Hrtf.Target.Coeffs, + voice->Chan[c].Direct.Hrtf.Target.Delay ); /* Normal panning for auxiliary sends. */ @@ -659,13 +659,13 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(!SendSlots[i]) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Send[i].Gains[c].Target[j] = 0.0f; + voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Send[i].Gains[c].Target); + WetGain[i], voice->Chan[c].Send[i].Gains.Target); } } } @@ -681,19 +681,19 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(chans[c].channel == LFE) { for(j = 0;j < MAX_OUTPUT_CHANNELS;j++) - voice->Direct.Gains[c].Target[j] = 0.0f; + voice->Chan[c].Direct.Gains.Target[j] = 0.0f; if(Device->Dry.Buffer == Device->RealOut.Buffer) { int idx; if((idx=GetChannelIdxByName(Device->RealOut, chans[c].channel)) != -1) - voice->Direct.Gains[c].Target[idx] = DryGain; + voice->Chan[c].Direct.Gains.Target[idx] = DryGain; } for(i = 0;i < NumSends;i++) { ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Send[i].Gains[c].Target[j] = 0.0f; + voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; } continue; } @@ -703,10 +703,10 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * /* Clamp X so it remains within 30 degrees of 0 or 180 degree azimuth. */ ALfloat x = sinf(chans[c].angle) * cosf(chans[c].elevation); coeffs[0] = clampf(-x, -0.5f, 0.5f) + 0.5f; - voice->Direct.Gains[c].Target[0] = coeffs[0] * DryGain; - voice->Direct.Gains[c].Target[1] = (1.0f-coeffs[0]) * DryGain; + voice->Chan[c].Direct.Gains.Target[0] = coeffs[0] * DryGain; + voice->Chan[c].Direct.Gains.Target[1] = (1.0f-coeffs[0]) * DryGain; for(j = 2;j < MAX_OUTPUT_CHANNELS;j++) - voice->Direct.Gains[c].Target[j] = 0.0f; + voice->Chan[c].Direct.Gains.Target[j] = 0.0f; CalcAngleCoeffs(chans[c].angle, chans[c].elevation, 0.0f, coeffs); } @@ -714,7 +714,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * { CalcAngleCoeffs(chans[c].angle, chans[c].elevation, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, DryGain, - voice->Direct.Gains[c].Target); + voice->Chan[c].Direct.Gains.Target); } for(i = 0;i < NumSends;i++) @@ -723,13 +723,13 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * { ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Send[i].Gains[c].Target[j] = 0.0f; + voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Send[i].Gains[c].Target); + WetGain[i], voice->Chan[c].Send[i].Gains.Target); } } } @@ -747,15 +747,15 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * DryGainLF = maxf(DryGainLF, 0.0001f); for(c = 0;c < num_channels;c++) { - voice->Direct.Filters[c].ActiveType = AF_None; - if(DryGainHF != 1.0f) voice->Direct.Filters[c].ActiveType |= AF_LowPass; - if(DryGainLF != 1.0f) voice->Direct.Filters[c].ActiveType |= AF_HighPass; + voice->Chan[c].Direct.FilterType = AF_None; + if(DryGainHF != 1.0f) voice->Chan[c].Direct.FilterType |= AF_LowPass; + if(DryGainLF != 1.0f) voice->Chan[c].Direct.FilterType |= AF_HighPass; ALfilterState_setParams( - &voice->Direct.Filters[c].LowPass, ALfilterType_HighShelf, + &voice->Chan[c].Direct.LowPass, ALfilterType_HighShelf, DryGainHF, hfscale, calc_rcpQ_from_slope(DryGainHF, 0.75f) ); ALfilterState_setParams( - &voice->Direct.Filters[c].HighPass, ALfilterType_LowShelf, + &voice->Chan[c].Direct.HighPass, ALfilterType_LowShelf, DryGainLF, lfscale, calc_rcpQ_from_slope(DryGainLF, 0.75f) ); } @@ -770,15 +770,15 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * WetGainLF[i] = maxf(WetGainLF[i], 0.0001f); for(c = 0;c < num_channels;c++) { - voice->Send[i].Filters[c].ActiveType = AF_None; - if(WetGainHF[i] != 1.0f) voice->Send[i].Filters[c].ActiveType |= AF_LowPass; - if(WetGainLF[i] != 1.0f) voice->Send[i].Filters[c].ActiveType |= AF_HighPass; + voice->Chan[c].Send[i].FilterType = AF_None; + if(WetGainHF[i] != 1.0f) voice->Chan[c].Send[i].FilterType |= AF_LowPass; + if(WetGainLF[i] != 1.0f) voice->Chan[c].Send[i].FilterType |= AF_HighPass; ALfilterState_setParams( - &voice->Send[i].Filters[c].LowPass, ALfilterType_HighShelf, + &voice->Chan[c].Send[i].LowPass, ALfilterType_HighShelf, WetGainHF[i], hfscale, calc_rcpQ_from_slope(WetGainHF[i], 0.75f) ); ALfilterState_setParams( - &voice->Send[i].Filters[c].HighPass, ALfilterType_LowShelf, + &voice->Chan[c].Send[i].HighPass, ALfilterType_LowShelf, WetGainLF[i], lfscale, calc_rcpQ_from_slope(WetGainLF[i], 0.75f) ); } @@ -1161,8 +1161,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro /* Get the HRIR coefficients and delays. */ GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, spread, DryGain, - voice->Direct.Hrtf[0].Target.Coeffs, - voice->Direct.Hrtf[0].Target.Delay); + voice->Chan[0].Direct.Hrtf.Target.Coeffs, + voice->Chan[0].Direct.Hrtf.Target.Delay); CalcDirectionCoeffs(dir, spread, coeffs); @@ -1172,13 +1172,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro { ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Send[i].Gains[0].Target[j] = 0.0f; + voice->Chan[0].Send[i].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Send[i].Gains[0].Target); + WetGain[i], voice->Chan[0].Send[i].Gains.Target); } } @@ -1209,17 +1209,18 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro /* Clamp X so it remains within 30 degrees of 0 or 180 degree azimuth. */ ALfloat x = -dir[0] * (0.5f * (cosf(spread*0.5f) + 1.0f)); x = clampf(x, -0.5f, 0.5f) + 0.5f; - voice->Direct.Gains[0].Target[0] = x * DryGain; - voice->Direct.Gains[0].Target[1] = (1.0f-x) * DryGain; + voice->Chan[0].Direct.Gains.Target[0] = x * DryGain; + voice->Chan[0].Direct.Gains.Target[1] = (1.0f-x) * DryGain; for(i = 2;i < MAX_OUTPUT_CHANNELS;i++) - voice->Direct.Gains[0].Target[i] = 0.0f; + voice->Chan[0].Direct.Gains.Target[i] = 0.0f; CalcDirectionCoeffs(dir, spread, coeffs); } else { CalcDirectionCoeffs(dir, spread, coeffs); - ComputePanningGains(Device->Dry, coeffs, DryGain, voice->Direct.Gains[0].Target); + ComputePanningGains(Device->Dry, coeffs, DryGain, + voice->Chan[0].Direct.Gains.Target); } for(i = 0;i < NumSends;i++) @@ -1228,13 +1229,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro { ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Send[i].Gains[0].Target[j] = 0.0f; + voice->Chan[0].Send[i].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Send[i].Gains[0].Target); + WetGain[i], voice->Chan[0].Send[i].Gains.Target); } } @@ -1248,15 +1249,15 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro Frequency; DryGainHF = maxf(DryGainHF, 0.0001f); DryGainLF = maxf(DryGainLF, 0.0001f); - voice->Direct.Filters[0].ActiveType = AF_None; - if(DryGainHF != 1.0f) voice->Direct.Filters[0].ActiveType |= AF_LowPass; - if(DryGainLF != 1.0f) voice->Direct.Filters[0].ActiveType |= AF_HighPass; + voice->Chan[0].Direct.FilterType = AF_None; + if(DryGainHF != 1.0f) voice->Chan[0].Direct.FilterType |= AF_LowPass; + if(DryGainLF != 1.0f) voice->Chan[0].Direct.FilterType |= AF_HighPass; ALfilterState_setParams( - &voice->Direct.Filters[0].LowPass, ALfilterType_HighShelf, + &voice->Chan[0].Direct.LowPass, ALfilterType_HighShelf, DryGainHF, hfscale, calc_rcpQ_from_slope(DryGainHF, 0.75f) ); ALfilterState_setParams( - &voice->Direct.Filters[0].HighPass, ALfilterType_LowShelf, + &voice->Chan[0].Direct.HighPass, ALfilterType_LowShelf, DryGainLF, lfscale, calc_rcpQ_from_slope(DryGainLF, 0.75f) ); } @@ -1268,15 +1269,15 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0001f); WetGainLF[i] = maxf(WetGainLF[i], 0.0001f); - voice->Send[i].Filters[0].ActiveType = AF_None; - if(WetGainHF[i] != 1.0f) voice->Send[i].Filters[0].ActiveType |= AF_LowPass; - if(WetGainLF[i] != 1.0f) voice->Send[i].Filters[0].ActiveType |= AF_HighPass; + voice->Chan[0].Send[i].FilterType = AF_None; + if(WetGainHF[i] != 1.0f) voice->Chan[0].Send[i].FilterType |= AF_LowPass; + if(WetGainLF[i] != 1.0f) voice->Chan[0].Send[i].FilterType |= AF_HighPass; ALfilterState_setParams( - &voice->Send[i].Filters[0].LowPass, ALfilterType_HighShelf, + &voice->Chan[0].Send[i].LowPass, ALfilterType_HighShelf, WetGainHF[i], hfscale, calc_rcpQ_from_slope(WetGainHF[i], 0.75f) ); ALfilterState_setParams( - &voice->Send[i].Filters[0].HighPass, ALfilterType_LowShelf, + &voice->Chan[0].Send[i].HighPass, ALfilterType_LowShelf, WetGainLF[i], lfscale, calc_rcpQ_from_slope(WetGainLF[i], 0.75f) ); } diff --git a/Alc/mixer.c b/Alc/mixer.c index 748a2357..1d14f890 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -553,18 +553,17 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam Device->ResampledData, DstBufferSize ); { - DirectParams *parms = &voice->Direct; + DirectParams *parms = &voice->Chan[chan].Direct; const ALfloat *samples; samples = DoFilters( - &parms->Filters[chan].LowPass, &parms->Filters[chan].HighPass, - Device->FilteredData, ResampledData, DstBufferSize, - parms->Filters[chan].ActiveType + &parms->LowPass, &parms->HighPass, Device->FilteredData, + ResampledData, DstBufferSize, parms->FilterType ); if(!voice->IsHrtf) { - ALfloat *restrict currents = parms->Gains[chan].Current; - const ALfloat *targets = parms->Gains[chan].Target; + ALfloat *restrict currents = parms->Gains.Current; + const ALfloat *targets = parms->Gains.Target; MixGains gains[MAX_OUTPUT_CHANNELS]; if(!Counter) @@ -607,7 +606,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam if(!Counter) { - parms->Hrtf[chan].Current = parms->Hrtf[chan].Target; + parms->Hrtf.Current = parms->Hrtf.Target; for(j = 0;j < HRIR_LENGTH;j++) { hrtfparams.Steps.Coeffs[j][0] = 0.0f; @@ -622,18 +621,18 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam ALint delaydiff; for(j = 0;j < IrSize;j++) { - coeffdiff = parms->Hrtf[chan].Target.Coeffs[j][0] - parms->Hrtf[chan].Current.Coeffs[j][0]; + coeffdiff = parms->Hrtf.Target.Coeffs[j][0] - parms->Hrtf.Current.Coeffs[j][0]; hrtfparams.Steps.Coeffs[j][0] = coeffdiff * Delta; - coeffdiff = parms->Hrtf[chan].Target.Coeffs[j][1] - parms->Hrtf[chan].Current.Coeffs[j][1]; + coeffdiff = parms->Hrtf.Target.Coeffs[j][1] - parms->Hrtf.Current.Coeffs[j][1]; hrtfparams.Steps.Coeffs[j][1] = coeffdiff * Delta; } - delaydiff = (ALint)(parms->Hrtf[chan].Target.Delay[0] - parms->Hrtf[chan].Current.Delay[0]); + delaydiff = (ALint)(parms->Hrtf.Target.Delay[0] - parms->Hrtf.Current.Delay[0]); hrtfparams.Steps.Delay[0] = fastf2i((ALfloat)delaydiff * Delta); - delaydiff = (ALint)(parms->Hrtf[chan].Target.Delay[1] - parms->Hrtf[chan].Current.Delay[1]); + delaydiff = (ALint)(parms->Hrtf.Target.Delay[1] - parms->Hrtf.Current.Delay[1]); hrtfparams.Steps.Delay[1] = fastf2i((ALfloat)delaydiff * Delta); } - hrtfparams.Target = &parms->Hrtf[chan].Target; - hrtfparams.Current = &parms->Hrtf[chan].Current; + hrtfparams.Target = &parms->Hrtf.Target; + hrtfparams.Current = &parms->Hrtf.Current; lidx = GetChannelIdxByName(Device->RealOut, FrontLeft); ridx = GetChannelIdxByName(Device->RealOut, FrontRight); @@ -641,15 +640,15 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam MixHrtfSamples(voice->DirectOut.Buffer, lidx, ridx, samples, Counter, voice->Offset, OutPos, IrSize, &hrtfparams, - &parms->Hrtf[chan].State, DstBufferSize); + &parms->Hrtf.State, DstBufferSize); } } for(j = 0;j < Device->NumAuxSends;j++) { - SendParams *parms = &voice->Send[j]; - ALfloat *restrict currents = parms->Gains[chan].Current; - const ALfloat *targets = parms->Gains[chan].Target; + SendParams *parms = &voice->Chan[chan].Send[j]; + ALfloat *restrict currents = parms->Gains.Current; + const ALfloat *targets = parms->Gains.Target; MixGains gains[MAX_OUTPUT_CHANNELS]; const ALfloat *samples; @@ -657,9 +656,8 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam continue; samples = DoFilters( - &parms->Filters[chan].LowPass, &parms->Filters[chan].HighPass, - Device->FilteredData, ResampledData, DstBufferSize, - parms->Filters[chan].ActiveType + &parms->LowPass, &parms->HighPass, Device->FilteredData, + ResampledData, DstBufferSize, parms->FilterType ); if(!Counter) diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 2dd8229c..db138be1 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -51,8 +51,10 @@ typedef struct ALvoice { ALuint Channels; } SendOut[MAX_SENDS]; - DirectParams Direct; - SendParams Send[MAX_SENDS]; + struct { + DirectParams Direct; + SendParams Send[MAX_SENDS]; + } Chan[MAX_INPUT_CHANNELS]; } ALvoice; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 266c0588..9913a117 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -125,35 +125,31 @@ typedef struct MixHrtfParams { } MixHrtfParams; typedef struct DirectParams { - struct { - enum ActiveFilters ActiveType; - ALfilterState LowPass; - ALfilterState HighPass; - } Filters[MAX_INPUT_CHANNELS]; + enum ActiveFilters FilterType; + ALfilterState LowPass; + ALfilterState HighPass; struct { HrtfParams Current; HrtfParams Target; HrtfState State; - } Hrtf[MAX_INPUT_CHANNELS]; + } Hrtf; struct { ALfloat Current[MAX_OUTPUT_CHANNELS]; ALfloat Target[MAX_OUTPUT_CHANNELS]; - } Gains[MAX_INPUT_CHANNELS]; + } Gains; } DirectParams; typedef struct SendParams { - struct { - enum ActiveFilters ActiveType; - ALfilterState LowPass; - ALfilterState HighPass; - } Filters[MAX_INPUT_CHANNELS]; + enum ActiveFilters FilterType; + ALfilterState LowPass; + ALfilterState HighPass; struct { ALfloat Current[MAX_OUTPUT_CHANNELS]; ALfloat Target[MAX_OUTPUT_CHANNELS]; - } Gains[MAX_INPUT_CHANNELS]; + } Gains; } SendParams; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 46467b01..4a50d217 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -3005,11 +3005,11 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { ALsizei j; for(j = 0;j < HRTF_HISTORY_LENGTH;j++) - voice->Direct.Hrtf[i].State.History[j] = 0.0f; + voice->Chan[i].Direct.Hrtf.State.History[j] = 0.0f; for(j = 0;j < HRIR_LENGTH;j++) { - voice->Direct.Hrtf[i].State.Values[j][0] = 0.0f; - voice->Direct.Hrtf[i].State.Values[j][1] = 0.0f; + voice->Chan[i].Direct.Hrtf.State.Values[j][0] = 0.0f; + voice->Chan[i].Direct.Hrtf.State.Values[j][1] = 0.0f; } } -- cgit v1.2.3 From 0fcd39c4c0205b8229df16f48b05cf0bf6600287 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 31 Jul 2016 23:42:30 -0700 Subject: Don't store the looping state in the voice Certain operations on the buffer queue depend on the loop state to behave properly, so it should not be deferred until the async voice update occurs. --- Alc/ALu.c | 2 -- Alc/mixer.c | 2 +- OpenAL32/Include/alSource.h | 6 ++---- OpenAL32/alSource.c | 29 ++++++++++++++++++++--------- 4 files changed, 23 insertions(+), 16 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index d1a12672..70fe7f49 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -437,7 +437,6 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * voice->SendOut[i].Channels = SendSlots[i]->NumChannels; } } - voice->Looping = ATOMIC_LOAD(&props->Looping, almemory_order_relaxed); /* Calculate the stepping value */ Pitch *= (ALfloat)ALBuffer->Frequency / Frequency; @@ -906,7 +905,6 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro voice->SendOut[i].Channels = SendSlots[i]->NumChannels; } } - voice->Looping = ATOMIC_LOAD(&props->Looping, almemory_order_relaxed); /* Transform source to listener space (convert to head relative) */ if(ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed) == AL_FALSE) diff --git a/Alc/mixer.c b/Alc/mixer.c index b2af812a..9f6ec9d1 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -388,9 +388,9 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam BufferListItem = ATOMIC_LOAD(&Source->current_buffer); DataPosInt = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); DataPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + Looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); NumChannels = Source->NumChannels; SampleSize = Source->SampleSize; - Looping = voice->Looping; increment = voice->Step; IrSize = (Device->Hrtf ? Device->Hrtf->irSize : 0); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index db138be1..74987b34 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -28,8 +28,6 @@ typedef struct ALvoice { /** Current target parameters used for mixing. */ ALint Step; - ALboolean Looping; - /* If not 'moving', gain/coefficients are set directly without fading. */ ALboolean Moving; @@ -74,7 +72,6 @@ struct ALsourceProps { ATOMIC(ALfloat) Direction[3]; ATOMIC(ALfloat) Orientation[2][3]; ATOMIC(ALboolean) HeadRelative; - ATOMIC(ALboolean) Looping; ATOMIC(enum DistanceModel) DistanceModel; ATOMIC(ALboolean) DirectChannels; @@ -128,7 +125,6 @@ typedef struct ALsource { ALfloat Direction[3]; ALfloat Orientation[2][3]; ALboolean HeadRelative; - ALboolean Looping; enum DistanceModel DistanceModel; ALboolean DirectChannels; @@ -192,6 +188,8 @@ typedef struct ALsource { ATOMIC(ALuint) position; ATOMIC(ALuint) position_fraction; + ATOMIC(ALboolean) looping; + /** Current buffer sample info. */ ALuint NumChannels; ALuint SampleSize; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 4a50d217..0e98f2f5 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -642,8 +642,9 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_LOOPING: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - Source->Looping = (ALboolean)*values; - DO_UPDATEPROPS(); + WriteLock(&Source->queue_lock); + ATOMIC_STORE(&Source->looping, *values); + WriteUnlock(&Source->queue_lock); return AL_TRUE; case AL_BUFFER: @@ -1198,7 +1199,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_LOOPING: - *values = Source->Looping; + *values = ATOMIC_LOAD(&Source->looping); return AL_TRUE; case AL_BUFFER: @@ -1285,7 +1286,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFERS_PROCESSED: ReadLock(&Source->queue_lock); - if(Source->Looping || Source->SourceType != AL_STREAMING) + if(ATOMIC_LOAD(&Source->looping) || Source->SourceType != AL_STREAMING) { /* Buffers on a looping source are in a perpetual state of * PENDING, so don't report any as PROCESSED */ @@ -2605,6 +2606,13 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); WriteLock(&source->queue_lock); + if(ATOMIC_LOAD(&source->looping) || source->SourceType != AL_STREAMING) + { + WriteUnlock(&source->queue_lock); + /* Trying to unqueue buffers on a looping or non-streaming source. */ + SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + } + /* Find the new buffer queue head */ OldTail = ATOMIC_LOAD(&source->queue); Current = ATOMIC_LOAD(&source->current_buffer); @@ -2617,10 +2625,10 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint OldTail = next; } } - if(source->Looping || source->SourceType != AL_STREAMING || i != nb) + if(i != nb) { WriteUnlock(&source->queue_lock); - /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */ + /* Trying to unqueue pending buffers. */ SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); } @@ -2693,7 +2701,6 @@ static void InitSourceParams(ALsource *Source) Source->RefDistance = 1.0f; Source->MaxDistance = FLT_MAX; Source->RollOffFactor = 1.0f; - Source->Looping = AL_FALSE; Source->Gain = 1.0f; Source->MinGain = 0.0f; Source->MaxGain = 1.0f; @@ -2741,6 +2748,8 @@ static void InitSourceParams(ALsource *Source) ATOMIC_INIT(&Source->position, 0); ATOMIC_INIT(&Source->position_fraction, 0); + ATOMIC_INIT(&Source->looping, AL_FALSE); + ATOMIC_INIT(&Source->Update, NULL); ATOMIC_INIT(&Source->FreeList, NULL); } @@ -2832,7 +2841,6 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends, ALCcontext *co almemory_order_relaxed); } ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed); - ATOMIC_STORE(&props->Looping, source->Looping, almemory_order_relaxed); ATOMIC_STORE(&props->DistanceModel, context->SourceDistanceModel ? source->DistanceModel : context->DistanceModel, almemory_order_relaxed @@ -3168,6 +3176,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device ALuint readPos, readPosFrac; ALuint totalBufferLen; ALdouble offset = 0.0; + ALboolean looping; ALuint refcount; ReadLock(&Source->queue_lock); @@ -3186,6 +3195,8 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device readPos = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); readPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + + looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); } while(refcount != ReadRef(&device->MixCount)); while(BufferList != NULL) @@ -3202,7 +3213,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device } assert(Buffer != NULL); - if(Source->Looping) + if(looping) readPos %= totalBufferLen; else { -- cgit v1.2.3 From dc8b7814c771d08abe61656b745e7763a010a3a3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 23 Aug 2016 18:56:01 -0700 Subject: Avoid resupplying unneeded source updates The source's voice holds a copy of the last properties it received, so listener updates can make sources recalculate internal properties from that stored copy. --- Alc/ALc.c | 4 +-- Alc/ALu.c | 79 +++++++++++++++++++++++++++++---------------- OpenAL32/Include/alSource.h | 71 +++++++++++++++++++++------------------- OpenAL32/alAuxEffectSlot.c | 2 +- OpenAL32/alListener.c | 18 ----------- OpenAL32/alState.c | 9 ------ 6 files changed, 91 insertions(+), 92 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index dbda46f1..f5965716 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1602,8 +1602,6 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) { ALsizei pos; - UpdateListenerProps(context); - LockUIntMapRead(&context->SourceMap); V0(device->Backend,lock)(); for(pos = 0;pos < context->SourceMap.size;pos++) @@ -1626,6 +1624,8 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) } V0(device->Backend,unlock)(); UnlockUIntMapRead(&context->SourceMap); + + UpdateListenerProps(context); UpdateAllSourceProps(context); } ReadUnlock(&context->PropLock); diff --git a/Alc/ALu.c b/Alc/ALu.c index a9f89de0..115c9c59 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -228,7 +228,7 @@ static ALboolean BsincPrepare(const ALuint increment, BsincState *state) } -static void CalcListenerParams(ALCcontext *Context) +static ALboolean CalcListenerParams(ALCcontext *Context) { ALlistener *Listener = Context->Listener; ALfloat N[3], V[3], U[3], P[3]; @@ -237,7 +237,7 @@ static void CalcListenerParams(ALCcontext *Context) aluVector vel; props = ATOMIC_EXCHANGE(struct ALlistenerProps*, &Listener->Update, NULL, almemory_order_acq_rel); - if(!props) return; + if(!props) return AL_FALSE; /* AT then UP */ N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed); @@ -288,6 +288,8 @@ static void CalcListenerParams(ALCcontext *Context) ATOMIC_STORE(&props->next, first, almemory_order_relaxed); } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALlistenerProps*, &Listener->FreeList, &first, props) == 0); + + return AL_TRUE; } static void CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) @@ -1281,7 +1283,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } } -static void CalcSourceParams(ALvoice *voice, ALCcontext *context) +static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force) { ALsource *source = voice->Source; const ALbufferlistitem *BufferListItem; @@ -1289,33 +1291,54 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context) struct ALsourceProps *props; props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->Update, NULL, almemory_order_acq_rel); - if(!props) return; - - BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); - while(BufferListItem != NULL) + if(!props) { - const ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) + if(!force) + return; + BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); + while(BufferListItem != NULL) { - if(buffer->FmtChannels == FmtMono) - CalcAttnSourceParams(voice, props, buffer, context); - else - CalcNonAttnSourceParams(voice, props, buffer, context); - break; + const ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + if(buffer->FmtChannels == FmtMono) + CalcAttnSourceParams(voice, &voice->Props, buffer, context); + else + CalcNonAttnSourceParams(voice, &voice->Props, buffer, context); + break; + } + BufferListItem = BufferListItem->next; } - BufferListItem = BufferListItem->next; } - - /* WARNING: A livelock is theoretically possible if another thread keeps - * changing the freelist head without giving this a chance to actually swap - * in the old container (practically impossible with this little code, - * but...). - */ - first = ATOMIC_LOAD(&source->FreeList); - do { - ATOMIC_STORE(&props->next, first, almemory_order_relaxed); - } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, - &source->FreeList, &first, props) == 0); + else + { + BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); + while(BufferListItem != NULL) + { + const ALbuffer *buffer; + if((buffer=BufferListItem->buffer) != NULL) + { + if(buffer->FmtChannels == FmtMono) + CalcAttnSourceParams(voice, props, buffer, context); + else + CalcNonAttnSourceParams(voice, props, buffer, context); + break; + } + BufferListItem = BufferListItem->next; + } + voice->Props = *props; + + /* WARNING: A livelock is theoretically possible if another thread keeps + * changing the freelist head without giving this a chance to actually swap + * in the old container (practically impossible with this little code, + * but...). + */ + first = ATOMIC_LOAD(&source->FreeList); + do { + ATOMIC_STORE(&props->next, first, almemory_order_relaxed); + } while(ATOMIC_COMPARE_EXCHANGE_WEAK(struct ALsourceProps*, + &source->FreeList, &first, props) == 0); + } } @@ -1327,7 +1350,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) IncrementRef(&ctx->UpdateCount); if(!ATOMIC_LOAD(&ctx->HoldUpdates)) { - CalcListenerParams(ctx); + ALboolean force = CalcListenerParams(ctx); while(slot) { CalcEffectSlotParams(slot, ctx->Device); @@ -1342,7 +1365,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) if(source->state != AL_PLAYING && source->state != AL_PAUSED) voice->Source = NULL; else - CalcSourceParams(voice, ctx); + CalcSourceParams(voice, ctx, force); } } IncrementRef(&ctx->UpdateCount); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 74987b34..b288937a 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -22,40 +22,6 @@ typedef struct ALbufferlistitem { } ALbufferlistitem; -typedef struct ALvoice { - struct ALsource *volatile Source; - - /** Current target parameters used for mixing. */ - ALint Step; - - /* If not 'moving', gain/coefficients are set directly without fading. */ - ALboolean Moving; - - ALboolean IsHrtf; - - ALuint Offset; /* Number of output samples mixed since starting. */ - - alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES]; - - BsincState SincState; - - struct { - ALfloat (*Buffer)[BUFFERSIZE]; - ALuint Channels; - } DirectOut; - - struct { - ALfloat (*Buffer)[BUFFERSIZE]; - ALuint Channels; - } SendOut[MAX_SENDS]; - - struct { - DirectParams Direct; - SendParams Send[MAX_SENDS]; - } Chan[MAX_INPUT_CHANNELS]; -} ALvoice; - - struct ALsourceProps { ATOMIC(ALfloat) Pitch; ATOMIC(ALfloat) Gain; @@ -108,6 +74,43 @@ struct ALsourceProps { ATOMIC(struct ALsourceProps*) next; }; + +typedef struct ALvoice { + struct ALsourceProps Props; + + struct ALsource *volatile Source; + + /** Current target parameters used for mixing. */ + ALint Step; + + /* If not 'moving', gain/coefficients are set directly without fading. */ + ALboolean Moving; + + ALboolean IsHrtf; + + ALuint Offset; /* Number of output samples mixed since starting. */ + + alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES]; + + BsincState SincState; + + struct { + ALfloat (*Buffer)[BUFFERSIZE]; + ALuint Channels; + } DirectOut; + + struct { + ALfloat (*Buffer)[BUFFERSIZE]; + ALuint Channels; + } SendOut[MAX_SENDS]; + + struct { + DirectParams Direct; + SendParams Send[MAX_SENDS]; + } Chan[MAX_INPUT_CHANNELS]; +} ALvoice; + + typedef struct ALsource { /** Source properties. */ ALfloat Pitch; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index db084e5a..50f1e5c5 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -210,7 +210,7 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param slot->AuxSendAuto = value; UpdateEffectSlotProps(slot); if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - UpdateAllSourceProps(context); + UpdateListenerProps(context); break; default: diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index c7f4955a..3ea23732 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -52,10 +52,7 @@ AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -93,10 +90,7 @@ AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat val SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -149,10 +143,7 @@ AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -174,10 +165,7 @@ AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint UNUSED(value)) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -207,10 +195,7 @@ AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, A SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); @@ -256,10 +241,7 @@ AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); } if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { UpdateListenerProps(context); - UpdateAllSourceProps(context); - } done: WriteUnlock(&context->PropLock); diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index 443ab884..59814a4b 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -557,10 +557,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); - UpdateAllSourceProps(context); - } WriteUnlock(&context->PropLock); done: @@ -580,10 +577,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); - UpdateAllSourceProps(context); - } WriteUnlock(&context->PropLock); done: @@ -603,10 +597,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); - UpdateAllSourceProps(context); - } WriteUnlock(&context->PropLock); done: -- cgit v1.2.3 From 01babb69d25fd23bde0fdf5ed525bb82934ce6fd Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 22 Nov 2016 02:28:18 -0800 Subject: Clean up finding a source's voice --- OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 55 ++++++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 27 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index b288937a..d5eb3c50 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -78,7 +78,7 @@ struct ALsourceProps { typedef struct ALvoice { struct ALsourceProps Props; - struct ALsource *volatile Source; + struct ALsource *Source; /** Current target parameters used for mixing. */ ALint Step; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 78aaf61d..b65c2c18 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -125,6 +125,18 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint *values); static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values); +static inline ALvoice *GetSourceVoice(const ALsource *source, const ALCcontext *context) +{ + ALvoice *voice = context->Voices; + ALvoice *voice_end = voice + context->VoiceCount; + while(voice != voice_end) + { + if(voice->Source == source) + return voice; + } + return NULL; +} + static inline bool SourceShouldUpdate(const ALsource *source, const ALCcontext *context) { return (source->state == AL_PLAYING || source->state == AL_PAUSED) && @@ -1584,22 +1596,15 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) } for(i = 0;i < n;i++) { - ALvoice *voice, *voice_end; + ALvoice *voice; if((Source=RemoveSource(context, sources[i])) == NULL) continue; FreeThunkEntry(Source->id); LockContext(context); - voice = context->Voices; - voice_end = voice + context->VoiceCount; - while(voice != voice_end) - { - ALsource *old = Source; - if(COMPARE_EXCHANGE(&voice->Source, &old, NULL)) - break; - voice++; - } + voice = GetSourceVoice(Source, context); + if(voice) voice->Source = NULL; UnlockContext(context); DeinitSource(Source); @@ -2977,29 +2982,27 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(!BufferList || !device->Connected) goto do_stop; - /* Make sure this source isn't already active, while looking for an - * unused active source slot to put it in. */ - for(i = 0;i < Context->VoiceCount;i++) + /* Make sure this source isn't already active, and if not, look for an + * unused voice to put it in. + */ + voice = GetSourceVoice(Source, Context); + if(voice == NULL) { - if(Context->Voices[i].Source == Source) + for(i = 0;i < Context->VoiceCount;i++) { - if(voice != NULL) - Context->Voices[i].Source = NULL; - else + if(Context->Voices[i].Source == NULL) + { voice = &Context->Voices[i]; - break; + voice->Source = Source; + break; + } } - - if(!voice && !Context->Voices[i].Source) + if(voice == NULL) { - voice = &Context->Voices[i]; + voice = &Context->Voices[Context->VoiceCount++]; voice->Source = Source; } - } - if(voice == NULL) - { - voice = &Context->Voices[Context->VoiceCount++]; - voice->Source = Source; + discontinuity = AL_TRUE; } if(discontinuity) -- cgit v1.2.3 From 6886f77cbc02b93db3682acb27eb767c6541fba0 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 23 Nov 2016 01:31:13 -0800 Subject: Only send source updates for sources that have updated --- Alc/ALc.c | 3 ++- OpenAL32/Include/alSource.h | 2 ++ OpenAL32/alSource.c | 11 ++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 9d3467f7..2e7c1e7f 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2141,10 +2141,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) source->Send[s].LFReference = HIGHPASSFREQREF; s++; } + source->NeedsUpdate = AL_TRUE; } UnlockUIntMapRead(&context->SourceMap); - UpdateAllSourceProps(context); + UpdateListenerProps(context); ReadUnlock(&context->PropLock); context = context->next; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index d5eb3c50..8b793102 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -197,6 +197,8 @@ typedef struct ALsource { ALuint NumChannels; ALuint SampleSize; + ALenum NeedsUpdate; + ATOMIC(struct ALsourceProps*) Update; ATOMIC(struct ALsourceProps*) FreeList; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index b65c2c18..9ef58115 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -399,6 +399,8 @@ static ALint Int64ValsByProp(ALenum prop) #define DO_UPDATEPROPS() do { \ if(SourceShouldUpdate(Source, Context)) \ UpdateSourceProps(Source, device->NumAuxSends); \ + else \ + Source->NeedsUpdate = AL_TRUE; \ } while(0) static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALfloat *values) @@ -2772,6 +2774,8 @@ static void InitSourceParams(ALsource *Source) ATOMIC_INIT(&Source->looping, AL_FALSE); + Source->NeedsUpdate = AL_TRUE; + ATOMIC_INIT(&Source->Update, NULL); ATOMIC_INIT(&Source->FreeList, NULL); } @@ -2924,8 +2928,12 @@ void UpdateAllSourceProps(ALCcontext *context) ALvoice *voice = &context->Voices[pos]; ALsource *source = voice->Source; if(source != NULL && (source->state == AL_PLAYING || - source->state == AL_PAUSED)) + source->state == AL_PAUSED) && + source->NeedsUpdate) + { + source->NeedsUpdate = AL_FALSE; UpdateSourceProps(source, num_sends); + } } } @@ -3029,6 +3037,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } } + Source->NeedsUpdate = AL_FALSE; UpdateSourceProps(Source, device->NumAuxSends); } else if(state == AL_PAUSED) -- cgit v1.2.3 From d2e5aa79ddc79bccde67d375cffea8f9922ca611 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 18 Jan 2017 07:13:23 -0800 Subject: Use ALsizei in more places --- Alc/ALc.c | 8 ++--- Alc/ALu.c | 2 +- Alc/backends/solaris.c | 6 ++-- Alc/mixer.c | 66 +++++++++++++++++++------------------- Alc/panning.c | 28 ++++++++-------- OpenAL32/Include/alAuxEffectSlot.h | 4 +-- OpenAL32/Include/alBuffer.h | 16 ++++----- OpenAL32/Include/alMain.h | 16 ++++----- OpenAL32/Include/alSource.h | 8 ++--- OpenAL32/Include/alu.h | 14 ++++---- OpenAL32/alBuffer.c | 20 ++++++------ 11 files changed, 94 insertions(+), 94 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 0b558ff7..80378d91 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1310,8 +1310,8 @@ const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) return "(unknown channels)"; } -extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type); -ALuint BytesFromDevFmt(enum DevFmtType type) +extern inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type); +ALsizei BytesFromDevFmt(enum DevFmtType type) { switch(type) { @@ -1325,7 +1325,7 @@ ALuint BytesFromDevFmt(enum DevFmtType type) } return 0; } -ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) +ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans) { switch(chans) { @@ -2093,7 +2093,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->FOAOut.Buffer = device->Dry.Buffer; device->FOAOut.NumChannels = device->Dry.NumChannels; } - TRACE("Channel config, Dry: %u, FOA: %u, Real: %u\n", device->Dry.NumChannels, + TRACE("Channel config, Dry: %d, FOA: %d, Real: %d\n", device->Dry.NumChannels, device->FOAOut.NumChannels, device->RealOut.NumChannels); SetMixerFPUMode(&oldMode); diff --git a/Alc/ALu.c b/Alc/ALu.c index 02b4ffe8..9b03b85a 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1400,7 +1400,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) ALsource *source; ALCcontext *ctx; FPUCtl oldMode; - ALuint i, c; + ALsizei i, c; SetMixerFPUMode(&oldMode); diff --git a/Alc/backends/solaris.c b/Alc/backends/solaris.c index 01472e6a..792f717a 100644 --- a/Alc/backends/solaris.c +++ b/Alc/backends/solaris.c @@ -177,8 +177,8 @@ static ALCboolean ALCsolarisBackend_reset(ALCsolarisBackend *self) { ALCdevice *device = STATIC_CAST(ALCbackend,self)->mDevice; audio_info_t info; - ALuint frameSize; - int numChannels; + ALsizei frameSize; + ALsizei numChannels; AUDIO_INITINFO(&info); @@ -220,7 +220,7 @@ static ALCboolean ALCsolarisBackend_reset(ALCsolarisBackend *self) return ALC_FALSE; } - if(ChannelsFromDevFmt(device->FmtChans) != info.play.channels) + if(ChannelsFromDevFmt(device->FmtChans) != (ALsizei)info.play.channels) { ERR("Could not set %d channels, got %d instead\n", ChannelsFromDevFmt(device->FmtChans), info.play.channels); return ALC_FALSE; diff --git a/Alc/mixer.c b/Alc/mixer.c index 2d804b1f..58192055 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -307,9 +307,9 @@ static inline ALfloat Sample_ALfloat(ALfloat val) { return val; } #define DECL_TEMPLATE(T) \ -static inline void Load_##T(ALfloat *dst, const T *src, ALuint srcstep, ALuint samples)\ +static inline void Load_##T(ALfloat *dst, const T *src, ALint srcstep, ALsizei samples)\ { \ - ALuint i; \ + ALsizei i; \ for(i = 0;i < samples;i++) \ dst[i] = Sample_##T(src[i*srcstep]); \ } @@ -320,7 +320,7 @@ DECL_TEMPLATE(ALfloat) #undef DECL_TEMPLATE -static void LoadSamples(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum FmtType srctype, ALuint samples) +static void LoadSamples(ALfloat *dst, const ALvoid *src, ALint srcstep, enum FmtType srctype, ALsizei samples) { switch(srctype) { @@ -336,9 +336,9 @@ static void LoadSamples(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum Fm } } -static inline void SilenceSamples(ALfloat *dst, ALuint samples) +static inline void SilenceSamples(ALfloat *dst, ALsizei samples) { - ALuint i; + ALsizei i; for(i = 0;i < samples;i++) dst[i] = 0.0f; } @@ -346,9 +346,9 @@ static inline void SilenceSamples(ALfloat *dst, ALuint samples) static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter, ALfloat *restrict dst, const ALfloat *restrict src, - ALuint numsamples, enum ActiveFilters type) + ALsizei numsamples, enum ActiveFilters type) { - ALuint i; + ALsizei i; switch(type) { case AF_None: @@ -369,7 +369,7 @@ static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter for(i = 0;i < numsamples;) { ALfloat temp[256]; - ALuint todo = minu(256, numsamples-i); + ALsizei todo = mini(256, numsamples-i); ALfilterState_process(lpfilter, temp, src+i, todo); ALfilterState_process(hpfilter, dst+i, temp, todo); @@ -381,21 +381,22 @@ static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter } -ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint SamplesToDo) +ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei SamplesToDo) { ResamplerFunc Resample; ALbufferlistitem *BufferListItem; ALuint DataPosInt, DataPosFrac; ALboolean Looping; - ALuint increment; + ALint increment; ALenum State; - ALuint OutPos; - ALuint NumChannels; - ALuint SampleSize; + ALsizei OutPos; + ALsizei NumChannels; + ALsizei SampleSize; ALint64 DataSize64; - ALuint Counter; - ALuint IrSize; - ALuint chan, send, j; + ALsizei Counter; + ALsizei IrSize; + ALsizei chan, j; + ALuint send; /* Get source info */ State = AL_PLAYING; /* Only called while playing. */ @@ -415,7 +416,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam Counter = voice->Moving ? SamplesToDo : 0; OutPos = 0; do { - ALuint SrcBufferSize, DstBufferSize; + ALsizei SrcBufferSize, DstBufferSize; /* Figure out how many buffer samples will be needed */ DataSize64 = SamplesToDo-OutPos; @@ -424,7 +425,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam DataSize64 >>= FRACTIONBITS; DataSize64 += MAX_POST_SAMPLES+MAX_PRE_SAMPLES; - SrcBufferSize = (ALuint)mini64(DataSize64, BUFFERSIZE); + SrcBufferSize = (ALsizei)mini64(DataSize64, BUFFERSIZE); /* Figure out how many samples we can actually mix from this. */ DataSize64 = SrcBufferSize; @@ -432,8 +433,8 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam DataSize64 <<= FRACTIONBITS; DataSize64 -= DataPosFrac; - DstBufferSize = (ALuint)((DataSize64+(increment-1)) / increment); - DstBufferSize = minu(DstBufferSize, (SamplesToDo-OutPos)); + DstBufferSize = (ALsizei)((DataSize64+(increment-1)) / increment); + DstBufferSize = mini(DstBufferSize, (SamplesToDo-OutPos)); /* Some mixers like having a multiple of 4, so try to give that unless * this is the last update. */ @@ -444,7 +445,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam { const ALfloat *ResampledData; ALfloat *SrcData = Device->SourceData; - ALuint SrcDataSize; + ALsizei SrcDataSize; /* Load the previous samples into the source data first. */ memcpy(SrcData, voice->PrevSamples[chan], MAX_PRE_SAMPLES*sizeof(ALfloat)); @@ -454,7 +455,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam { const ALbuffer *ALBuffer = BufferListItem->buffer; const ALubyte *Data = ALBuffer->data; - ALuint DataSize; + ALsizei DataSize; /* Offset buffer data to current channel */ Data += chan*SampleSize; @@ -478,13 +479,12 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam } else { - ALuint LoopStart = ALBuffer->LoopStart; - ALuint LoopEnd = ALBuffer->LoopEnd; + ALsizei LoopStart = ALBuffer->LoopStart; + ALsizei LoopEnd = ALBuffer->LoopEnd; /* Load what's left of this loop iteration, then load * repeats of the loop section */ - DataSize = LoopEnd - DataPosInt; - DataSize = minu(SrcBufferSize - SrcDataSize, DataSize); + DataSize = minu(SrcBufferSize - SrcDataSize, LoopEnd - DataPosInt); LoadSamples(&SrcData[SrcDataSize], &Data[DataPosInt * NumChannels*SampleSize], NumChannels, ALBuffer->FmtType, DataSize); @@ -493,7 +493,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam DataSize = LoopEnd-LoopStart; while(SrcBufferSize > SrcDataSize) { - DataSize = minu(SrcBufferSize - SrcDataSize, DataSize); + DataSize = mini(SrcBufferSize - SrcDataSize, DataSize); LoadSamples(&SrcData[SrcDataSize], &Data[LoopStart * NumChannels*SampleSize], NumChannels, ALBuffer->FmtType, DataSize); @@ -645,22 +645,22 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam OutPos += DstBufferSize; voice->Offset += DstBufferSize; - Counter = maxu(DstBufferSize, Counter) - DstBufferSize; + Counter = maxi(DstBufferSize, Counter) - DstBufferSize; /* Handle looping sources */ while(1) { const ALbuffer *ALBuffer; - ALuint DataSize = 0; - ALuint LoopStart = 0; - ALuint LoopEnd = 0; + ALsizei DataSize = 0; + ALsizei LoopStart = 0; + ALsizei LoopEnd = 0; if((ALBuffer=BufferListItem->buffer) != NULL) { DataSize = ALBuffer->SampleLen; LoopStart = ALBuffer->LoopStart; LoopEnd = ALBuffer->LoopEnd; - if(LoopEnd > DataPosInt) + if((ALuint)LoopEnd > DataPosInt) break; } @@ -671,7 +671,7 @@ ALvoid MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALuint Sam break; } - if(DataSize > DataPosInt) + if((ALuint)DataSize > DataPosInt) break; if(!(BufferListItem=BufferListItem->next)) diff --git a/Alc/panning.c b/Alc/panning.c index e1ad6d0b..a0576e0d 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -209,9 +209,9 @@ void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat } -void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { - ALuint i; + ALsizei i; for(i = 0;i < numchans;i++) { @@ -224,10 +224,10 @@ void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALf gains[i] = 0.0f; } -void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { ALfloat gain = 0.0f; - ALuint i; + ALsizei i; for(i = 0;i < numchans;i++) { @@ -239,9 +239,9 @@ void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALuint numchans, ALfl gains[i] = 0.0f; } -void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, ALsizei numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { - ALuint i, j; + ALsizei i, j; for(i = 0;i < numchans;i++) { @@ -254,9 +254,9 @@ void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALu gains[i] = 0.0f; } -void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { - ALuint i; + ALsizei i; for(i = 0;i < numchans;i++) gains[i] = chanmap[i].Scale * coeffs[chanmap[i].Index] * ingain; @@ -264,9 +264,9 @@ void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, cons gains[i] = 0.0f; } -void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { - ALuint i, j; + ALsizei i, j; for(i = 0;i < numchans;i++) { @@ -279,9 +279,9 @@ void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, gains[i] = 0.0f; } -void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) +void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]) { - ALuint i; + ALsizei i; for(i = 0;i < numchans;i++) gains[i] = chanmap[i].Scale * mtx[chanmap[i].Index] * ingain; @@ -342,13 +342,13 @@ typedef struct ChannelMap { } ChannelMap; static void SetChannelMap(const enum Channel *devchans, ChannelConfig *ambicoeffs, - const ChannelMap *chanmap, size_t count, ALuint *outcount, + const ChannelMap *chanmap, size_t count, ALsizei *outcount, ALboolean isfuma) { const ALsizei *acnmap = isfuma ? FuMa2ACN : ACN2ACN; const ALfloat *n3dscale = isfuma ? FuMa2N3DScale : UnitScale; size_t j, k; - ALuint i; + ALsizei i; for(i = 0;i < MAX_OUTPUT_CHANNELS && devchans[i] != InvalidChannel;i++) { diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 70fcac5c..40ff1393 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -18,7 +18,7 @@ typedef struct ALeffectState { const struct ALeffectStateVtable *vtbl; ALfloat (*OutBuffer)[BUFFERSIZE]; - ALuint OutChannels; + ALsizei OutChannels; } ALeffectState; void ALeffectState_Construct(ALeffectState *state); @@ -120,7 +120,7 @@ typedef struct ALeffectslot { /* Self ID */ ALuint id; - ALuint NumChannels; + ALsizei NumChannels; BFChannelConfig ChanMap[MAX_EFFECT_CHANNELS]; /* Wet buffer configuration is ACN channel order with N3D scaling: * * Channel 0 is the unattenuated mono signal. diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h index e99af050..062be452 100644 --- a/OpenAL32/Include/alBuffer.h +++ b/OpenAL32/Include/alBuffer.h @@ -36,9 +36,9 @@ enum UserFmtChannels { UserFmtBFormat3D = AL_BFORMAT3D_SOFT, /* WXYZ */ }; -ALuint BytesFromUserFmt(enum UserFmtType type); -ALuint ChannelsFromUserFmt(enum UserFmtChannels chans); -inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type) +ALsizei BytesFromUserFmt(enum UserFmtType type); +ALsizei ChannelsFromUserFmt(enum UserFmtChannels chans); +inline ALsizei FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type) { return ChannelsFromUserFmt(chans) * BytesFromUserFmt(type); } @@ -63,9 +63,9 @@ enum FmtChannels { }; #define MAX_INPUT_CHANNELS (8) -ALuint BytesFromFmt(enum FmtType type); -ALuint ChannelsFromFmt(enum FmtChannels chans); -inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type) +ALsizei BytesFromFmt(enum FmtType type); +ALsizei ChannelsFromFmt(enum FmtChannels chans); +inline ALsizei FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type) { return ChannelsFromFmt(chans) * BytesFromFmt(type); } @@ -87,8 +87,8 @@ typedef struct ALbuffer { ALsizei OriginalSize; ALsizei OriginalAlign; - ALsizei LoopStart; - ALsizei LoopEnd; + ALsizei LoopStart; + ALsizei LoopEnd; ATOMIC(ALsizei) UnpackAlign; ATOMIC(ALsizei) PackAlign; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index fca98be9..fd90a49a 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -499,9 +499,9 @@ enum DevFmtChannels { }; #define MAX_OUTPUT_CHANNELS (16) -ALuint BytesFromDevFmt(enum DevFmtType type); -ALuint ChannelsFromDevFmt(enum DevFmtChannels chans); -inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type) +ALsizei BytesFromDevFmt(enum DevFmtType type); +ALsizei ChannelsFromDevFmt(enum DevFmtChannels chans); +inline ALsizei FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type) { return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type); } @@ -682,20 +682,20 @@ struct ALCdevice_struct * first-order, 9 for second-order, etc). If the count is 0, Ambi.Map * is used instead to map each output to a coefficient index. */ - ALuint CoeffCount; + ALsizei CoeffCount; ALfloat (*Buffer)[BUFFERSIZE]; - ALuint NumChannels; + ALsizei NumChannels; } Dry; /* First-order ambisonics output, to be upsampled to the dry buffer if different. */ struct { AmbiConfig Ambi; /* Will only be 4 or 0. */ - ALuint CoeffCount; + ALsizei CoeffCount; ALfloat (*Buffer)[BUFFERSIZE]; - ALuint NumChannels; + ALsizei NumChannels; } FOAOut; /* "Real" output, which will be written to the device buffer. May alias the @@ -705,7 +705,7 @@ struct ALCdevice_struct enum Channel ChannelName[MAX_OUTPUT_CHANNELS]; ALfloat (*Buffer)[BUFFERSIZE]; - ALuint NumChannels; + ALsizei NumChannels; } RealOut; /* Running count of the mixer invocations, in 31.1 fixed point. This diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 8b793102..4f04efe2 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -96,12 +96,12 @@ typedef struct ALvoice { struct { ALfloat (*Buffer)[BUFFERSIZE]; - ALuint Channels; + ALsizei Channels; } DirectOut; struct { ALfloat (*Buffer)[BUFFERSIZE]; - ALuint Channels; + ALsizei Channels; } SendOut[MAX_SENDS]; struct { @@ -194,8 +194,8 @@ typedef struct ALsource { ATOMIC(ALboolean) looping; /** Current buffer sample info. */ - ALuint NumChannels; - ALuint SampleSize; + ALsizei NumChannels; + ALsizei SampleSize; ALenum NeedsUpdate; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 21b787d2..dba167d4 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -313,8 +313,8 @@ void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat else \ ComputeAmbientGainsBF((b).Ambi.Map, (b).NumChannels, g, o); \ } while (0) -void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); -void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALuint numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +void ComputeAmbientGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); /** * ComputePanningGains @@ -328,8 +328,8 @@ void ComputeAmbientGainsBF(const BFChannelConfig *chanmap, ALuint numchans, ALfl else \ ComputePanningGainsBF((b).Ambi.Map, (b).NumChannels, c, g, o); \ } while (0) -void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, ALuint numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); -void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +void ComputePanningGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, ALsizei numcoeffs, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, const ALfloat coeffs[MAX_AMBI_COEFFS], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); /** * ComputeFirstOrderGains @@ -344,11 +344,11 @@ void ComputePanningGainsBF(const BFChannelConfig *chanmap, ALuint numchans, cons else \ ComputeFirstOrderGainsBF((b).Ambi.Map, (b).NumChannels, m, g, o); \ } while (0) -void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); -void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALuint numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +void ComputeFirstOrderGainsMC(const ChannelConfig *chancoeffs, ALsizei numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); +void ComputeFirstOrderGainsBF(const BFChannelConfig *chanmap, ALsizei numchans, const ALfloat mtx[4], ALfloat ingain, ALfloat gains[MAX_OUTPUT_CHANNELS]); -ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALuint SamplesToDo); +ALvoid MixSource(struct ALvoice *voice, struct ALsource *source, ALCdevice *Device, ALsizei SamplesToDo); ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size); /* Caller must lock the device. */ diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 24470d64..45a8cb5b 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -42,8 +42,8 @@ extern inline void LockBuffersWrite(ALCdevice *device); extern inline void UnlockBuffersWrite(ALCdevice *device); extern inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id); extern inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id); -extern inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type); -extern inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type); +extern inline ALsizei FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type); +extern inline ALsizei FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type); static ALboolean IsValidType(ALenum type); static ALboolean IsValidChannels(ALenum channels); @@ -145,7 +145,7 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoi ALCcontext *context; ALbuffer *albuf; ALenum newformat = AL_NONE; - ALuint framesize; + ALsizei framesize; ALsizei align; ALenum err; @@ -293,9 +293,9 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons ALCdevice *device; ALCcontext *context; ALbuffer *albuf; - ALuint byte_align; - ALuint channels; - ALuint bytes; + ALsizei byte_align; + ALsizei channels; + ALsizei bytes; ALsizei align; context = GetContextRef(); @@ -1074,7 +1074,7 @@ ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, } -ALuint BytesFromUserFmt(enum UserFmtType type) +ALsizei BytesFromUserFmt(enum UserFmtType type) { switch(type) { @@ -1095,7 +1095,7 @@ ALuint BytesFromUserFmt(enum UserFmtType type) } return 0; } -ALuint ChannelsFromUserFmt(enum UserFmtChannels chans) +ALsizei ChannelsFromUserFmt(enum UserFmtChannels chans) { switch(chans) { @@ -1190,7 +1190,7 @@ static ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans, return AL_FALSE; } -ALuint BytesFromFmt(enum FmtType type) +ALsizei BytesFromFmt(enum FmtType type) { switch(type) { @@ -1200,7 +1200,7 @@ ALuint BytesFromFmt(enum FmtType type) } return 0; } -ALuint ChannelsFromFmt(enum FmtChannels chans) +ALsizei ChannelsFromFmt(enum FmtChannels chans) { switch(chans) { -- cgit v1.2.3 From 0324712540f88d18f1fa8f18f7a72da06af00d75 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 13 Feb 2017 11:29:32 -0800 Subject: Put BsincState in a generic union --- Alc/ALu.c | 4 ++-- Alc/mixer.c | 2 +- Alc/mixer_c.c | 20 ++++++++++---------- Alc/mixer_defs.h | 34 +++++++++++++++++----------------- Alc/mixer_neon.c | 38 +++++++++++++++++++------------------- Alc/mixer_sse.c | 16 ++++++++-------- Alc/mixer_sse2.c | 6 +++--- Alc/mixer_sse3.c | 12 ++++++------ Alc/mixer_sse41.c | 18 +++++++++--------- OpenAL32/Include/alSource.h | 2 +- OpenAL32/Include/alu.h | 6 +++++- 11 files changed, 81 insertions(+), 77 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 29097c2a..42f229a2 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -433,7 +433,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * voice->Step = MAX_PITCH<Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1); - BsincPrepare(voice->Step, &voice->SincState); + BsincPrepare(voice->Step, &voice->ResampleState.bsinc); /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); @@ -1115,7 +1115,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro voice->Step = MAX_PITCH<Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1); - BsincPrepare(voice->Step, &voice->SincState); + BsincPrepare(voice->Step, &voice->ResampleState.bsinc); if(Device->Render_Mode == HrtfRender) { diff --git a/Alc/mixer.c b/Alc/mixer.c index 5442954e..592d51d4 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -564,7 +564,7 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp ); /* Now resample, then filter and mix to the appropriate outputs. */ - ResampledData = Resample(&voice->SincState, + ResampledData = Resample(&voice->ResampleState, &SrcData[MAX_PRE_SAMPLES], DataPosFrac, increment, Device->ResampledData, DstBufferSize ); diff --git a/Alc/mixer_c.c b/Alc/mixer_c.c index 1284371b..323f1363 100644 --- a/Alc/mixer_c.c +++ b/Alc/mixer_c.c @@ -18,7 +18,7 @@ static inline ALfloat fir8_32(const ALfloat *restrict vals, ALuint frac) { return resample_fir8(vals[-3], vals[-2], vals[-1], vals[0], vals[1], vals[2], vals[3], vals[4], frac); } -const ALfloat *Resample_copy32_C(const BsincState* UNUSED(state), +const ALfloat *Resample_copy32_C(const InterpState* UNUSED(state), const ALfloat *restrict src, ALuint UNUSED(frac), ALint UNUSED(increment), ALfloat *restrict dst, ALsizei numsamples) { @@ -32,7 +32,7 @@ const ALfloat *Resample_copy32_C(const BsincState* UNUSED(state), } #define DECL_TEMPLATE(Sampler) \ -const ALfloat *Resample_##Sampler##_C(const BsincState* UNUSED(state), \ +const ALfloat *Resample_##Sampler##_C(const InterpState* UNUSED(state), \ const ALfloat *restrict src, ALuint frac, ALint increment, \ ALfloat *restrict dst, ALsizei numsamples) \ { \ @@ -55,17 +55,17 @@ DECL_TEMPLATE(fir8_32) #undef DECL_TEMPLATE -const ALfloat *Resample_bsinc32_C(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_bsinc32_C(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen) { const ALfloat *fil, *scd, *phd, *spd; - const ALfloat sf = state->sf; - const ALsizei m = state->m; + const ALfloat sf = state->bsinc.sf; + const ALsizei m = state->bsinc.m; ALsizei j_f, pi, i; ALfloat pf, r; - src += state->l; + src += state->bsinc.l; for(i = 0;i < dstlen;i++) { // Calculate the phase index and factor. @@ -74,10 +74,10 @@ const ALfloat *Resample_bsinc32_C(const BsincState *state, const ALfloat *restri pf = (frac & ((1<coeffs[pi].filter; - scd = state->coeffs[pi].scDelta; - phd = state->coeffs[pi].phDelta; - spd = state->coeffs[pi].spDelta; + fil = ASSUME_ALIGNED(state->bsinc.coeffs[pi].filter, 16); + scd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].scDelta, 16); + phd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].phDelta, 16); + spd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].spDelta, 16); // Apply the scale and phase interpolated filter. r = 0.0f; diff --git a/Alc/mixer_defs.h b/Alc/mixer_defs.h index 4bafc839..60735c9f 100644 --- a/Alc/mixer_defs.h +++ b/Alc/mixer_defs.h @@ -12,12 +12,12 @@ struct MixHrtfParams; struct HrtfState; /* C resamplers */ -const ALfloat *Resample_copy32_C(const BsincState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); -const ALfloat *Resample_point32_C(const BsincState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); -const ALfloat *Resample_lerp32_C(const BsincState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); -const ALfloat *Resample_fir4_32_C(const BsincState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); -const ALfloat *Resample_fir8_32_C(const BsincState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); -const ALfloat *Resample_bsinc32_C(const BsincState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); +const ALfloat *Resample_copy32_C(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); +const ALfloat *Resample_point32_C(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); +const ALfloat *Resample_lerp32_C(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); +const ALfloat *Resample_fir4_32_C(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); +const ALfloat *Resample_fir8_32_C(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); +const ALfloat *Resample_bsinc32_C(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); /* C mixers */ @@ -67,28 +67,28 @@ inline void InitiatePositionArrays(ALuint frac, ALint increment, ALuint *restric } } -const ALfloat *Resample_lerp32_SSE2(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_lerp32_SSE2(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_lerp32_SSE41(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_lerp32_SSE41(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_fir4_32_SSE3(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_fir4_32_SSE3(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_fir4_32_SSE41(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_fir4_32_SSE41(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_fir8_32_SSE3(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_fir8_32_SSE3(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_fir8_32_SSE41(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_fir8_32_SSE41(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_bsinc32_SSE(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_bsinc32_SSE(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); @@ -109,16 +109,16 @@ void MixRow_Neon(ALfloat *OutBuffer, const ALfloat *Gains, ALsizei InPos, ALsizei BufferSize); /* Neon resamplers */ -const ALfloat *Resample_lerp32_Neon(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_lerp32_Neon(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_fir4_32_Neon(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_fir4_32_Neon(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_fir8_32_Neon(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_fir8_32_Neon(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei numsamples); -const ALfloat *Resample_bsinc32_Neon(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_bsinc32_Neon(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen); diff --git a/Alc/mixer_neon.c b/Alc/mixer_neon.c index 533817ff..543ff0f3 100644 --- a/Alc/mixer_neon.c +++ b/Alc/mixer_neon.c @@ -10,9 +10,9 @@ #include "mixer_defs.h" -const ALfloat *Resample_lerp32_Neon(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_lerp32_Neon(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const int32x4_t increment4 = vdupq_n_s32(increment*4); const float32x4_t fracOne4 = vdupq_n_f32(1.0f/FRACTIONONE); @@ -66,9 +66,9 @@ const ALfloat *Resample_lerp32_Neon(const BsincState* UNUSED(state), const ALflo return dst; } -const ALfloat *Resample_fir4_32_Neon(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_fir4_32_Neon(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const int32x4_t increment4 = vdupq_n_s32(increment*4); const uint32x4_t fracMask4 = vdupq_n_u32(FRACTIONMASK); @@ -136,9 +136,9 @@ const ALfloat *Resample_fir4_32_Neon(const BsincState* UNUSED(state), const ALfl return dst; } -const ALfloat *Resample_fir8_32_Neon(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_fir8_32_Neon(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const int32x4_t increment4 = vdupq_n_s32(increment*4); const uint32x4_t fracMask4 = vdupq_n_u32(FRACTIONMASK); @@ -211,18 +211,18 @@ const ALfloat *Resample_fir8_32_Neon(const BsincState* UNUSED(state), const ALfl return dst; } -const ALfloat *Resample_bsinc32_Neon(const BsincState *state, const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei dstlen) +const ALfloat *Resample_bsinc32_Neon(const InterpState *state, + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei dstlen) { - const float32x4_t sf4 = vdupq_n_f32(state->sf); - const ALsizei m = state->m; + const float32x4_t sf4 = vdupq_n_f32(state->bsinc.sf); + const ALsizei m = state->bsinc.m; const ALfloat *fil, *scd, *phd, *spd; ALsizei pi, i, j; float32x4_t r4; ALfloat pf; - src += state->l; + src += state->bsinc.l; for(i = 0;i < dstlen;i++) { // Calculate the phase index and factor. @@ -231,10 +231,10 @@ const ALfloat *Resample_bsinc32_Neon(const BsincState *state, const ALfloat *res pf = (frac & ((1<coeffs[pi].filter, 16); - scd = ASSUME_ALIGNED(state->coeffs[pi].scDelta, 16); - phd = ASSUME_ALIGNED(state->coeffs[pi].phDelta, 16); - spd = ASSUME_ALIGNED(state->coeffs[pi].spDelta, 16); + fil = ASSUME_ALIGNED(state->bsinc.coeffs[pi].filter, 16); + scd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].scDelta, 16); + phd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].phDelta, 16); + spd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].spDelta, 16); // Apply the scale and phase interpolated filter. r4 = vdupq_n_f32(0.0f); diff --git a/Alc/mixer_sse.c b/Alc/mixer_sse.c index 8aeb8211..7870a6d8 100644 --- a/Alc/mixer_sse.c +++ b/Alc/mixer_sse.c @@ -12,18 +12,18 @@ #include "mixer_defs.h" -const ALfloat *Resample_bsinc32_SSE(const BsincState *state, const ALfloat *restrict src, +const ALfloat *Resample_bsinc32_SSE(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen) { - const __m128 sf4 = _mm_set1_ps(state->sf); - const ALsizei m = state->m; + const __m128 sf4 = _mm_set1_ps(state->bsinc.sf); + const ALsizei m = state->bsinc.m; const ALfloat *fil, *scd, *phd, *spd; ALsizei pi, i, j; ALfloat pf; __m128 r4; - src += state->l; + src += state->bsinc.l; for(i = 0;i < dstlen;i++) { // Calculate the phase index and factor. @@ -32,10 +32,10 @@ const ALfloat *Resample_bsinc32_SSE(const BsincState *state, const ALfloat *rest pf = (frac & ((1<coeffs[pi].filter, 16); - scd = ASSUME_ALIGNED(state->coeffs[pi].scDelta, 16); - phd = ASSUME_ALIGNED(state->coeffs[pi].phDelta, 16); - spd = ASSUME_ALIGNED(state->coeffs[pi].spDelta, 16); + fil = ASSUME_ALIGNED(state->bsinc.coeffs[pi].filter, 16); + scd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].scDelta, 16); + phd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].phDelta, 16); + spd = ASSUME_ALIGNED(state->bsinc.coeffs[pi].spDelta, 16); // Apply the scale and phase interpolated filter. r4 = _mm_setzero_ps(); diff --git a/Alc/mixer_sse2.c b/Alc/mixer_sse2.c index 5cf4c8a0..a1e8507e 100644 --- a/Alc/mixer_sse2.c +++ b/Alc/mixer_sse2.c @@ -27,9 +27,9 @@ #include "mixer_defs.h" -const ALfloat *Resample_lerp32_SSE2(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_lerp32_SSE2(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const __m128i increment4 = _mm_set1_epi32(increment*4); const __m128 fracOne4 = _mm_set1_ps(1.0f/FRACTIONONE); diff --git a/Alc/mixer_sse3.c b/Alc/mixer_sse3.c index 34121d71..3b444158 100644 --- a/Alc/mixer_sse3.c +++ b/Alc/mixer_sse3.c @@ -31,9 +31,9 @@ #include "mixer_defs.h" -const ALfloat *Resample_fir4_32_SSE3(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_fir4_32_SSE3(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const __m128i increment4 = _mm_set1_epi32(increment*4); const __m128i fracMask4 = _mm_set1_epi32(FRACTIONMASK); @@ -96,9 +96,9 @@ const ALfloat *Resample_fir4_32_SSE3(const BsincState* UNUSED(state), const ALfl return dst; } -const ALfloat *Resample_fir8_32_SSE3(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_fir8_32_SSE3(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const __m128i increment4 = _mm_set1_epi32(increment*4); const __m128i fracMask4 = _mm_set1_epi32(FRACTIONMASK); diff --git a/Alc/mixer_sse41.c b/Alc/mixer_sse41.c index a531ca77..7ae5bec7 100644 --- a/Alc/mixer_sse41.c +++ b/Alc/mixer_sse41.c @@ -28,9 +28,9 @@ #include "mixer_defs.h" -const ALfloat *Resample_lerp32_SSE41(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_lerp32_SSE41(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const __m128i increment4 = _mm_set1_epi32(increment*4); const __m128 fracOne4 = _mm_set1_ps(1.0f/FRACTIONONE); @@ -85,9 +85,9 @@ const ALfloat *Resample_lerp32_SSE41(const BsincState* UNUSED(state), const ALfl return dst; } -const ALfloat *Resample_fir4_32_SSE41(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_fir4_32_SSE41(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const __m128i increment4 = _mm_set1_epi32(increment*4); const __m128i fracMask4 = _mm_set1_epi32(FRACTIONMASK); @@ -153,9 +153,9 @@ const ALfloat *Resample_fir4_32_SSE41(const BsincState* UNUSED(state), const ALf return dst; } -const ALfloat *Resample_fir8_32_SSE41(const BsincState* UNUSED(state), const ALfloat *restrict src, - ALuint frac, ALint increment, ALfloat *restrict dst, - ALsizei numsamples) +const ALfloat *Resample_fir8_32_SSE41(const InterpState* UNUSED(state), + const ALfloat *restrict src, ALuint frac, ALint increment, + ALfloat *restrict dst, ALsizei numsamples) { const __m128i increment4 = _mm_set1_epi32(increment*4); const __m128i fracMask4 = _mm_set1_epi32(FRACTIONMASK); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 4f04efe2..3111a48a 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -92,7 +92,7 @@ typedef struct ALvoice { alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES]; - BsincState SincState; + InterpState ResampleState; struct { ALfloat (*Buffer)[BUFFERSIZE]; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 642fb944..c3c7a20c 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -62,6 +62,10 @@ typedef struct BsincState { } coeffs[BSINC_PHASE_COUNT]; } BsincState; +typedef union InterpState { + BsincState bsinc; +} InterpState; + typedef union aluVector { alignas(16) ALfloat v[4]; @@ -148,7 +152,7 @@ typedef struct SendParams { } SendParams; -typedef const ALfloat* (*ResamplerFunc)(const BsincState *state, +typedef const ALfloat* (*ResamplerFunc)(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, ALfloat *restrict dst, ALsizei dstlen ); -- cgit v1.2.3 From 0d19a209014582f1e77ab3b927dfb1af6c307d66 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 13 Feb 2017 21:18:18 -0800 Subject: Make the source state atomic Since it's modified by the mixer when playback is ended, a plain struct member isn't safe. --- Alc/ALc.c | 3 +-- Alc/ALu.c | 10 ++++++---- Alc/mixer.c | 2 +- OpenAL32/Include/alSource.h | 9 ++++++++- OpenAL32/alSource.c | 46 ++++++++++++++++++++------------------------- 5 files changed, 36 insertions(+), 34 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index fcc6d649..69e37540 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1697,8 +1697,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) ALsource *Source = context->SourceMap.values[pos]; ALenum new_state; - if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - Source->OffsetType != AL_NONE) + if(Source->OffsetType != AL_NONE && IsPlayingOrPaused(Source)) { WriteLock(&Source->queue_lock); ApplyOffset(Source); diff --git a/Alc/ALu.c b/Alc/ALu.c index 42f229a2..31dd6271 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1326,7 +1326,7 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) for(;voice != voice_end;++voice) { if(!(source=voice->Source)) continue; - if(source->state != AL_PLAYING && source->state != AL_PAUSED) + if(!IsPlayingOrPaused(source)) voice->Source = NULL; else CalcSourceParams(voice, ctx, force); @@ -1449,7 +1449,8 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { ALboolean IsVoiceInit = (voice->Step > 0); source = voice->Source; - if(source && source->state == AL_PLAYING && IsVoiceInit) + if(IsVoiceInit && source && + ATOMIC_LOAD(&source->state, almemory_order_relaxed) == AL_PLAYING) MixSource(voice, source, device, SamplesToDo); } @@ -1614,12 +1615,13 @@ void aluHandleDisconnect(ALCdevice *device) voice_end = voice + Context->VoiceCount; while(voice != voice_end) { + ALenum playing = AL_PLAYING; ALsource *source = voice->Source; voice->Source = NULL; - if(source && source->state == AL_PLAYING) + if(source && + ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED)) { - source->state = AL_STOPPED; ATOMIC_STORE(&source->current_buffer, NULL, almemory_order_relaxed); ATOMIC_STORE(&source->position, 0, almemory_order_relaxed); ATOMIC_STORE(&source->position_fraction, 0, almemory_order_release); diff --git a/Alc/mixer.c b/Alc/mixer.c index 592d51d4..179c028e 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -711,7 +711,7 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp voice->Moving = AL_TRUE; /* Update source info */ - Source->state = State; + ATOMIC_STORE(&Source->state, State, almemory_order_relaxed); ATOMIC_STORE(&Source->current_buffer, BufferListItem, almemory_order_relaxed); ATOMIC_STORE(&Source->position, DataPosInt, almemory_order_relaxed); ATOMIC_STORE(&Source->position_fraction, DataPosFrac, almemory_order_release); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 3111a48a..b9479905 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -175,7 +175,7 @@ typedef struct ALsource { ALint SourceType; /** Source state (initial, playing, paused, or stopped) */ - ALenum state; + ATOMIC(ALenum) state; ALenum new_state; /** Source Buffer Queue info. */ @@ -224,6 +224,13 @@ void UpdateAllSourceProps(ALCcontext *context); ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source); +inline ALboolean IsPlayingOrPaused(ALsource *source) +{ + ALenum state = ATOMIC_LOAD_SEQ(&source->state); + return state == AL_PLAYING || state == AL_PAUSED; +} + + ALvoid ReleaseALSources(ALCcontext *Context); #ifdef __cplusplus diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index c60cd790..edcb49cd 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -46,6 +46,7 @@ extern inline void LockSourcesWrite(ALCcontext *context); extern inline void UnlockSourcesWrite(ALCcontext *context); extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); +extern inline ALboolean IsPlayingOrPaused(ALsource *source); static void InitSourceParams(ALsource *Source); static void DeinitSource(ALsource *source); @@ -524,7 +525,7 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p Source->OffsetType = prop; Source->Offset = *values; - if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && + if(IsPlayingOrPaused(Source) && !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) { ALCdevice_Lock(Context->Device); @@ -671,7 +672,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } WriteLock(&Source->queue_lock); - if(!(Source->state == AL_STOPPED || Source->state == AL_INITIAL)) + if(IsPlayingOrPaused(Source)) { WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); @@ -725,7 +726,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->OffsetType = prop; Source->Offset = *values; - if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && + if(IsPlayingOrPaused(Source) && !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) { ALCdevice_Lock(Context->Device); @@ -843,8 +844,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } UnlockFiltersRead(device); - if(slot != Source->Send[values[1]].Slot && - (Source->state == AL_PLAYING || Source->state == AL_PAUSED)) + if(slot != Source->Send[values[1]].Slot && IsPlayingOrPaused(Source)) { /* Add refcount on the new slot, and release the previous slot */ if(slot) IncrementRef(&slot->ref); @@ -1227,7 +1227,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_SOURCE_STATE: - *values = Source->state; + *values = ATOMIC_LOAD_SEQ(&Source->state); return AL_TRUE; case AL_BYTE_LENGTH_SOFT: @@ -2767,7 +2767,7 @@ static void InitSourceParams(ALsource *Source) Source->Offset = 0.0; Source->OffsetType = AL_NONE; Source->SourceType = AL_UNDETERMINED; - Source->state = AL_INITIAL; + ATOMIC_INIT(&Source->state, AL_INITIAL); Source->new_state = AL_NONE; ATOMIC_INIT(&Source->queue, NULL); @@ -2926,9 +2926,7 @@ void UpdateAllSourceProps(ALCcontext *context) { ALvoice *voice = &context->Voices[pos]; ALsource *source = voice->Source; - if(source != NULL && (source->state == AL_PLAYING || - source->state == AL_PAUSED) && - source->NeedsUpdate) + if(source != NULL && source->NeedsUpdate && IsPlayingOrPaused(source)) { source->NeedsUpdate = AL_FALSE; UpdateSourceProps(source, num_sends); @@ -2963,19 +2961,15 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) BufferList = BufferList->next; } - if(Source->state != AL_PAUSED) + if(ATOMIC_EXCHANGE(ALenum, &Source->state, AL_PLAYING, almemory_order_acq_rel) == AL_PAUSED) + discontinuity = AL_FALSE; + else { - Source->state = AL_PLAYING; ATOMIC_STORE(&Source->current_buffer, BufferList, almemory_order_relaxed); ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); ATOMIC_STORE(&Source->position_fraction, 0, almemory_order_release); discontinuity = AL_TRUE; } - else - { - Source->state = AL_PLAYING; - discontinuity = AL_FALSE; - } // Check if an Offset has been set if(Source->OffsetType != AL_NONE) @@ -3041,15 +3035,15 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } else if(state == AL_PAUSED) { - if(Source->state == AL_PLAYING) - Source->state = AL_PAUSED; + ALenum playing = AL_PLAYING; + ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &Source->state, &playing, AL_PAUSED); } else if(state == AL_STOPPED) { do_stop: - if(Source->state != AL_INITIAL) + if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) != AL_INITIAL) { - Source->state = AL_STOPPED; + ATOMIC_STORE(&Source->state, AL_STOPPED, almemory_order_relaxed); ATOMIC_STORE_SEQ(&Source->current_buffer, NULL); } Source->OffsetType = AL_NONE; @@ -3057,9 +3051,9 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } else if(state == AL_INITIAL) { - if(Source->state != AL_INITIAL) + if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) != AL_INITIAL) { - Source->state = AL_INITIAL; + ATOMIC_STORE(&Source->state, AL_INITIAL, almemory_order_relaxed); ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD_SEQ(&Source->queue), almemory_order_relaxed); ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); @@ -3085,7 +3079,7 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCdevice *device, ALuint ALuint refcount; ReadLock(&Source->queue_lock); - if(Source->state != AL_PLAYING && Source->state != AL_PAUSED) + if(!IsPlayingOrPaused(Source)) { ReadUnlock(&Source->queue_lock); do { @@ -3135,7 +3129,7 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCdevice *device, ALuint64 ALuint refcount; ReadLock(&Source->queue_lock); - if(Source->state != AL_PLAYING && Source->state != AL_PAUSED) + if(!IsPlayingOrPaused(Source)) { ReadUnlock(&Source->queue_lock); do { @@ -3200,7 +3194,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device ALuint refcount; ReadLock(&Source->queue_lock); - if(Source->state != AL_PLAYING && Source->state != AL_PAUSED) + if(!IsPlayingOrPaused(Source)) { ReadUnlock(&Source->queue_lock); return 0.0; -- cgit v1.2.3 From 69dd57096183c4e381cc3f5c0a8ac4e33048b346 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 13 Feb 2017 21:30:20 -0800 Subject: Fix build with non-C11 atomics --- OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index b9479905..d45e5d9c 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -224,7 +224,7 @@ void UpdateAllSourceProps(ALCcontext *context); ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source); -inline ALboolean IsPlayingOrPaused(ALsource *source) +inline ALboolean IsPlayingOrPaused(const ALsource *source) { ALenum state = ATOMIC_LOAD_SEQ(&source->state); return state == AL_PLAYING || state == AL_PAUSED; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index edcb49cd..036b7542 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -46,7 +46,7 @@ extern inline void LockSourcesWrite(ALCcontext *context); extern inline void UnlockSourcesWrite(ALCcontext *context); extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); -extern inline ALboolean IsPlayingOrPaused(ALsource *source); +extern inline ALboolean IsPlayingOrPaused(const ALsource *source); static void InitSourceParams(ALsource *Source); static void DeinitSource(ALsource *source); @@ -141,7 +141,7 @@ static inline ALvoice *GetSourceVoice(const ALsource *source, const ALCcontext * static inline bool SourceShouldUpdate(const ALsource *source, const ALCcontext *context) { - return (source->state == AL_PLAYING || source->state == AL_PAUSED) && + return IsPlayingOrPaused(source) && !ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); } -- cgit v1.2.3 From 5a50c46c22e7e6c5f119613584d826bc7b7b4a61 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 14 Feb 2017 19:59:39 -0800 Subject: Make ALsourceProps' Send array dynamically sized ALsourceProps' Send[] array is placed at the end of the struct, and given an indeterminate size. Extra space is allocated at the end of each struct given the number of auxiliary sends set for the device. --- Alc/ALc.c | 99 ++++++++++++++++++++++++++++++++++++++++----- Alc/ALu.c | 22 +++++----- Alc/helpers.c | 1 + OpenAL32/Include/alMain.h | 9 +++++ OpenAL32/Include/alSource.h | 8 ++-- OpenAL32/alSource.c | 21 +++------- 6 files changed, 121 insertions(+), 39 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 69e37540..1028321e 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1769,6 +1769,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) ALCcontext *context; enum HrtfRequestMode hrtf_appreq = Hrtf_Default; enum HrtfRequestMode hrtf_userreq = Hrtf_Default; + ALsizei old_sends = device->NumAuxSends; enum DevFmtChannels oldChans; enum DevFmtType oldType; ALCuint oldFreq; @@ -2183,7 +2184,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALsizei pos; - ReadLock(&context->PropLock); + WriteLock(&context->PropLock); LockUIntMapRead(&context->EffectSlotMap); for(pos = 0;pos < context->EffectSlotMap.size;pos++) { @@ -2208,8 +2209,10 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) for(pos = 0;pos < context->SourceMap.size;pos++) { ALsource *source = context->SourceMap.values[pos]; - ALuint s = device->NumAuxSends; - while(s < MAX_SENDS) + struct ALsourceProps *props; + ALsizei s; + + for(s = device->NumAuxSends;s < MAX_SENDS;s++) { if(source->Send[s].Slot) DecrementRef(&source->Send[s].Slot->ref); @@ -2219,14 +2222,32 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) source->Send[s].HFReference = LOWPASSFREQREF; source->Send[s].GainLF = 1.0f; source->Send[s].LFReference = HIGHPASSFREQREF; - s++; } + source->NeedsUpdate = AL_TRUE; + + /* Clear any pre-existing source property structs, in case the + * number of auxiliary sends changed. Playing (or paused) sources + * will have updates specified. + */ + props = ATOMIC_EXCHANGE_SEQ(struct ALsourceProps*, &source->Update, NULL); + al_free(props); + + props = ATOMIC_EXCHANGE(struct ALsourceProps*, &source->FreeList, NULL, + almemory_order_relaxed); + while(props) + { + struct ALsourceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + al_free(props); + props = next; + } } + AllocateVoices(context, context->MaxVoices, old_sends); UnlockUIntMapRead(&context->SourceMap); UpdateListenerProps(context); - ReadUnlock(&context->PropLock); + UpdateAllSourceProps(context); + WriteUnlock(&context->PropLock); context = context->next; } @@ -2595,6 +2616,65 @@ ALCcontext *GetContextRef(void) } +void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) +{ + ALCdevice *device = context->Device; + ALsizei num_sends = device->NumAuxSends; + struct ALsourceProps *props; + size_t sizeof_props; + ALvoice *voices; + ALsizei v = 0; + size_t size; + + if(num_voices == context->MaxVoices && num_sends == old_sends) + return; + + /* Allocate the voices, and the voices' stored source property set + * (including the dynamically-sized Send[] array) in one chunk. + */ + sizeof_props = RoundUp(offsetof(struct ALsourceProps, Send[num_sends]), 16); + size = sizeof(*voices) + sizeof_props; + + voices = al_calloc(16, size * num_voices); + props = (struct ALsourceProps*)(voices + num_voices); + + if(context->Voices) + { + ALsizei v_count = mini(context->VoiceCount, num_voices); + for(;v < v_count;v++) + { + ALsizei s_count = mini(old_sends, num_sends); + ALsizei i; + + /* Copy the old voice data and source property set to the new + * storage. + */ + voices[v] = context->Voices[v]; + *props = *(context->Voices[v].Props); + for(i = 0;i < s_count;i++) + props->Send[i] = context->Voices[v].Props->Send[i]; + + /* Set this voice's property set pointer and increment 'props' to + * the next property storage space. + */ + voices[v].Props = props; + props = (struct ALsourceProps*)((char*)props + sizeof_props); + } + } + /* Finish setting the voices' property set pointers. */ + for(;v < num_voices;v++) + { + voices[v].Props = props; + props = (struct ALsourceProps*)((char*)props + sizeof_props); + } + + al_free(context->Voices); + context->Voices = voices; + context->MaxVoices = num_voices; + context->VoiceCount = mini(context->VoiceCount, num_voices); +} + + /************************************************ * Standard ALC functions ************************************************/ @@ -3267,11 +3347,13 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin InitRef(&ALContext->ref, 1); ALContext->Listener = (ALlistener*)ALContext->_listener_mem; + ALContext->Device = device; ATOMIC_INIT(&ALContext->ActiveAuxSlotList, NULL); + ALContext->Voices = NULL; + ALContext->MaxVoices = 0; ALContext->VoiceCount = 0; - ALContext->MaxVoices = 256; - ALContext->Voices = al_calloc(16, ALContext->MaxVoices * sizeof(ALContext->Voices[0])); + AllocateVoices(ALContext, 256, device->NumAuxSends); } if(!ALContext || !ALContext->Voices) { @@ -3312,8 +3394,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin return NULL; } - ALContext->Device = device; - ALCdevice_IncRef(device); + ALCdevice_IncRef(ALContext->Device); InitContext(ALContext); if(ConfigValueFloat(al_string_get_cstr(device->DeviceName), NULL, "volume-adjust", &valf)) diff --git a/Alc/ALu.c b/Alc/ALu.c index 31dd6271..3cb02f84 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -807,14 +807,6 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro ALint NumSends; ALint i; - DryGainHF = 1.0f; - DryGainLF = 1.0f; - for(i = 0;i < MAX_SENDS;i++) - { - WetGainHF[i] = 1.0f; - WetGainLF[i] = 1.0f; - } - /* Get context/device properties */ DopplerFactor = Listener->Params.DopplerFactor; SpeedOfSound = Listener->Params.SpeedOfSound; @@ -989,8 +981,14 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro /* Source Gain + Attenuation */ DryGain = SourceVolume * Attenuation; + DryGainHF = 1.0f; + DryGainLF = 1.0f; for(i = 0;i < NumSends;i++) + { WetGain[i] = SourceVolume * RoomAttenuation[i]; + WetGainHF[i] = 1.0f; + WetGainLF[i] = 1.0f; + } /* Distance-based air absorption */ if(AirAbsorptionFactor > 0.0f && ClampedDist > MinDist) @@ -1284,7 +1282,9 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc if(props) { - voice->Props = *props; + memcpy(voice->Props, props, + offsetof(struct ALsourceProps, Send[context->Device->NumAuxSends]) + ); ATOMIC_REPLACE_HEAD(struct ALsourceProps*, &source->FreeList, props); } @@ -1296,9 +1296,9 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc if((buffer=BufferListItem->buffer) != NULL) { if(buffer->FmtChannels == FmtMono) - CalcAttnSourceParams(voice, &voice->Props, buffer, context); + CalcAttnSourceParams(voice, voice->Props, buffer, context); else - CalcNonAttnSourceParams(voice, &voice->Props, buffer, context); + CalcNonAttnSourceParams(voice, voice->Props, buffer, context); break; } BufferListItem = BufferListItem->next; diff --git a/Alc/helpers.c b/Alc/helpers.c index eac3811d..1ce567b2 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -112,6 +112,7 @@ DEFINE_PROPERTYKEY(PKEY_AudioEndpoint_GUID, 0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x extern inline ALuint NextPowerOf2(ALuint value); +extern inline size_t RoundUp(size_t value, size_t r); extern inline ALint fastf2i(ALfloat f); extern inline ALuint fastf2u(ALfloat f); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 2573c836..947a16ba 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -356,6 +356,13 @@ inline ALuint NextPowerOf2(ALuint value) return value+1; } +/** Round up a value to the next multiple. */ +inline size_t RoundUp(size_t value, size_t r) +{ + value += r-1; + return value - (value%r); +} + /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero * mode. */ inline ALint fastf2i(ALfloat f) @@ -813,6 +820,8 @@ ALCcontext *GetContextRef(void); void ALCcontext_IncRef(ALCcontext *context); void ALCcontext_DecRef(ALCcontext *context); +void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends); + void AppendAllDevicesList(const ALCchar *name); void AppendCaptureDeviceList(const ALCchar *name); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index d45e5d9c..cc9dd763 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -23,6 +23,8 @@ typedef struct ALbufferlistitem { struct ALsourceProps { + ATOMIC(struct ALsourceProps*) next; + ATOMIC(ALfloat) Pitch; ATOMIC(ALfloat) Gain; ATOMIC(ALfloat) OuterGain; @@ -69,14 +71,12 @@ struct ALsourceProps { ATOMIC(ALfloat) HFReference; ATOMIC(ALfloat) GainLF; ATOMIC(ALfloat) LFReference; - } Send[MAX_SENDS]; - - ATOMIC(struct ALsourceProps*) next; + } Send[]; }; typedef struct ALvoice { - struct ALsourceProps Props; + struct ALsourceProps *Props; struct ALsource *Source; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 036b7542..56d2b415 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2306,23 +2306,13 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ALCdevice_Lock(context->Device); while(n > context->MaxVoices-context->VoiceCount) { - ALvoice *temp = NULL; - ALsizei newcount; - - newcount = context->MaxVoices << 1; - if(newcount > 0) - temp = al_malloc(16, newcount * sizeof(context->Voices[0])); - if(!temp) + ALsizei newcount = context->MaxVoices << 1; + if(context->MaxVoices >= newcount) { ALCdevice_Unlock(context->Device); SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } - memcpy(temp, context->Voices, context->MaxVoices * sizeof(temp[0])); - memset(&temp[context->MaxVoices], 0, (newcount-context->MaxVoices) * sizeof(temp[0])); - - al_free(context->Voices); - context->Voices = temp; - context->MaxVoices = newcount; + AllocateVoices(context, newcount, context->Device->NumAuxSends); } if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll) @@ -2757,6 +2747,7 @@ static void InitSourceParams(ALsource *Source) Source->Direct.LFReference = HIGHPASSFREQREF; for(i = 0;i < MAX_SENDS;i++) { + Source->Send[i].Slot = NULL; Source->Send[i].Gain = 1.0f; Source->Send[i].GainHF = 1.0f; Source->Send[i].HFReference = LOWPASSFREQREF; @@ -2819,7 +2810,7 @@ static void DeinitSource(ALsource *source) BufferList = next; } - for(i = 0;i < MAX_SENDS;++i) + for(i = 0;i < MAX_SENDS;i++) { if(source->Send[i].Slot) DecrementRef(&source->Send[i].Slot->ref); @@ -2835,7 +2826,7 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends) /* Get an unused property container, or allocate a new one as needed. */ props = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire); if(!props) - props = al_calloc(16, sizeof(*props)); + props = al_calloc(16, offsetof(struct ALsourceProps, Send[num_sends])); else { struct ALsourceProps *next; -- cgit v1.2.3 From 909193a345469529ec98b8b01379738facee861d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 15 Feb 2017 17:40:26 -0800 Subject: Reorganize ALvoice members This places the Send[] array at the end of the struct, making it easier to handle dynamically. --- Alc/ALu.c | 168 +++++++++++++++++++++++--------------------- Alc/mixer.c | 15 ++-- OpenAL32/Include/alSource.h | 13 ++-- OpenAL32/alSource.c | 6 +- 4 files changed, 104 insertions(+), 98 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 3cb02f84..d5065199 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -407,8 +407,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * StereoMap[0].angle = -ATOMIC_LOAD(&props->StereoPan[0], almemory_order_relaxed); StereoMap[1].angle = -ATOMIC_LOAD(&props->StereoPan[1], almemory_order_relaxed); - voice->DirectOut.Buffer = Device->Dry.Buffer; - voice->DirectOut.Channels = Device->Dry.NumChannels; + voice->Direct.Buffer = Device->Dry.Buffer; + voice->Direct.Channels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); @@ -417,13 +417,13 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) { SendSlots[i] = NULL; - voice->SendOut[i].Buffer = NULL; - voice->SendOut[i].Channels = 0; + voice->Send[i].Buffer = NULL; + voice->Send[i].Channels = 0; } else { - voice->SendOut[i].Buffer = SendSlots[i]->WetBuffer; - voice->SendOut[i].Channels = SendSlots[i]->NumChannels; + voice->Send[i].Buffer = SendSlots[i]->WetBuffer; + voice->Send[i].Channels = SendSlots[i]->NumChannels; } } @@ -534,11 +534,11 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * 0.0f, -V[0]*scale, V[1]*scale, -V[2]*scale ); - voice->DirectOut.Buffer = Device->FOAOut.Buffer; - voice->DirectOut.Channels = Device->FOAOut.NumChannels; + voice->Direct.Buffer = Device->FOAOut.Buffer; + voice->Direct.Channels = Device->FOAOut.NumChannels; for(c = 0;c < num_channels;c++) ComputeFirstOrderGains(Device->FOAOut, matrix.m[c], DryGain, - voice->Chan[c].Direct.Gains.Target); + voice->Direct.Params[c].Gains.Target); for(i = 0;i < NumSends;i++) { @@ -547,7 +547,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * for(c = 0;c < num_channels;c++) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; + voice->Send[i].Params[c].Gains.Target[j] = 0.0f; } } else @@ -555,8 +555,9 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * for(c = 0;c < num_channels;c++) { const ALeffectslot *Slot = SendSlots[i]; - ComputeFirstOrderGainsBF(Slot->ChanMap, Slot->NumChannels, matrix.m[c], - WetGain[i], voice->Chan[c].Send[i].Gains.Target); + ComputeFirstOrderGainsBF(Slot->ChanMap, Slot->NumChannels, + matrix.m[c], WetGain[i], voice->Send[i].Params[c].Gains.Target + ); } } } @@ -570,15 +571,15 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(DirectChannels) { /* Skip the virtual channels and write inputs to the real output. */ - voice->DirectOut.Buffer = Device->RealOut.Buffer; - voice->DirectOut.Channels = Device->RealOut.NumChannels; + voice->Direct.Buffer = Device->RealOut.Buffer; + voice->Direct.Channels = Device->RealOut.NumChannels; for(c = 0;c < num_channels;c++) { int idx; for(j = 0;j < MAX_OUTPUT_CHANNELS;j++) - voice->Chan[c].Direct.Gains.Target[j] = 0.0f; + voice->Direct.Params[c].Gains.Target[j] = 0.0f; if((idx=GetChannelIdxByName(Device->RealOut, chans[c].channel)) != -1) - voice->Chan[c].Direct.Gains.Target[idx] = DryGain; + voice->Direct.Params[c].Gains.Target[idx] = DryGain; } /* Auxiliary sends still use normal panning since they mix to B-Format, which can't @@ -592,13 +593,14 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(!SendSlots[i]) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; + voice->Send[i].Params[c].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Chan[c].Send[i].Gains.Target); + ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, + coeffs, WetGain[i], voice->Send[i].Params[c].Gains.Target + ); } } } @@ -610,25 +612,25 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * /* Full HRTF rendering. Skip the virtual channels and render each * input channel to the real outputs. */ - voice->DirectOut.Buffer = Device->RealOut.Buffer; - voice->DirectOut.Channels = Device->RealOut.NumChannels; + voice->Direct.Buffer = Device->RealOut.Buffer; + voice->Direct.Channels = Device->RealOut.NumChannels; for(c = 0;c < num_channels;c++) { if(chans[c].channel == LFE) { /* Skip LFE */ - voice->Chan[c].Direct.Hrtf.Target.Delay[0] = 0; - voice->Chan[c].Direct.Hrtf.Target.Delay[1] = 0; + voice->Direct.Params[c].Hrtf.Target.Delay[0] = 0; + voice->Direct.Params[c].Hrtf.Target.Delay[1] = 0; for(i = 0;i < HRIR_LENGTH;i++) { - voice->Chan[c].Direct.Hrtf.Target.Coeffs[i][0] = 0.0f; - voice->Chan[c].Direct.Hrtf.Target.Coeffs[i][1] = 0.0f; + voice->Direct.Params[c].Hrtf.Target.Coeffs[i][0] = 0.0f; + voice->Direct.Params[c].Hrtf.Target.Coeffs[i][1] = 0.0f; } for(i = 0;i < NumSends;i++) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; + voice->Send[i].Params[c].Gains.Target[j] = 0.0f; } continue; @@ -637,8 +639,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * /* Get the static HRIR coefficients and delays for this channel. */ GetHrtfCoeffs(Device->Hrtf.Handle, chans[c].elevation, chans[c].angle, 0.0f, DryGain, - voice->Chan[c].Direct.Hrtf.Target.Coeffs, - voice->Chan[c].Direct.Hrtf.Target.Delay + voice->Direct.Params[c].Hrtf.Target.Coeffs, + voice->Direct.Params[c].Hrtf.Target.Delay ); /* Normal panning for auxiliary sends. */ @@ -649,13 +651,14 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(!SendSlots[i]) { for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; + voice->Send[i].Params[c].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Chan[c].Send[i].Gains.Target); + ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, + coeffs, WetGain[i], voice->Send[i].Params[c].Gains.Target + ); } } } @@ -671,19 +674,19 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * if(chans[c].channel == LFE) { for(j = 0;j < MAX_OUTPUT_CHANNELS;j++) - voice->Chan[c].Direct.Gains.Target[j] = 0.0f; + voice->Direct.Params[c].Gains.Target[j] = 0.0f; if(Device->Dry.Buffer == Device->RealOut.Buffer) { int idx; if((idx=GetChannelIdxByName(Device->RealOut, chans[c].channel)) != -1) - voice->Chan[c].Direct.Gains.Target[idx] = DryGain; + voice->Direct.Params[c].Gains.Target[idx] = DryGain; } for(i = 0;i < NumSends;i++) { ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; + voice->Direct.Params[c].Gains.Target[j] = 0.0f; } continue; } @@ -693,10 +696,10 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * /* Clamp X so it remains within 30 degrees of 0 or 180 degree azimuth. */ ALfloat x = sinf(chans[c].angle) * cosf(chans[c].elevation); coeffs[0] = clampf(-x, -0.5f, 0.5f) + 0.5f; - voice->Chan[c].Direct.Gains.Target[0] = coeffs[0] * DryGain; - voice->Chan[c].Direct.Gains.Target[1] = (1.0f-coeffs[0]) * DryGain; + voice->Direct.Params[c].Gains.Target[0] = coeffs[0] * DryGain; + voice->Direct.Params[c].Gains.Target[1] = (1.0f-coeffs[0]) * DryGain; for(j = 2;j < MAX_OUTPUT_CHANNELS;j++) - voice->Chan[c].Direct.Gains.Target[j] = 0.0f; + voice->Direct.Params[c].Gains.Target[j] = 0.0f; CalcAngleCoeffs(chans[c].angle, chans[c].elevation, 0.0f, coeffs); } @@ -704,7 +707,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * { CalcAngleCoeffs(chans[c].angle, chans[c].elevation, 0.0f, coeffs); ComputePanningGains(Device->Dry, coeffs, DryGain, - voice->Chan[c].Direct.Gains.Target); + voice->Direct.Params[c].Gains.Target); } for(i = 0;i < NumSends;i++) @@ -713,13 +716,14 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * { ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Chan[c].Send[i].Gains.Target[j] = 0.0f; + voice->Send[i].Params[c].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Chan[c].Send[i].Gains.Target); + ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, + coeffs, WetGain[i], voice->Send[i].Params[c].Gains.Target + ); } } } @@ -737,15 +741,15 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * DryGainLF = maxf(DryGainLF, 0.0001f); for(c = 0;c < num_channels;c++) { - voice->Chan[c].Direct.FilterType = AF_None; - if(DryGainHF != 1.0f) voice->Chan[c].Direct.FilterType |= AF_LowPass; - if(DryGainLF != 1.0f) voice->Chan[c].Direct.FilterType |= AF_HighPass; + voice->Direct.Params[c].FilterType = AF_None; + if(DryGainHF != 1.0f) voice->Direct.Params[c].FilterType |= AF_LowPass; + if(DryGainLF != 1.0f) voice->Direct.Params[c].FilterType |= AF_HighPass; ALfilterState_setParams( - &voice->Chan[c].Direct.LowPass, ALfilterType_HighShelf, + &voice->Direct.Params[c].LowPass, ALfilterType_HighShelf, DryGainHF, hfscale, calc_rcpQ_from_slope(DryGainHF, 0.75f) ); ALfilterState_setParams( - &voice->Chan[c].Direct.HighPass, ALfilterType_LowShelf, + &voice->Direct.Params[c].HighPass, ALfilterType_LowShelf, DryGainLF, lfscale, calc_rcpQ_from_slope(DryGainLF, 0.75f) ); } @@ -760,15 +764,15 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * WetGainLF[i] = maxf(WetGainLF[i], 0.0001f); for(c = 0;c < num_channels;c++) { - voice->Chan[c].Send[i].FilterType = AF_None; - if(WetGainHF[i] != 1.0f) voice->Chan[c].Send[i].FilterType |= AF_LowPass; - if(WetGainLF[i] != 1.0f) voice->Chan[c].Send[i].FilterType |= AF_HighPass; + voice->Send[i].Params[c].FilterType = AF_None; + if(WetGainHF[i] != 1.0f) voice->Send[i].Params[c].FilterType |= AF_LowPass; + if(WetGainLF[i] != 1.0f) voice->Send[i].Params[c].FilterType |= AF_HighPass; ALfilterState_setParams( - &voice->Chan[c].Send[i].LowPass, ALfilterType_HighShelf, + &voice->Send[i].Params[c].LowPass, ALfilterType_HighShelf, WetGainHF[i], hfscale, calc_rcpQ_from_slope(WetGainHF[i], 0.75f) ); ALfilterState_setParams( - &voice->Chan[c].Send[i].HighPass, ALfilterType_LowShelf, + &voice->Send[i].Params[c].HighPass, ALfilterType_LowShelf, WetGainLF[i], lfscale, calc_rcpQ_from_slope(WetGainLF[i], 0.75f) ); } @@ -846,8 +850,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro WetGainHFAuto = ATOMIC_LOAD(&props->WetGainHFAuto, almemory_order_relaxed); RoomRolloffBase = ATOMIC_LOAD(&props->RoomRolloffFactor, almemory_order_relaxed); - voice->DirectOut.Buffer = Device->Dry.Buffer; - voice->DirectOut.Channels = Device->Dry.NumChannels; + voice->Direct.Buffer = Device->Dry.Buffer; + voice->Direct.Channels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); @@ -879,13 +883,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro if(!SendSlots[i]) { - voice->SendOut[i].Buffer = NULL; - voice->SendOut[i].Channels = 0; + voice->Send[i].Buffer = NULL; + voice->Send[i].Channels = 0; } else { - voice->SendOut[i].Buffer = SendSlots[i]->WetBuffer; - voice->SendOut[i].Channels = SendSlots[i]->NumChannels; + voice->Send[i].Buffer = SendSlots[i]->WetBuffer; + voice->Send[i].Channels = SendSlots[i]->NumChannels; } } @@ -1126,8 +1130,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro ALfloat coeffs[MAX_AMBI_COEFFS]; ALfloat spread = 0.0f; - voice->DirectOut.Buffer = Device->RealOut.Buffer; - voice->DirectOut.Channels = Device->RealOut.NumChannels; + voice->Direct.Buffer = Device->RealOut.Buffer; + voice->Direct.Channels = Device->RealOut.NumChannels; if(Distance > FLT_EPSILON) { @@ -1149,8 +1153,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro /* Get the HRIR coefficients and delays. */ GetHrtfCoeffs(Device->Hrtf.Handle, ev, az, spread, DryGain, - voice->Chan[0].Direct.Hrtf.Target.Coeffs, - voice->Chan[0].Direct.Hrtf.Target.Delay); + voice->Direct.Params[0].Hrtf.Target.Coeffs, + voice->Direct.Params[0].Hrtf.Target.Delay); CalcDirectionCoeffs(dir, spread, coeffs); @@ -1160,13 +1164,14 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro { ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Chan[0].Send[i].Gains.Target[j] = 0.0f; + voice->Send[i].Params[0].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Chan[0].Send[i].Gains.Target); + ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, + coeffs, WetGain[i], voice->Send[i].Params[0].Gains.Target + ); } } @@ -1197,10 +1202,10 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro /* Clamp X so it remains within 30 degrees of 0 or 180 degree azimuth. */ ALfloat x = -dir[0] * (0.5f * (cosf(spread*0.5f) + 1.0f)); x = clampf(x, -0.5f, 0.5f) + 0.5f; - voice->Chan[0].Direct.Gains.Target[0] = x * DryGain; - voice->Chan[0].Direct.Gains.Target[1] = (1.0f-x) * DryGain; + voice->Direct.Params[0].Gains.Target[0] = x * DryGain; + voice->Direct.Params[0].Gains.Target[1] = (1.0f-x) * DryGain; for(i = 2;i < MAX_OUTPUT_CHANNELS;i++) - voice->Chan[0].Direct.Gains.Target[i] = 0.0f; + voice->Direct.Params[0].Gains.Target[i] = 0.0f; CalcDirectionCoeffs(dir, spread, coeffs); } @@ -1208,7 +1213,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro { CalcDirectionCoeffs(dir, spread, coeffs); ComputePanningGains(Device->Dry, coeffs, DryGain, - voice->Chan[0].Direct.Gains.Target); + voice->Direct.Params[0].Gains.Target); } for(i = 0;i < NumSends;i++) @@ -1217,13 +1222,14 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro { ALuint j; for(j = 0;j < MAX_EFFECT_CHANNELS;j++) - voice->Chan[0].Send[i].Gains.Target[j] = 0.0f; + voice->Send[i].Params[0].Gains.Target[j] = 0.0f; } else { const ALeffectslot *Slot = SendSlots[i]; - ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, coeffs, - WetGain[i], voice->Chan[0].Send[i].Gains.Target); + ComputePanningGainsBF(Slot->ChanMap, Slot->NumChannels, + coeffs, WetGain[i], voice->Send[i].Params[0].Gains.Target + ); } } @@ -1237,15 +1243,15 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro Frequency; DryGainHF = maxf(DryGainHF, 0.0001f); DryGainLF = maxf(DryGainLF, 0.0001f); - voice->Chan[0].Direct.FilterType = AF_None; - if(DryGainHF != 1.0f) voice->Chan[0].Direct.FilterType |= AF_LowPass; - if(DryGainLF != 1.0f) voice->Chan[0].Direct.FilterType |= AF_HighPass; + voice->Direct.Params[0].FilterType = AF_None; + if(DryGainHF != 1.0f) voice->Direct.Params[0].FilterType |= AF_LowPass; + if(DryGainLF != 1.0f) voice->Direct.Params[0].FilterType |= AF_HighPass; ALfilterState_setParams( - &voice->Chan[0].Direct.LowPass, ALfilterType_HighShelf, + &voice->Direct.Params[0].LowPass, ALfilterType_HighShelf, DryGainHF, hfscale, calc_rcpQ_from_slope(DryGainHF, 0.75f) ); ALfilterState_setParams( - &voice->Chan[0].Direct.HighPass, ALfilterType_LowShelf, + &voice->Direct.Params[0].HighPass, ALfilterType_LowShelf, DryGainLF, lfscale, calc_rcpQ_from_slope(DryGainLF, 0.75f) ); } @@ -1257,15 +1263,15 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0001f); WetGainLF[i] = maxf(WetGainLF[i], 0.0001f); - voice->Chan[0].Send[i].FilterType = AF_None; - if(WetGainHF[i] != 1.0f) voice->Chan[0].Send[i].FilterType |= AF_LowPass; - if(WetGainLF[i] != 1.0f) voice->Chan[0].Send[i].FilterType |= AF_HighPass; + voice->Send[i].Params[0].FilterType = AF_None; + if(WetGainHF[i] != 1.0f) voice->Send[i].Params[0].FilterType |= AF_LowPass; + if(WetGainLF[i] != 1.0f) voice->Send[i].Params[0].FilterType |= AF_HighPass; ALfilterState_setParams( - &voice->Chan[0].Send[i].LowPass, ALfilterType_HighShelf, + &voice->Send[i].Params[0].LowPass, ALfilterType_HighShelf, WetGainHF[i], hfscale, calc_rcpQ_from_slope(WetGainHF[i], 0.75f) ); ALfilterState_setParams( - &voice->Chan[0].Send[i].HighPass, ALfilterType_LowShelf, + &voice->Send[i].Params[0].HighPass, ALfilterType_LowShelf, WetGainLF[i], lfscale, calc_rcpQ_from_slope(WetGainLF[i], 0.75f) ); } diff --git a/Alc/mixer.c b/Alc/mixer.c index 179c028e..d5cf30cc 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -569,7 +569,7 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp Device->ResampledData, DstBufferSize ); { - DirectParams *parms = &voice->Chan[chan].Direct; + DirectParams *parms = &voice->Direct.Params[chan]; const ALfloat *samples; samples = DoFilters( @@ -581,8 +581,9 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp if(!Counter) memcpy(parms->Gains.Current, parms->Gains.Target, sizeof(parms->Gains.Current)); - MixSamples(samples, voice->DirectOut.Channels, voice->DirectOut.Buffer, - parms->Gains.Current, parms->Gains.Target, Counter, OutPos, DstBufferSize + MixSamples(samples, voice->Direct.Channels, voice->Direct.Buffer, + parms->Gains.Current, parms->Gains.Target, Counter, OutPos, + DstBufferSize ); } else @@ -626,7 +627,7 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp assert(lidx != -1 && ridx != -1); MixHrtfSamples( - voice->DirectOut.Buffer[lidx], voice->DirectOut.Buffer[ridx], + voice->Direct.Buffer[lidx], voice->Direct.Buffer[ridx], samples, Counter, voice->Offset, OutPos, IrSize, &hrtfparams, &parms->Hrtf.State, DstBufferSize ); @@ -635,10 +636,10 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp for(send = 0;send < Device->NumAuxSends;send++) { - SendParams *parms = &voice->Chan[chan].Send[send]; + SendParams *parms = &voice->Send[send].Params[chan]; const ALfloat *samples; - if(!voice->SendOut[send].Buffer) + if(!voice->Send[send].Buffer) continue; samples = DoFilters( @@ -649,7 +650,7 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp if(!Counter) memcpy(parms->Gains.Current, parms->Gains.Target, sizeof(parms->Gains.Current)); - MixSamples(samples, voice->SendOut[send].Channels, voice->SendOut[send].Buffer, + MixSamples(samples, voice->Send[send].Channels, voice->Send[send].Buffer, parms->Gains.Current, parms->Gains.Target, Counter, OutPos, DstBufferSize ); } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index cc9dd763..c63aef70 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -95,19 +95,18 @@ typedef struct ALvoice { InterpState ResampleState; struct { + DirectParams Params[MAX_INPUT_CHANNELS]; + ALfloat (*Buffer)[BUFFERSIZE]; ALsizei Channels; - } DirectOut; + } Direct; struct { + SendParams Params[MAX_INPUT_CHANNELS]; + ALfloat (*Buffer)[BUFFERSIZE]; ALsizei Channels; - } SendOut[MAX_SENDS]; - - struct { - DirectParams Direct; - SendParams Send[MAX_SENDS]; - } Chan[MAX_INPUT_CHANNELS]; + } Send[MAX_SENDS]; } ALvoice; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 56d2b415..395bc8c2 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -3013,11 +3013,11 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { ALsizei j; for(j = 0;j < HRTF_HISTORY_LENGTH;j++) - voice->Chan[i].Direct.Hrtf.State.History[j] = 0.0f; + voice->Direct.Params[i].Hrtf.State.History[j] = 0.0f; for(j = 0;j < HRIR_LENGTH;j++) { - voice->Chan[i].Direct.Hrtf.State.Values[j][0] = 0.0f; - voice->Chan[i].Direct.Hrtf.State.Values[j][1] = 0.0f; + voice->Direct.Params[i].Hrtf.State.Values[j][0] = 0.0f; + voice->Direct.Params[i].Hrtf.State.Values[j][1] = 0.0f; } } -- cgit v1.2.3 From cd24e42b3f7887867735db2cd35a0c4137163379 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 Feb 2017 11:17:47 -0800 Subject: Make the voices' Send[] array dynamically sized The voices are still all allocated in one chunk to avoid memory fragmentation. But they're accessed as an array of pointers since the size isn't static. --- Alc/ALc.c | 40 ++++++++++++++++++++++++++++------------ Alc/ALu.c | 22 +++++++++++----------- OpenAL32/Include/alMain.h | 2 +- OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 16 ++++++++-------- 5 files changed, 49 insertions(+), 33 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index c831ca9d..5a382d6e 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2607,21 +2607,26 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) ALsizei num_sends = device->NumAuxSends; struct ALsourceProps *props; size_t sizeof_props; - ALvoice *voices; + size_t sizeof_voice; + ALvoice **voices; + ALvoice *voice; ALsizei v = 0; size_t size; if(num_voices == context->MaxVoices && num_sends == old_sends) return; - /* Allocate the voices, and the voices' stored source property set - * (including the dynamically-sized Send[] array) in one chunk. + /* Allocate the voice pointers, voices, and the voices' stored source + * property set (including the dynamically-sized Send[] array) in one + * chunk. */ sizeof_props = RoundUp(offsetof(struct ALsourceProps, Send[num_sends]), 16); - size = sizeof(*voices) + sizeof_props; + sizeof_voice = RoundUp(offsetof(ALvoice, Send[num_sends]), 16); + size = sizeof(ALvoice*) + sizeof_voice + sizeof_props; - voices = al_calloc(16, size * num_voices); - props = (struct ALsourceProps*)(voices + num_voices); + voices = al_calloc(16, RoundUp(size*num_voices, 16)); + voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16)); + props = (struct ALsourceProps*)((char*)voice + num_voices*sizeof_voice); if(context->Voices) { @@ -2634,23 +2639,34 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) /* Copy the old voice data and source property set to the new * storage. */ - voices[v] = context->Voices[v]; - *props = *(context->Voices[v].Props); + *voice = *(context->Voices[v]); for(i = 0;i < s_count;i++) - props->Send[i] = context->Voices[v].Props->Send[i]; + voice->Send[i] = context->Voices[v]->Send[i]; + *props = *(context->Voices[v]->Props); + for(i = 0;i < s_count;i++) + props->Send[i] = context->Voices[v]->Props->Send[i]; /* Set this voice's property set pointer and increment 'props' to * the next property storage space. */ - voices[v].Props = props; + voice->Props = props; props = (struct ALsourceProps*)((char*)props + sizeof_props); + + /* Set this voice's reference and increment 'voice' to the next + * voice storage space. + */ + voices[v] = voice; + voice = (ALvoice*)((char*)voice + sizeof_voice); } } - /* Finish setting the voices' property set pointers. */ + /* Finish setting the voices' property set pointers and references. */ for(;v < num_voices;v++) { - voices[v].Props = props; + voice->Props = props; props = (struct ALsourceProps*)((char*)props + sizeof_props); + + voices[v] = voice; + voice = (ALvoice*)((char*)voice + sizeof_voice); } al_free(context->Voices); diff --git a/Alc/ALu.c b/Alc/ALu.c index 1fca0ed0..edb23128 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1313,7 +1313,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) { - ALvoice *voice, *voice_end; + ALvoice **voice, **voice_end; ALsource *source; IncrementRef(&ctx->UpdateCount); @@ -1330,11 +1330,11 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) { - if(!(source=voice->Source)) continue; + if(!(source=(*voice)->Source)) continue; if(!IsPlayingOrPaused(source)) - voice->Source = NULL; + (*voice)->Source = NULL; else - CalcSourceParams(voice, ctx, force); + CalcSourceParams(*voice, ctx, force); } } IncrementRef(&ctx->UpdateCount); @@ -1424,7 +1424,7 @@ DECL_TEMPLATE(ALbyte, aluF2B) void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) { ALsizei SamplesToDo; - ALvoice *voice, *voice_end; + ALvoice **voice, **voice_end; ALeffectslot *slot; ALsource *source; ALCcontext *ctx; @@ -1475,11 +1475,11 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) { - ALboolean IsVoiceInit = (voice->Step > 0); - source = voice->Source; + ALboolean IsVoiceInit = ((*voice)->Step > 0); + source = (*voice)->Source; if(IsVoiceInit && source && ATOMIC_LOAD(&source->state, almemory_order_relaxed) == AL_PLAYING) - MixSource(voice, source, device, SamplesToDo); + MixSource(*voice, source, device, SamplesToDo); } /* effect slot processing */ @@ -1637,15 +1637,15 @@ void aluHandleDisconnect(ALCdevice *device) Context = ATOMIC_LOAD_SEQ(&device->ContextList); while(Context) { - ALvoice *voice, *voice_end; + ALvoice **voice, **voice_end; voice = Context->Voices; voice_end = voice + Context->VoiceCount; while(voice != voice_end) { ALenum playing = AL_PLAYING; - ALsource *source = voice->Source; - voice->Source = NULL; + ALsource *source = (*voice)->Source; + (*voice)->Source = NULL; if(source && ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED)) diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index bb8a57ce..76862f38 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -812,7 +812,7 @@ struct ALCcontext_struct { ALfloat GainBoost; - struct ALvoice *Voices; + struct ALvoice **Voices; ALsizei VoiceCount; ALsizei MaxVoices; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index c63aef70..53e9a2f4 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -106,7 +106,7 @@ typedef struct ALvoice { ALfloat (*Buffer)[BUFFERSIZE]; ALsizei Channels; - } Send[MAX_SENDS]; + } Send[]; } ALvoice; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 395bc8c2..c541884b 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -128,12 +128,12 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp static inline ALvoice *GetSourceVoice(const ALsource *source, const ALCcontext *context) { - ALvoice *voice = context->Voices; - ALvoice *voice_end = voice + context->VoiceCount; + ALvoice **voice = context->Voices; + ALvoice **voice_end = voice + context->VoiceCount; while(voice != voice_end) { - if(voice->Source == source) - return voice; + if((*voice)->Source == source) + return *voice; ++voice; } return NULL; @@ -2915,7 +2915,7 @@ void UpdateAllSourceProps(ALCcontext *context) for(pos = 0;pos < context->VoiceCount;pos++) { - ALvoice *voice = &context->Voices[pos]; + ALvoice *voice = context->Voices[pos]; ALsource *source = voice->Source; if(source != NULL && source->NeedsUpdate && IsPlayingOrPaused(source)) { @@ -2982,16 +2982,16 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { for(i = 0;i < Context->VoiceCount;i++) { - if(Context->Voices[i].Source == NULL) + if(Context->Voices[i]->Source == NULL) { - voice = &Context->Voices[i]; + voice = Context->Voices[i]; voice->Source = Source; break; } } if(voice == NULL) { - voice = &Context->Voices[Context->VoiceCount++]; + voice = Context->Voices[Context->VoiceCount++]; voice->Source = Source; } discontinuity = AL_TRUE; -- cgit v1.2.3 From 864d5387dda119d9faecfd62226b62f1a8af8532 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 Feb 2017 16:31:59 -0800 Subject: Dynamically allocate the ALsource Send[] array --- Alc/ALc.c | 102 +++++++++++++++++++++++++------------------- Alc/mixer.c | 2 +- OpenAL32/Include/alMain.h | 2 +- OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 55 ++++++++++++++---------- 5 files changed, 94 insertions(+), 69 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 3d49538f..e63323b4 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1766,15 +1766,17 @@ static inline void UpdateClockBase(ALCdevice *device) */ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { - ALCcontext *context; - enum HrtfRequestMode hrtf_appreq = Hrtf_Default; enum HrtfRequestMode hrtf_userreq = Hrtf_Default; - ALsizei old_sends = device->NumAuxSends; + enum HrtfRequestMode hrtf_appreq = Hrtf_Default; + const ALsizei old_sends = device->NumAuxSends; + ALsizei new_sends = device->NumAuxSends; enum DevFmtChannels oldChans; enum DevFmtType oldType; + ALboolean update_failed; + ALCsizei hrtf_id = -1; + ALCcontext *context; ALCuint oldFreq; FPUCtl oldMode; - ALCsizei hrtf_id = -1; size_t size; // Check for attributes @@ -1800,10 +1802,10 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) numMono = device->NumMonoSources; numStereo = device->NumStereoSources; - numSends = device->NumAuxSends; schans = device->FmtChans; stype = device->FmtType; freq = device->Frequency; + numSends = old_sends; #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v) while(attrList[attrIdx]) @@ -1880,9 +1882,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) return ALC_INVALID_VALUE; } - ConfigValueUInt(NULL, NULL, "sends", &numSends); - numSends = minu(MAX_SENDS, numSends); - if((device->Flags&DEVICE_RUNNING)) V0(device->Backend,stop)(); device->Flags &= ~DEVICE_RUNNING; @@ -1894,7 +1893,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->FmtType = stype; device->NumMonoSources = numMono; device->NumStereoSources = numStereo; - device->NumAuxSends = numSends; + + ConfigValueUInt(NULL, NULL, "sends", &numSends); + new_sends = clampi(numSends, 1, MAX_SENDS); } else if(attrList && attrList[0]) { @@ -1907,10 +1908,12 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) V0(device->Backend,stop)(); device->Flags &= ~DEVICE_RUNNING; + UpdateClockBase(device); + freq = device->Frequency; numMono = device->NumMonoSources; numStereo = device->NumStereoSources; - numSends = device->NumAuxSends; + numSends = old_sends; #define TRACE_ATTR(a, v) TRACE("%s = %d\n", #a, v) while(attrList[attrIdx]) @@ -1962,11 +1965,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "frequency", &freq); freq = maxu(freq, MIN_OUTPUT_RATE); - ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends); - numSends = minu(MAX_SENDS, numSends); - - UpdateClockBase(device); - device->UpdateSize = (ALuint64)device->UpdateSize * freq / device->Frequency; /* SSE and Neon do best with the update size being a multiple of 4 */ @@ -1976,7 +1974,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->Frequency = freq; device->NumMonoSources = numMono; device->NumStereoSources = numStereo; - device->NumAuxSends = numSends; + + ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends); + new_sends = clampi(numSends, 1, MAX_SENDS); } if((device->Flags&DEVICE_RUNNING)) @@ -2148,6 +2148,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->FOAOut.NumChannels = device->Dry.NumChannels; } + /* Need to delay returning failure until replacement Send arrays have been + * allocated with the appropriate size. + */ + device->NumAuxSends = new_sends; + update_failed = AL_FALSE; SetMixerFPUMode(&oldMode); if(device->DefaultSlot) { @@ -2157,11 +2162,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) state->OutBuffer = device->Dry.Buffer; state->OutChannels = device->Dry.NumChannels; if(V(state,deviceUpdate)(device) == AL_FALSE) - { - RestoreFPUMode(&oldMode); - return ALC_INVALID_DEVICE; - } - UpdateEffectSlotProps(slot); + update_failed = AL_TRUE; + else + UpdateEffectSlotProps(slot); } context = ATOMIC_LOAD_SEQ(&device->ContextList); @@ -2179,14 +2182,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) state->OutBuffer = device->Dry.Buffer; state->OutChannels = device->Dry.NumChannels; if(V(state,deviceUpdate)(device) == AL_FALSE) - { - UnlockUIntMapRead(&context->EffectSlotMap); - ReadUnlock(&context->PropLock); - RestoreFPUMode(&oldMode); - return ALC_INVALID_DEVICE; - } - - UpdateEffectSlotProps(slot); + update_failed = AL_TRUE; + else + UpdateEffectSlotProps(slot); } UnlockUIntMapRead(&context->EffectSlotMap); @@ -2195,25 +2193,39 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { ALsource *source = context->SourceMap.values[pos]; struct ALsourceProps *props; - ALsizei s; - for(s = device->NumAuxSends;s < MAX_SENDS;s++) + if(old_sends != device->NumAuxSends) { - if(source->Send[s].Slot) - DecrementRef(&source->Send[s].Slot->ref); - source->Send[s].Slot = NULL; - source->Send[s].Gain = 1.0f; - source->Send[s].GainHF = 1.0f; - source->Send[s].HFReference = LOWPASSFREQREF; - source->Send[s].GainLF = 1.0f; - source->Send[s].LFReference = HIGHPASSFREQREF; + ALvoid *sends = al_calloc(16, device->NumAuxSends*sizeof(source->Send[0])); + ALsizei s; + + memcpy(sends, source->Send, + mini(device->NumAuxSends, old_sends)*sizeof(source->Send[0]) + ); + for(s = device->NumAuxSends;s < old_sends;s++) + { + if(source->Send[s].Slot) + DecrementRef(&source->Send[s].Slot->ref); + source->Send[s].Slot = NULL; + } + al_free(source->Send); + source->Send = sends; + for(s = old_sends;s < device->NumAuxSends;s++) + { + source->Send[s].Slot = NULL; + source->Send[s].Gain = 1.0f; + source->Send[s].GainHF = 1.0f; + source->Send[s].HFReference = LOWPASSFREQREF; + source->Send[s].GainLF = 1.0f; + source->Send[s].LFReference = HIGHPASSFREQREF; + } } source->NeedsUpdate = AL_TRUE; /* Clear any pre-existing source property structs, in case the * number of auxiliary sends changed. Playing (or paused) sources - * will have updates specified. + * will have updates respecified in UpdateAllSourceProps. */ props = ATOMIC_EXCHANGE_SEQ(struct ALsourceProps*, &source->Update, NULL); al_free(props); @@ -2237,6 +2249,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) context = context->next; } RestoreFPUMode(&oldMode); + if(update_failed) + return ALC_INVALID_DEVICE; if(!(device->Flags&DEVICE_PAUSED)) { @@ -3720,8 +3734,8 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax); if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4; - ConfigValueUInt(deviceName, NULL, "sends", &device->NumAuxSends); - if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS; + ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends); + device->NumAuxSends = clampi(device->NumAuxSends, 0, MAX_SENDS); device->NumStereoSources = 1; device->NumMonoSources = device->SourcesMax - device->NumStereoSources; @@ -4126,8 +4140,8 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax); if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4; - ConfigValueUInt(NULL, NULL, "sends", &device->NumAuxSends); - if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS; + ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends); + device->NumAuxSends = clampi(device->NumAuxSends, 0, MAX_SENDS); device->NumStereoSources = 1; device->NumMonoSources = device->SourcesMax - device->NumStereoSources; diff --git a/Alc/mixer.c b/Alc/mixer.c index a48b0e29..46ca0892 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -381,7 +381,7 @@ void MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Samp ALsizei Counter; ALsizei IrSize; ALsizei chan, j; - ALuint send; + ALsizei send; /* Get source info */ State = AL_PLAYING; /* Only called while playing. */ diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 76862f38..0b467403 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -648,7 +648,7 @@ struct ALCdevice_struct ALCuint NumMonoSources; ALCuint NumStereoSources; - ALuint NumAuxSends; + ALsizei NumAuxSends; // Map of Buffers for this device UIntMap BufferMap; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 53e9a2f4..72b05fc8 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -161,7 +161,7 @@ typedef struct ALsource { ALfloat HFReference; ALfloat GainLF; ALfloat LFReference; - } Send[MAX_SENDS]; + } *Send; /** * Last user-specified offset, and the offset type (bytes, samples, or diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index c541884b..1b3f4c56 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -48,9 +48,9 @@ extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); extern inline ALboolean IsPlayingOrPaused(const ALsource *source); -static void InitSourceParams(ALsource *Source); -static void DeinitSource(ALsource *source); -static void UpdateSourceProps(ALsource *source, ALuint num_sends); +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 ALint64 GetSourceSampleOffset(ALsource *Source, ALCdevice *device, ALuint64 *clocktime); static ALdouble GetSourceSecOffset(ALsource *Source, ALCdevice *device, ALuint64 *clocktime); static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device); @@ -816,7 +816,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_AUXILIARY_SEND_FILTER: LockEffectSlotsRead(Context); LockFiltersRead(device); - if(!((ALuint)values[1] < device->NumAuxSends && + if(!((ALuint)values[1] < (ALuint)device->NumAuxSends && (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) && (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) { @@ -1539,6 +1539,7 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) { + ALCdevice *device; ALCcontext *context; ALsizei cur = 0; ALenum err; @@ -1548,6 +1549,7 @@ AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) if(!(n >= 0)) SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); + device = context->Device; for(cur = 0;cur < n;cur++) { ALsource *source = al_calloc(16, sizeof(ALsource)); @@ -1556,7 +1558,7 @@ AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) alDeleteSources(cur, sources); SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); } - InitSourceParams(source); + InitSourceParams(source, device->NumAuxSends); err = NewThunkEntry(&source->id); if(err == AL_NO_ERROR) @@ -1581,6 +1583,7 @@ done: AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) { + ALCdevice *device; ALCcontext *context; ALsource *Source; ALsizei i; @@ -1598,6 +1601,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) if(LookupSource(context, sources[i]) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); } + device = context->Device; for(i = 0;i < n;i++) { ALvoice *voice; @@ -1606,12 +1610,12 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) continue; FreeThunkEntry(Source->id); - ALCdevice_Lock(context->Device); + ALCdevice_Lock(device); voice = GetSourceVoice(Source, context); if(voice) voice->Source = NULL; - ALCdevice_Unlock(context->Device); + ALCdevice_Unlock(device); - DeinitSource(Source); + DeinitSource(Source, device->NumAuxSends); memset(Source, 0, sizeof(*Source)); al_free(Source); @@ -2692,9 +2696,9 @@ done: } -static void InitSourceParams(ALsource *Source) +static void InitSourceParams(ALsource *Source, ALsizei num_sends) { - ALuint i; + ALsizei i; RWLockInit(&Source->queue_lock); @@ -2745,7 +2749,8 @@ static void InitSourceParams(ALsource *Source) Source->Direct.HFReference = LOWPASSFREQREF; Source->Direct.GainLF = 1.0f; Source->Direct.LFReference = HIGHPASSFREQREF; - for(i = 0;i < MAX_SENDS;i++) + Source->Send = al_calloc(16, num_sends*sizeof(Source->Send[0])); + for(i = 0;i < num_sends;i++) { Source->Send[i].Slot = NULL; Source->Send[i].Gain = 1.0f; @@ -2775,12 +2780,12 @@ static void InitSourceParams(ALsource *Source) ATOMIC_INIT(&Source->FreeList, NULL); } -static void DeinitSource(ALsource *source) +static void DeinitSource(ALsource *source, ALsizei num_sends) { ALbufferlistitem *BufferList; struct ALsourceProps *props; size_t count = 0; - size_t i; + ALsizei i; props = ATOMIC_LOAD_SEQ(&source->Update); if(props) al_free(props); @@ -2810,18 +2815,23 @@ static void DeinitSource(ALsource *source) BufferList = next; } - for(i = 0;i < MAX_SENDS;i++) + if(source->Send) { - if(source->Send[i].Slot) - DecrementRef(&source->Send[i].Slot->ref); - source->Send[i].Slot = NULL; + for(i = 0;i < num_sends;i++) + { + if(source->Send[i].Slot) + DecrementRef(&source->Send[i].Slot->ref); + source->Send[i].Slot = NULL; + } + al_free(source->Send); + source->Send = NULL; } } -static void UpdateSourceProps(ALsource *source, ALuint num_sends) +static void UpdateSourceProps(ALsource *source, ALsizei num_sends) { struct ALsourceProps *props; - size_t i; + ALsizei i; /* Get an unused property container, or allocate a new one as needed. */ props = ATOMIC_LOAD(&source->FreeList, almemory_order_acquire); @@ -2856,7 +2866,7 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends) ATOMIC_STORE(&props->Direction[i], source->Direction[i], almemory_order_relaxed); for(i = 0;i < 2;i++) { - size_t j; + ALsizei j; for(j = 0;j < 3;j++) ATOMIC_STORE(&props->Orientation[i][j], source->Orientation[i][j], almemory_order_relaxed); @@ -2910,7 +2920,7 @@ static void UpdateSourceProps(ALsource *source, ALuint num_sends) void UpdateAllSourceProps(ALCcontext *context) { - ALuint num_sends = context->Device->NumAuxSends; + ALsizei num_sends = context->Device->NumAuxSends; ALsizei pos; for(pos = 0;pos < context->VoiceCount;pos++) @@ -3390,13 +3400,14 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac) */ ALvoid ReleaseALSources(ALCcontext *Context) { + ALCdevice *device = Context->Device; ALsizei pos; for(pos = 0;pos < Context->SourceMap.size;pos++) { ALsource *temp = Context->SourceMap.values[pos]; Context->SourceMap.values[pos] = NULL; - DeinitSource(temp); + DeinitSource(temp, device->NumAuxSends); FreeThunkEntry(temp->id); memset(temp, 0, sizeof(*temp)); -- cgit v1.2.3 From d3cc867bd42759cb8e294d691354187984f96ff4 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 21 Feb 2017 16:54:55 -0800 Subject: Increase the default effect slot and send count The default number of auxiliary effect slots is now 64. This can still be raised by the config file without a hard maximum, but incurs processing cost for each effect slot generated by the app. The default number of source sends is now actually 2, as per the EFX docs. However, it can be raised up to 16 via ALC_MAX_AUXILIARY_SENDS attribute requests, rather than the previous 4. --- Alc/ALc.c | 28 +++++++++++++++------------- OpenAL32/Include/alSource.h | 3 ++- alsoftrc.sample | 4 ++-- utils/alsoft-config/mainwindow.cpp | 4 ++-- utils/alsoft-config/mainwindow.ui | 6 +++--- 5 files changed, 24 insertions(+), 21 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index e63323b4..e33f397b 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1788,11 +1788,12 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) GotType = 1<<2, GotAll = GotFreq|GotChans|GotType }; - ALCuint freq, numMono, numStereo, numSends; + ALCuint freq, numMono, numStereo; enum DevFmtChannels schans; enum DevFmtType stype; ALCuint attrIdx = 0; ALCint gotFmt = 0; + ALCsizei numSends; if(!attrList) { @@ -1894,13 +1895,14 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->NumMonoSources = numMono; device->NumStereoSources = numStereo; - ConfigValueUInt(NULL, NULL, "sends", &numSends); - new_sends = clampi(numSends, 1, MAX_SENDS); + ConfigValueInt(NULL, NULL, "sends", &numSends); + new_sends = clampi(numSends, 0, MAX_SENDS); } else if(attrList && attrList[0]) { - ALCuint freq, numMono, numStereo, numSends; + ALCuint freq, numMono, numStereo; ALCuint attrIdx = 0; + ALCsizei numSends; /* If a context is already running on the device, stop playback so the * device attributes can be updated. */ @@ -1921,8 +1923,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(attrList[attrIdx] == ALC_FREQUENCY) { freq = attrList[attrIdx + 1]; - device->Flags |= DEVICE_FREQUENCY_REQUEST; TRACE_ATTR(ALC_FREQUENCY, freq); + device->Flags |= DEVICE_FREQUENCY_REQUEST; } if(attrList[attrIdx] == ALC_STEREO_SOURCES) @@ -1975,8 +1977,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->NumMonoSources = numMono; device->NumStereoSources = numStereo; - ConfigValueUInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends); - new_sends = clampi(numSends, 1, MAX_SENDS); + ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &numSends); + new_sends = clampi(numSends, 0, MAX_SENDS); } if((device->Flags&DEVICE_RUNNING)) @@ -3620,8 +3622,8 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) device->SamplesDone = 0; device->SourcesMax = 256; - device->AuxiliaryEffectSlotMax = 4; - device->NumAuxSends = MAX_SENDS; + device->AuxiliaryEffectSlotMax = 64; + device->NumAuxSends = DEFAULT_SENDS; InitUIntMap(&device->BufferMap, ~0); InitUIntMap(&device->EffectMap, ~0); @@ -3732,7 +3734,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) if(device->SourcesMax == 0) device->SourcesMax = 256; ConfigValueUInt(deviceName, NULL, "slots", &device->AuxiliaryEffectSlotMax); - if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4; + if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64; ConfigValueInt(deviceName, NULL, "sends", &device->NumAuxSends); device->NumAuxSends = clampi(device->NumAuxSends, 0, MAX_SENDS); @@ -4107,8 +4109,8 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN device->SamplesDone = 0; device->SourcesMax = 256; - device->AuxiliaryEffectSlotMax = 4; - device->NumAuxSends = MAX_SENDS; + device->AuxiliaryEffectSlotMax = 64; + device->NumAuxSends = DEFAULT_SENDS; InitUIntMap(&device->BufferMap, ~0); InitUIntMap(&device->EffectMap, ~0); @@ -4138,7 +4140,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN if(device->SourcesMax == 0) device->SourcesMax = 256; ConfigValueUInt(NULL, NULL, "slots", &device->AuxiliaryEffectSlotMax); - if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4; + if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 64; ConfigValueInt(NULL, NULL, "sends", &device->NumAuxSends); device->NumAuxSends = clampi(device->NumAuxSends, 0, MAX_SENDS); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 72b05fc8..8889ed24 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -1,7 +1,8 @@ #ifndef _AL_SOURCE_H_ #define _AL_SOURCE_H_ -#define MAX_SENDS 4 +#define MAX_SENDS 16 +#define DEFAULT_SENDS 2 #include "alMain.h" #include "alu.h" diff --git a/alsoftrc.sample b/alsoftrc.sample index 52e93ad1..d676c8aa 100644 --- a/alsoftrc.sample +++ b/alsoftrc.sample @@ -173,12 +173,12 @@ # can use a non-negligible amount of CPU time if an effect is set on it even # if no sources are feeding it, so this may help when apps use more than the # system can handle. -#slots = 4 +#slots = 64 ## sends: # Sets the number of auxiliary sends per source. When not specified (default), # it allows the app to request how many it wants. The maximum value currently -# possible is 4. +# possible is 16. #sends = ## volume-adjust: diff --git a/utils/alsoft-config/mainwindow.cpp b/utils/alsoft-config/mainwindow.cpp index e4dc10fc..200f6811 100644 --- a/utils/alsoft-config/mainwindow.cpp +++ b/utils/alsoft-config/mainwindow.cpp @@ -295,9 +295,9 @@ MainWindow::MainWindow(QWidget *parent) : mSourceCountValidator = new QIntValidator(0, 4096, this); ui->srcCountLineEdit->setValidator(mSourceCountValidator); - mEffectSlotValidator = new QIntValidator(0, 16, this); + mEffectSlotValidator = new QIntValidator(0, 64, this); ui->effectSlotLineEdit->setValidator(mEffectSlotValidator); - mSourceSendValidator = new QIntValidator(0, 4, this); + mSourceSendValidator = new QIntValidator(0, 16, this); ui->srcSendLineEdit->setValidator(mSourceSendValidator); mSampleRateValidator = new QIntValidator(8000, 192000, this); ui->sampleRateCombo->lineEdit()->setValidator(mSampleRateValidator); diff --git a/utils/alsoft-config/mainwindow.ui b/utils/alsoft-config/mainwindow.ui index afb91996..b886dc00 100644 --- a/utils/alsoft-config/mainwindow.ui +++ b/utils/alsoft-config/mainwindow.ui @@ -1649,13 +1649,13 @@ may help when apps use more than the system can handle. - 1 + 3 true - 4 + 64 @@ -1686,7 +1686,7 @@ may help when apps use more than the system can handle. The number of auxiliary sends per source. When not specified, it allows the app to request how many it wants. The maximum -value currently possible is 4. +value currently possible is 16. 1 -- cgit v1.2.3 From eceeabaf2ff3814c2a8dbb5b67f79e87cfaa97cd Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 24 Feb 2017 01:47:34 -0800 Subject: Improve handling of source state reads This avoids using seq_cst for loading the source state when either inside the mixer, or otherwise protected from inconsistencies with async updates. It also fixes potential race conditions with getting the source offset just as a source stops. --- OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 159 ++++++++++++++++++++++++-------------------- 2 files changed, 89 insertions(+), 72 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 8889ed24..6282939e 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -226,7 +226,7 @@ ALboolean ApplyOffset(ALsource *Source); inline ALboolean IsPlayingOrPaused(const ALsource *source) { - ALenum state = ATOMIC_LOAD_SEQ(&source->state); + ALenum state = ATOMIC_LOAD(&source->state, almemory_order_relaxed); return state == AL_PLAYING || state == AL_PAUSED; } diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 1b3f4c56..bb70a056 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -139,9 +139,15 @@ static inline ALvoice *GetSourceVoice(const ALsource *source, const ALCcontext * return NULL; } +static inline bool IsPlayingOrPausedSeq(const ALsource *source) +{ + ALenum state = ATOMIC_LOAD_SEQ(&source->state); + return state == AL_PLAYING || state == AL_PAUSED; +} + static inline bool SourceShouldUpdate(const ALsource *source, const ALCcontext *context) { - return IsPlayingOrPaused(source) && + return IsPlayingOrPausedSeq(source) && !ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire); } @@ -525,18 +531,24 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p Source->OffsetType = prop; Source->Offset = *values; - if(IsPlayingOrPaused(Source) && + if(IsPlayingOrPausedSeq(Source) && !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) { ALCdevice_Lock(Context->Device); - WriteLock(&Source->queue_lock); - if(ApplyOffset(Source) == AL_FALSE) + /* Double-check that the source is still playing while we have + * the lock. + */ + if(IsPlayingOrPaused(Source)) { + WriteLock(&Source->queue_lock); + if(ApplyOffset(Source) == AL_FALSE) + { + WriteUnlock(&Source->queue_lock); + ALCdevice_Unlock(Context->Device); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + } WriteUnlock(&Source->queue_lock); - ALCdevice_Unlock(Context->Device); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } - WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); } return AL_TRUE; @@ -672,7 +684,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } WriteLock(&Source->queue_lock); - if(IsPlayingOrPaused(Source)) + if(IsPlayingOrPausedSeq(Source)) { WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); @@ -726,18 +738,21 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->OffsetType = prop; Source->Offset = *values; - if(IsPlayingOrPaused(Source) && + if(IsPlayingOrPausedSeq(Source) && !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) { ALCdevice_Lock(Context->Device); - WriteLock(&Source->queue_lock); - if(ApplyOffset(Source) == AL_FALSE) + if(IsPlayingOrPaused(Source)) { + WriteLock(&Source->queue_lock); + if(ApplyOffset(Source) == AL_FALSE) + { + WriteUnlock(&Source->queue_lock); + ALCdevice_Unlock(Context->Device); + SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); + } WriteUnlock(&Source->queue_lock); - ALCdevice_Unlock(Context->Device); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); } - WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); } return AL_TRUE; @@ -844,7 +859,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } UnlockFiltersRead(device); - if(slot != Source->Send[values[1]].Slot && IsPlayingOrPaused(Source)) + if(slot != Source->Send[values[1]].Slot && IsPlayingOrPausedSeq(Source)) { /* Add refcount on the new slot, and release the previous slot */ if(slot) IncrementRef(&slot->ref); @@ -2927,7 +2942,7 @@ void UpdateAllSourceProps(ALCcontext *context) { ALvoice *voice = context->Voices[pos]; ALsource *source = voice->Source; - if(source != NULL && source->NeedsUpdate && IsPlayingOrPaused(source)) + if(source != NULL && source->NeedsUpdate && IsPlayingOrPausedSeq(source)) { source->NeedsUpdate = AL_FALSE; UpdateSourceProps(source, num_sends); @@ -3080,31 +3095,25 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCdevice *device, ALuint ALuint refcount; ReadLock(&Source->queue_lock); - if(!IsPlayingOrPaused(Source)) - { - ReadUnlock(&Source->queue_lock); - do { - while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) - althrd_yield(); - *clocktime = GetDeviceClockTime(device); - ATOMIC_THREAD_FENCE(almemory_order_acquire); - } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); - return 0; - } - do { + BufferList = Current = NULL; + readPos = 0; while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) althrd_yield(); *clocktime = GetDeviceClockTime(device); - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); - Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); + if(IsPlayingOrPaused(Source)) + { + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); + Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); - readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed) << 32; - readPos |= (ALuint64)ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed) << - (32-FRACTIONBITS); + readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed) << 32; + readPos |= ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed) << + (32-FRACTIONBITS); + } ATOMIC_THREAD_FENCE(almemory_order_acquire); } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); + while(BufferList && BufferList != Current) { if(BufferList->buffer) @@ -3125,55 +3134,59 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCdevice *device, ALuint64 { const ALbufferlistitem *BufferList; const ALbufferlistitem *Current; - const ALbuffer *Buffer = NULL; ALuint64 readPos; ALuint refcount; + ALdouble offset; ReadLock(&Source->queue_lock); - if(!IsPlayingOrPaused(Source)) - { - ReadUnlock(&Source->queue_lock); - do { - while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) - althrd_yield(); - *clocktime = GetDeviceClockTime(device); - ATOMIC_THREAD_FENCE(almemory_order_acquire); - } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); - return 0.0; - } - do { + BufferList = Current = NULL; + readPos = 0; while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) althrd_yield(); *clocktime = GetDeviceClockTime(device); - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); - Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); + if(IsPlayingOrPaused(Source)) + { + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); + Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); - readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed)<position_fraction, almemory_order_relaxed); + readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed) << + FRACTIONBITS; + readPos |= ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + } ATOMIC_THREAD_FENCE(almemory_order_acquire); } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); - while(BufferList && BufferList != Current) + + if(!Current) + offset = 0.0; + else { - const ALbuffer *buffer = BufferList->buffer; - if(buffer != NULL) + const ALbuffer *Buffer = NULL; + while(BufferList && BufferList != Current) { - if(!Buffer) Buffer = buffer; - readPos += (ALuint64)buffer->SampleLen << FRACTIONBITS; + const ALbuffer *buffer = BufferList->buffer; + if(buffer != NULL) + { + if(!Buffer) Buffer = buffer; + readPos += (ALuint64)buffer->SampleLen << FRACTIONBITS; + } + BufferList = BufferList->next; } - BufferList = BufferList->next; - } - while(BufferList && !Buffer) - { - Buffer = BufferList->buffer; - BufferList = BufferList->next; + while(BufferList && !Buffer) + { + Buffer = BufferList->buffer; + BufferList = BufferList->next; + } + assert(Buffer != NULL); + + offset = (ALdouble)readPos / (ALdouble)FRACTIONONE / + (ALdouble)Buffer->Frequency; } - assert(Buffer != NULL); ReadUnlock(&Source->queue_lock); - return (ALdouble)readPos / (ALdouble)FRACTIONONE / (ALdouble)Buffer->Frequency; + return offset; } /* GetSourceOffset @@ -3190,21 +3203,17 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device ALboolean readFin = AL_FALSE; ALuint readPos, readPosFrac; ALuint totalBufferLen; - ALdouble offset = 0.0; ALboolean looping; ALuint refcount; + ALdouble offset; + ALenum state; ReadLock(&Source->queue_lock); - if(!IsPlayingOrPaused(Source)) - { - ReadUnlock(&Source->queue_lock); - return 0.0; - } - - totalBufferLen = 0; do { while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) althrd_yield(); + state = ATOMIC_LOAD(&Source->state, almemory_order_relaxed); + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); @@ -3215,6 +3224,13 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device ATOMIC_THREAD_FENCE(almemory_order_acquire); } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); + if(state != AL_PLAYING && state != AL_PAUSED) + { + ReadUnlock(&Source->queue_lock); + return 0.0; + } + + totalBufferLen = 0; while(BufferList != NULL) { const ALbuffer *buffer; @@ -3238,6 +3254,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device readPos = readPosFrac = 0; } + offset = 0.0; switch(name) { case AL_SEC_OFFSET: -- cgit v1.2.3 From 5c859af24ea44dabbbb31631309bb08a858a523e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 27 Feb 2017 15:35:15 -0800 Subject: Move the current buffer queue entry and play position to the voice This has a couple behavioral changes. First and biggest is that querying AL_BUFFERS_PROCESSED from a source will always return all buffers processed when in an AL_STOPPED state. Previously all buffers would be set as processed when first becoming stopped, but newly queued buffers would *not* be indicated as processed. That old behavior was not compliant with the spec, which unequivocally states "On a source in the AL_STOPPED state, all buffers are processed." Secondly, querying AL_BUFFER on an AL_STREAMING source will now always return 0. Previously it would return the current "active" buffer in the queue, but there's no basis for that in the spec. --- Alc/ALc.c | 26 +++--- Alc/ALu.c | 9 +-- Alc/mixer.c | 14 ++-- OpenAL32/Include/alSource.h | 24 +++--- OpenAL32/alSource.c | 191 +++++++++++++++++++++++--------------------- 5 files changed, 137 insertions(+), 127 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index c829d8e7..bf683ba3 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1692,22 +1692,24 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) LockUIntMapRead(&context->SourceMap); V0(device->Backend,lock)(); - for(pos = 0;pos < context->SourceMap.size;pos++) + for(pos = 0;pos < context->VoiceCount;pos++) { - ALsource *Source = context->SourceMap.values[pos]; - ALenum new_state; - - if(Source->OffsetType != AL_NONE && IsPlayingOrPaused(Source)) + ALvoice *voice = context->Voices[pos]; + ALsource *source = voice->Source; + if(source && source->OffsetType != AL_NONE) { - WriteLock(&Source->queue_lock); - ApplyOffset(Source); - WriteUnlock(&Source->queue_lock); + WriteLock(&source->queue_lock); + ApplyOffset(source, voice); + WriteUnlock(&source->queue_lock); } - - new_state = Source->new_state; - Source->new_state = AL_NONE; + } + for(pos = 0;pos < context->SourceMap.size;pos++) + { + ALsource *source = context->SourceMap.values[pos]; + ALenum new_state = source->new_state; + source->new_state = AL_NONE; if(new_state) - SetSourceState(Source, context, new_state); + SetSourceState(source, context, new_state); } V0(device->Backend,unlock)(); UnlockUIntMapRead(&context->SourceMap); diff --git a/Alc/ALu.c b/Alc/ALu.c index 3b83711f..b4938152 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1594,16 +1594,13 @@ void aluHandleDisconnect(ALCdevice *device) voice_end = voice + Context->VoiceCount; while(voice != voice_end) { - ALenum playing = AL_PLAYING; ALsource *source = (*voice)->Source; (*voice)->Source = NULL; - if(source && - ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED)) + if(source) { - ATOMIC_STORE(&source->current_buffer, NULL, almemory_order_relaxed); - ATOMIC_STORE(&source->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&source->position_fraction, 0, almemory_order_release); + ALenum playing = AL_PLAYING; + ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALenum, &source->state, &playing, AL_STOPPED); } voice++; diff --git a/Alc/mixer.c b/Alc/mixer.c index be09ed67..b332030e 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -385,9 +385,9 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei /* Get source info */ State = AL_PLAYING; /* Only called while playing. */ - BufferListItem = ATOMIC_LOAD(&Source->current_buffer, almemory_order_acquire); - DataPosInt = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); - DataPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + DataPosInt = ATOMIC_LOAD(&voice->position, almemory_order_acquire); + DataPosFrac = ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed); + BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); Looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); NumChannels = Source->NumChannels; SampleSize = Source->SampleSize; @@ -681,9 +681,9 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei voice->Moving = AL_TRUE; /* Update source info */ - ATOMIC_STORE(&Source->state, State, almemory_order_relaxed); - ATOMIC_STORE(&Source->current_buffer, BufferListItem, almemory_order_relaxed); - ATOMIC_STORE(&Source->position, DataPosInt, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, DataPosFrac, almemory_order_release); + ATOMIC_STORE(&Source->state, State, almemory_order_relaxed); + ATOMIC_STORE(&voice->position, DataPosInt, almemory_order_relaxed); + ATOMIC_STORE(&voice->position_fraction, DataPosFrac, almemory_order_relaxed); + ATOMIC_STORE(&voice->current_buffer, BufferListItem, almemory_order_release); return State == AL_PLAYING; } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 6282939e..f8a32f71 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -81,6 +81,17 @@ typedef struct ALvoice { struct ALsource *Source; + /* Current buffer queue item being played. */ + ATOMIC(ALbufferlistitem*) current_buffer; + + /** + * Source offset in samples, relative to the currently playing buffer, NOT + * the whole queue, and the fractional (fixed-point) offset to the next + * sample. + */ + ATOMIC(ALuint) position; + ATOMIC(ALuint) position_fraction; + /** Current target parameters used for mixing. */ ALint Step; @@ -178,18 +189,9 @@ typedef struct ALsource { ATOMIC(ALenum) state; ALenum new_state; - /** Source Buffer Queue info. */ + /** Source Buffer Queue head. */ RWLock queue_lock; ATOMIC(ALbufferlistitem*) queue; - ATOMIC(ALbufferlistitem*) current_buffer; - - /** - * Source offset in samples, relative to the currently playing buffer, NOT - * the whole queue, and the fractional (fixed-point) offset to the next - * sample. - */ - ATOMIC(ALuint) position; - ATOMIC(ALuint) position_fraction; ATOMIC(ALboolean) looping; @@ -222,7 +224,7 @@ inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) void UpdateAllSourceProps(ALCcontext *context); ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); -ALboolean ApplyOffset(ALsource *Source); +ALboolean ApplyOffset(ALsource *Source, ALvoice *voice); inline ALboolean IsPlayingOrPaused(const ALsource *source) { diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 1fc2c5bd..b8345e04 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -51,9 +51,9 @@ extern inline ALboolean IsPlayingOrPaused(const ALsource *source); 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 ALint64 GetSourceSampleOffset(ALsource *Source, ALCdevice *device, ALuint64 *clocktime); -static ALdouble GetSourceSecOffset(ALsource *Source, ALCdevice *device, ALuint64 *clocktime); -static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device); +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); static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac); typedef enum SourceProp { @@ -531,17 +531,20 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p Source->OffsetType = prop; Source->Offset = *values; - if(IsPlayingOrPausedSeq(Source) && - !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) + if(!ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire) && + IsPlayingOrPausedSeq(Source)) { + ALvoice *voice; + ALCdevice_Lock(Context->Device); /* Double-check that the source is still playing while we have * the lock. */ - if(IsPlayingOrPaused(Source)) + voice = GetSourceVoice(Source, Context); + if(voice) { WriteLock(&Source->queue_lock); - if(ApplyOffset(Source) == AL_FALSE) + if(ApplyOffset(Source, voice) == AL_FALSE) { WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); @@ -714,7 +717,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p newlist = NULL; } oldlist = ATOMIC_EXCHANGE_SEQ(ALbufferlistitem*, &Source->queue, newlist); - ATOMIC_STORE_SEQ(&Source->current_buffer, newlist); WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); @@ -738,14 +740,17 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->OffsetType = prop; Source->Offset = *values; - if(IsPlayingOrPausedSeq(Source) && - !ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire)) + if(!ATOMIC_LOAD(&Context->DeferUpdates, almemory_order_acquire) && + IsPlayingOrPausedSeq(Source)) { + ALvoice *voice; + ALCdevice_Lock(Context->Device); - if(IsPlayingOrPaused(Source)) + voice = GetSourceVoice(Source, Context); + if(voice) { WriteLock(&Source->queue_lock); - if(ApplyOffset(Source) == AL_FALSE) + if(ApplyOffset(Source, voice) == AL_FALSE) { WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); @@ -1091,7 +1096,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SEC_OFFSET: case AL_SAMPLE_OFFSET: case AL_BYTE_OFFSET: - *values = GetSourceOffset(Source, prop, device); + *values = GetSourceOffset(Source, prop, Context); return AL_TRUE; case AL_CONE_OUTER_GAINHF: @@ -1144,7 +1149,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p /* Get the source offset with the clock time first. Then get the * clock time with the device latency. Order is important. */ - values[0] = GetSourceSecOffset(Source, device, &srcclock); + values[0] = GetSourceSecOffset(Source, Context, &srcclock); clocktime = V0(device->Backend,getClockLatency)(); if(srcclock == (ALuint64)clocktime.ClockTime) values[1] = (ALdouble)clocktime.Latency / 1000000000.0; @@ -1235,8 +1240,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFER: ReadLock(&Source->queue_lock); BufferList = (Source->SourceType == AL_STATIC) ? - ATOMIC_LOAD_SEQ(&Source->queue) : - ATOMIC_LOAD_SEQ(&Source->current_buffer); + ATOMIC_LOAD_SEQ(&Source->queue) : NULL; *values = (BufferList && BufferList->buffer) ? BufferList->buffer->id : 0; ReadUnlock(&Source->queue_lock); return AL_TRUE; @@ -1326,8 +1330,15 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p else { const ALbufferlistitem *BufferList = ATOMIC_LOAD_SEQ(&Source->queue); - const ALbufferlistitem *Current = ATOMIC_LOAD_SEQ(&Source->current_buffer); + const ALbufferlistitem *Current = NULL; ALsizei played = 0; + ALvoice *voice; + + if((voice=GetSourceVoice(Source, Context)) != NULL) + Current = ATOMIC_LOAD_SEQ(&voice->current_buffer); + else if(ATOMIC_LOAD_SEQ(&Source->state) == AL_INITIAL) + Current = BufferList; + while(BufferList && BufferList != Current) { played++; @@ -1442,7 +1453,7 @@ static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp /* Get the source offset with the clock time first. Then get the * clock time with the device latency. Order is important. */ - values[0] = GetSourceSampleOffset(Source, device, &srcclock); + values[0] = GetSourceSampleOffset(Source, Context, &srcclock); clocktime = V0(device->Backend,getClockLatency)(); if(srcclock == (ALuint64)clocktime.ClockTime) values[1] = clocktime.Latency; @@ -2606,12 +2617,6 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferList = BufferList->next; BufferList->next = BufferListStart; } - /* If the current buffer was at the end (NULL), put it at the start of the newly queued - * buffers. - */ - BufferList = NULL; - ATOMIC_COMPARE_EXCHANGE_STRONG_SEQ(ALbufferlistitem*, &source->current_buffer, - &BufferList, BufferListStart); WriteUnlock(&source->queue_lock); done: @@ -2626,11 +2631,9 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint ALbufferlistitem *OldHead; ALbufferlistitem *OldTail; ALbufferlistitem *Current; + ALvoice *voice; ALsizei i = 0; - if(nb == 0) - return; - context = GetContextRef(); if(!context) return; @@ -2641,6 +2644,9 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint if((source=LookupSource(context, src)) == NULL) SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); + /* Nothing to unqueue. */ + if(nb == 0) goto done; + WriteLock(&source->queue_lock); if(ATOMIC_LOAD_SEQ(&source->looping) || source->SourceType != AL_STREAMING) { @@ -2651,7 +2657,11 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint /* Find the new buffer queue head */ OldTail = ATOMIC_LOAD_SEQ(&source->queue); - Current = ATOMIC_LOAD_SEQ(&source->current_buffer); + Current = NULL; + if((voice=GetSourceVoice(source, context)) != NULL) + Current = ATOMIC_LOAD_SEQ(&voice->current_buffer); + else if(ATOMIC_LOAD_SEQ(&source->state) == AL_INITIAL) + Current = OldTail; if(OldTail != Current) { for(i = 1;i < nb;i++) @@ -2782,10 +2792,6 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) Source->new_state = AL_NONE; ATOMIC_INIT(&Source->queue, NULL); - ATOMIC_INIT(&Source->current_buffer, NULL); - - ATOMIC_INIT(&Source->position, 0); - ATOMIC_INIT(&Source->position_fraction, 0); ATOMIC_INIT(&Source->looping, AL_FALSE); @@ -2987,29 +2993,22 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) switch(ATOMIC_EXCHANGE(ALenum, &Source->state, AL_PLAYING, almemory_order_acq_rel)) { case AL_PLAYING: + assert(voice != NULL); /* A source that's already playing is restarted. */ - ATOMIC_STORE(&Source->current_buffer, BufferList, almemory_order_relaxed); - ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, 0, almemory_order_release); + ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); + ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed); + ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_release); /* fall-through */ case AL_PAUSED: + assert(voice != NULL); /* A source that's paused simply resumes. Make sure it uses the * volume last specified; there's no reason to fade from where * it stopped at. */ - assert(voice != NULL); voice->Moving = AL_FALSE; goto done; default: - /* A source that's not playing or paused has its offset - * applied, and then starts playing. - */ - ATOMIC_STORE(&Source->current_buffer, BufferList, almemory_order_relaxed); - ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, 0, almemory_order_release); - if(Source->OffsetType != AL_NONE) - ApplyOffset(Source); break; } @@ -3032,6 +3031,15 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) voice->Source = Source; } + /* A source that's not playing or paused has any offset applied when it + * starts playing. + */ + ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); + ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed); + ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_release); + if(Source->OffsetType != AL_NONE) + ApplyOffset(Source, voice); + /* Clear previous samples. */ memset(voice->PrevSamples, 0, sizeof(voice->PrevSamples)); @@ -3067,10 +3075,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) voice = GetSourceVoice(Source, Context); if(voice) voice->Source = NULL; if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) != AL_INITIAL) - { ATOMIC_STORE(&Source->state, AL_STOPPED, almemory_order_relaxed); - ATOMIC_STORE_SEQ(&Source->current_buffer, NULL); - } Source->OffsetType = AL_NONE; Source->Offset = 0.0; } @@ -3079,13 +3084,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) voice = GetSourceVoice(Source, Context); if(voice) voice->Source = NULL; if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) != AL_INITIAL) - { ATOMIC_STORE(&Source->state, AL_INITIAL, almemory_order_relaxed); - ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD_SEQ(&Source->queue), - almemory_order_relaxed); - ATOMIC_STORE(&Source->position, 0, almemory_order_relaxed); - ATOMIC_STORE_SEQ(&Source->position_fraction, 0); - } Source->OffsetType = AL_NONE; Source->Offset = 0.0; } @@ -3099,42 +3098,49 @@ done: * samples. The offset is relative to the start of the queue (not the start of * the current buffer). */ -static ALint64 GetSourceSampleOffset(ALsource *Source, ALCdevice *device, ALuint64 *clocktime) +static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime) { + ALCdevice *device = context->Device; const ALbufferlistitem *BufferList; const ALbufferlistitem *Current; ALuint64 readPos; ALuint refcount; + ALvoice *voice; ReadLock(&Source->queue_lock); + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); do { - BufferList = Current = NULL; + Current = NULL; readPos = 0; while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) althrd_yield(); *clocktime = GetDeviceClockTime(device); - if(IsPlayingOrPaused(Source)) + voice = GetSourceVoice(Source, context); + if(voice) { - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); - Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); + Current = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); - readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed) << 32; - readPos |= ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed) << + readPos = (ALuint64)ATOMIC_LOAD(&voice->position, almemory_order_relaxed) << 32; + readPos |= ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed) << (32-FRACTIONBITS); } ATOMIC_THREAD_FENCE(almemory_order_acquire); } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); - while(BufferList && BufferList != Current) + if(voice) { - if(BufferList->buffer) - readPos += (ALuint64)BufferList->buffer->SampleLen << 32; - BufferList = BufferList->next; + while(BufferList && BufferList != Current) + { + if(BufferList->buffer) + readPos += (ALuint64)BufferList->buffer->SampleLen << 32; + BufferList = BufferList->next; + } + readPos = minu64(readPos, U64(0x7fffffffffffffff)); } ReadUnlock(&Source->queue_lock); - return (ALint64)minu64(readPos, U64(0x7fffffffffffffff)); + return (ALint64)readPos; } /* GetSourceSecOffset @@ -3142,37 +3148,39 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCdevice *device, ALuint * Gets the current read offset for the given Source, in seconds. The offset is * relative to the start of the queue (not the start of the current buffer). */ -static ALdouble GetSourceSecOffset(ALsource *Source, ALCdevice *device, ALuint64 *clocktime) +static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime) { + ALCdevice *device = context->Device; const ALbufferlistitem *BufferList; const ALbufferlistitem *Current; ALuint64 readPos; ALuint refcount; ALdouble offset; + ALvoice *voice; ReadLock(&Source->queue_lock); + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); do { - BufferList = Current = NULL; + Current = NULL; readPos = 0; while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) althrd_yield(); *clocktime = GetDeviceClockTime(device); - if(IsPlayingOrPaused(Source)) + voice = GetSourceVoice(Source, context); + if(voice) { - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); - Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); + Current = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); - readPos = (ALuint64)ATOMIC_LOAD(&Source->position, almemory_order_relaxed) << + readPos = (ALuint64)ATOMIC_LOAD(&voice->position, almemory_order_relaxed) << FRACTIONBITS; - readPos |= ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + readPos |= ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed); } ATOMIC_THREAD_FENCE(almemory_order_acquire); } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); - if(!Current) - offset = 0.0; - else + offset = 0.0; + if(voice) { const ALbuffer *Buffer = NULL; while(BufferList && BufferList != Current) @@ -3207,8 +3215,9 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCdevice *device, ALuint64 * (Bytes, Samples or Seconds). The offset is relative to the start of the * queue (not the start of the current buffer). */ -static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device) +static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context) { + ALCdevice *device = context->Device; const ALbufferlistitem *BufferList; const ALbufferlistitem *Current; const ALbuffer *Buffer = NULL; @@ -3218,25 +3227,26 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device ALboolean looping; ALuint refcount; ALdouble offset; - ALenum state; + ALvoice *voice; ReadLock(&Source->queue_lock); + BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); + looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); do { while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) althrd_yield(); - state = ATOMIC_LOAD(&Source->state, almemory_order_relaxed); - - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); - Current = ATOMIC_LOAD(&Source->current_buffer, almemory_order_relaxed); - - readPos = ATOMIC_LOAD(&Source->position, almemory_order_relaxed); - readPosFrac = ATOMIC_LOAD(&Source->position_fraction, almemory_order_relaxed); + voice = GetSourceVoice(Source, context); + if(voice) + { + Current = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); - looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); + readPos = ATOMIC_LOAD(&voice->position, almemory_order_relaxed); + readPosFrac = ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed); + } ATOMIC_THREAD_FENCE(almemory_order_acquire); } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); - if(state != AL_PLAYING && state != AL_PAUSED) + if(!voice) { ReadUnlock(&Source->queue_lock); return 0.0; @@ -3314,7 +3324,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCdevice *device * Apply the stored playback offset to the Source. This function will update * the number of buffers "played" given the stored offset. */ -ALboolean ApplyOffset(ALsource *Source) +ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) { ALbufferlistitem *BufferList; const ALbuffer *Buffer; @@ -3335,10 +3345,9 @@ ALboolean ApplyOffset(ALsource *Source) if(bufferLen > offset-totalBufferLen) { /* Offset is in this buffer */ - ATOMIC_STORE(&Source->current_buffer, BufferList, almemory_order_relaxed); - - ATOMIC_STORE(&Source->position, offset - totalBufferLen, almemory_order_relaxed); - ATOMIC_STORE(&Source->position_fraction, frac, almemory_order_release); + ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); + ATOMIC_STORE(&voice->position, offset - totalBufferLen, almemory_order_relaxed); + ATOMIC_STORE(&voice->position_fraction, frac, almemory_order_release); return AL_TRUE; } -- cgit v1.2.3 From 6d7a790183552aa783d6043c755a10693d2f9369 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 2 Mar 2017 00:49:03 -0800 Subject: Add a boolean to specify if a voice should be playing --- Alc/ALu.c | 19 ++++++++-------- OpenAL32/Include/alSource.h | 8 ++++--- OpenAL32/alSource.c | 54 ++++++++++++++++++++++++++++++++------------- 3 files changed, 53 insertions(+), 28 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 9fe5712d..0a1b919a 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1224,9 +1224,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } } -static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force) +static void CalcSourceParams(ALvoice *voice, ALsource *source, ALCcontext *context, ALboolean force) { - ALsource *source = voice->Source; const ALbufferlistitem *BufferListItem; struct ALsourceProps *props; @@ -1278,11 +1277,8 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) { - if(!(source=(*voice)->Source)) continue; - if(!IsPlayingOrPaused(source)) - (*voice)->Source = NULL; - else - CalcSourceParams(*voice, ctx, force); + if((source=(*voice)->Source) != NULL) + CalcSourceParams(*voice, source, ctx, force); } } IncrementRef(&ctx->UpdateCount); @@ -1423,13 +1419,15 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) { - ALboolean IsVoiceInit = ((*voice)->Step > 0); source = (*voice)->Source; - if(IsVoiceInit && source && - ATOMIC_LOAD(&source->state, almemory_order_relaxed) == AL_PLAYING) + if(source && ATOMIC_LOAD(&(*voice)->Playing, almemory_order_relaxed) && + (*voice)->Step > 0) { if(!MixSource(*voice, source, device, SamplesToDo)) + { (*voice)->Source = NULL; + ATOMIC_STORE(&(*voice)->Playing, false, almemory_order_release); + } } } @@ -1596,6 +1594,7 @@ void aluHandleDisconnect(ALCdevice *device) { ALsource *source = (*voice)->Source; (*voice)->Source = NULL; + ATOMIC_STORE(&(*voice)->Playing, false, almemory_order_release); if(source) { diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index f8a32f71..fc1756e5 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -1,13 +1,14 @@ #ifndef _AL_SOURCE_H_ #define _AL_SOURCE_H_ -#define MAX_SENDS 16 -#define DEFAULT_SENDS 2 - +#include "bool.h" #include "alMain.h" #include "alu.h" #include "hrtf.h" +#define MAX_SENDS 16 +#define DEFAULT_SENDS 2 + #ifdef __cplusplus extern "C" { #endif @@ -80,6 +81,7 @@ typedef struct ALvoice { struct ALsourceProps *Props; struct ALsource *Source; + ATOMIC(bool) Playing; /* Current buffer queue item being played. */ ATOMIC(ALbufferlistitem*) current_buffer; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 40aa855c..14329bc2 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -1637,8 +1637,11 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) FreeThunkEntry(Source->id); ALCdevice_Lock(device); - voice = GetSourceVoice(Source, context); - if(voice) voice->Source = NULL; + if((voice=GetSourceVoice(Source, context)) != NULL) + { + voice->Source = NULL; + ATOMIC_STORE(&voice->Playing, false, almemory_order_release); + } ALCdevice_Unlock(device); DeinitSource(Source, device->NumAuxSends); @@ -2963,6 +2966,8 @@ void UpdateAllSourceProps(ALCcontext *context) */ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { + ALCdevice *device = Context->Device; + ALuint refcount; ALvoice *voice; WriteLock(&Source->queue_lock); @@ -2994,11 +2999,12 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { case AL_PLAYING: assert(voice != NULL); - /* A source that's already playing is restarted. */ + /* A source that's already playing is restarted from the beginning. */ ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed); ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_release); - /* fall-through */ + goto done; + case AL_PAUSED: assert(voice != NULL); /* A source that's paused simply resumes. Make sure it uses the @@ -3006,12 +3012,16 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) * it stopped at. */ voice->Moving = AL_FALSE; + ATOMIC_STORE(&voice->Playing, true, almemory_order_release); goto done; default: break; } + Source->NeedsUpdate = AL_FALSE; + UpdateSourceProps(Source, device->NumAuxSends); + /* Make sure this source isn't already active, and if not, look for an * unused voice to put it in. */ @@ -3021,22 +3031,20 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Context->Voices[i]->Source == NULL) { voice = Context->Voices[i]; - voice->Source = Source; break; } } if(voice == NULL) - { voice = Context->Voices[Context->VoiceCount++]; - voice->Source = Source; - } + ATOMIC_STORE(&voice->Playing, false, almemory_order_release); + ATOMIC_THREAD_FENCE(almemory_order_acquire); /* A source that's not playing or paused has any offset applied when it * starts playing. */ ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed); - ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_release); + ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_relaxed); if(Source->OffsetType != AL_NONE) ApplyOffset(Source, voice); @@ -3061,19 +3069,30 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } } - Source->NeedsUpdate = AL_FALSE; - UpdateSourceProps(Source, device->NumAuxSends); + voice->Source = Source; + ATOMIC_STORE(&voice->Playing, true, almemory_order_release); } 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: - voice = GetSourceVoice(Source, Context); - if(voice) voice->Source = NULL; + if((voice=GetSourceVoice(Source, Context)) != NULL) + { + voice->Source = NULL; + 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; @@ -3081,8 +3100,13 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } else if(state == AL_INITIAL) { - voice = GetSourceVoice(Source, Context); - if(voice) voice->Source = NULL; + if((voice=GetSourceVoice(Source, Context)) != NULL) + { + voice->Source = NULL; + 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_INITIAL, almemory_order_relaxed); Source->OffsetType = AL_NONE; -- cgit v1.2.3 From 073829f26a4a509d11de5375d43169a8f6ba9e12 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 5 Mar 2017 04:50:27 -0800 Subject: Make the voice's source pointer atomic --- Alc/ALc.c | 2 +- Alc/ALu.c | 12 ++++++------ OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 16 +++++++++------- 4 files changed, 17 insertions(+), 15 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 59475e48..42e1cea0 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1721,7 +1721,7 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) for(pos = 0;pos < context->VoiceCount;pos++) { ALvoice *voice = context->Voices[pos]; - ALsource *source = voice->Source; + ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire); if(source && source->OffsetType != AL_NONE) { WriteLock(&source->queue_lock); diff --git a/Alc/ALu.c b/Alc/ALu.c index 0a1b919a..e14c2013 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1277,8 +1277,8 @@ static void UpdateContextSources(ALCcontext *ctx, ALeffectslot *slot) voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) { - if((source=(*voice)->Source) != NULL) - CalcSourceParams(*voice, source, ctx, force); + source = ATOMIC_LOAD(&(*voice)->Source, almemory_order_acquire); + if(source) CalcSourceParams(*voice, source, ctx, force); } } IncrementRef(&ctx->UpdateCount); @@ -1419,13 +1419,13 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) voice_end = voice + ctx->VoiceCount; for(;voice != voice_end;++voice) { - source = (*voice)->Source; + source = ATOMIC_LOAD(&(*voice)->Source, almemory_order_acquire); if(source && ATOMIC_LOAD(&(*voice)->Playing, almemory_order_relaxed) && (*voice)->Step > 0) { if(!MixSource(*voice, source, device, SamplesToDo)) { - (*voice)->Source = NULL; + ATOMIC_STORE(&(*voice)->Source, NULL, almemory_order_relaxed); ATOMIC_STORE(&(*voice)->Playing, false, almemory_order_release); } } @@ -1592,8 +1592,8 @@ void aluHandleDisconnect(ALCdevice *device) voice_end = voice + Context->VoiceCount; while(voice != voice_end) { - ALsource *source = (*voice)->Source; - (*voice)->Source = NULL; + ALsource *source = ATOMIC_EXCHANGE(ALsource*, &(*voice)->Source, NULL, + almemory_order_acq_rel); ATOMIC_STORE(&(*voice)->Playing, false, almemory_order_release); if(source) diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index fc1756e5..52fe731e 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -80,7 +80,7 @@ struct ALsourceProps { typedef struct ALvoice { struct ALsourceProps *Props; - struct ALsource *Source; + ATOMIC(struct ALsource*) Source; ATOMIC(bool) Playing; /* Current buffer queue item being played. */ diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 14329bc2..df0e7136 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -132,7 +132,7 @@ static inline ALvoice *GetSourceVoice(const ALsource *source, const ALCcontext * ALvoice **voice_end = voice + context->VoiceCount; while(voice != voice_end) { - if((*voice)->Source == source) + if(ATOMIC_LOAD(&(*voice)->Source, almemory_order_acquire) == source) return *voice; ++voice; } @@ -1639,7 +1639,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) ALCdevice_Lock(device); if((voice=GetSourceVoice(Source, context)) != NULL) { - voice->Source = NULL; + ATOMIC_STORE(&voice->Source, NULL, almemory_order_relaxed); ATOMIC_STORE(&voice->Playing, false, almemory_order_release); } ALCdevice_Unlock(device); @@ -2950,7 +2950,7 @@ void UpdateAllSourceProps(ALCcontext *context) for(pos = 0;pos < context->VoiceCount;pos++) { ALvoice *voice = context->Voices[pos]; - ALsource *source = voice->Source; + ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire); if(source != NULL && source->NeedsUpdate && IsPlayingOrPausedSeq(source)) { source->NeedsUpdate = AL_FALSE; @@ -3028,7 +3028,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) assert(voice == NULL); for(i = 0;i < Context->VoiceCount;i++) { - if(Context->Voices[i]->Source == NULL) + if(ATOMIC_LOAD(&Context->Voices[i]->Source, almemory_order_acquire) == NULL) { voice = Context->Voices[i]; break; @@ -3069,7 +3069,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) } } - voice->Source = Source; + ATOMIC_STORE(&voice->Source, Source, almemory_order_relaxed); ATOMIC_STORE(&voice->Playing, true, almemory_order_release); } else if(state == AL_PAUSED) @@ -3088,7 +3088,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) do_stop: if((voice=GetSourceVoice(Source, Context)) != NULL) { - voice->Source = 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(); @@ -3102,7 +3102,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { if((voice=GetSourceVoice(Source, Context)) != NULL) { - voice->Source = 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(); @@ -3257,6 +3257,8 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); do { + Current = NULL; + readPos = readPosFrac = 0; while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) althrd_yield(); voice = GetSourceVoice(Source, context); -- cgit v1.2.3 From 1b3100ab9ac24a345b16a03fbad2c3cc2167ce79 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 5 Mar 2017 22:47:29 -0800 Subject: Remove an unused function --- OpenAL32/Include/alSource.h | 6 ------ OpenAL32/alSource.c | 1 - 2 files changed, 7 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 52fe731e..c33d6d1a 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -228,12 +228,6 @@ void UpdateAllSourceProps(ALCcontext *context); ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); ALboolean ApplyOffset(ALsource *Source, ALvoice *voice); -inline ALboolean IsPlayingOrPaused(const ALsource *source) -{ - ALenum state = ATOMIC_LOAD(&source->state, almemory_order_relaxed); - return state == AL_PLAYING || state == AL_PAUSED; -} - ALvoid ReleaseALSources(ALCcontext *Context); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index df0e7136..799ad855 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -46,7 +46,6 @@ extern inline void LockSourcesWrite(ALCcontext *context); extern inline void UnlockSourcesWrite(ALCcontext *context); extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); -extern inline ALboolean IsPlayingOrPaused(const ALsource *source); static void InitSourceParams(ALsource *Source, ALsizei num_sends); static void DeinitSource(ALsource *source, ALsizei num_sends); -- cgit v1.2.3 From 190120dfd7ae53e284944fa4971efcf999cc321e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 6 Mar 2017 22:58:04 -0800 Subject: Store the channel count and sample size in the voice --- Alc/mixer.c | 4 ++-- OpenAL32/Include/alSource.h | 11 +++++++---- OpenAL32/alSource.c | 15 ++++----------- 3 files changed, 13 insertions(+), 17 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/mixer.c b/Alc/mixer.c index 393d9210..1c503a92 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -389,8 +389,8 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei DataPosFrac = ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed); BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); Looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); - NumChannels = Source->NumChannels; - SampleSize = Source->SampleSize; + NumChannels = voice->NumChannels; + SampleSize = voice->SampleSize; increment = voice->Step; IrSize = (Device->Hrtf.Handle ? Device->Hrtf.Handle->irSize : 0); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index c33d6d1a..2525f107 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -94,6 +94,13 @@ typedef struct ALvoice { ATOMIC(ALuint) position; ATOMIC(ALuint) position_fraction; + /** + * Number of channels and bytes-per-sample for the attached source's + * buffer(s). + */ + ALsizei NumChannels; + ALsizei SampleSize; + /** Current target parameters used for mixing. */ ALint Step; @@ -197,10 +204,6 @@ typedef struct ALsource { ATOMIC(ALboolean) looping; - /** Current buffer sample info. */ - ALsizei NumChannels; - ALsizei SampleSize; - ALenum NeedsUpdate; ATOMIC(struct ALsourceProps*) Update; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 024d7918..ca4f3811 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -719,11 +719,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p /* Source is now Static */ Source->SourceType = AL_STATIC; - - ReadLock(&buffer->lock); - Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); - Source->SampleSize = BytesFromFmt(buffer->FmtType); - ReadUnlock(&buffer->lock); } else { @@ -2582,12 +2577,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu IncrementRef(&buffer->ref); if(BufferFmt == NULL) - { BufferFmt = buffer; - - source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); - source->SampleSize = BytesFromFmt(buffer->FmtType); - } else if(BufferFmt->Frequency != buffer->Frequency || BufferFmt->OriginalChannels != buffer->OriginalChannels || BufferFmt->OriginalType != buffer->OriginalType) @@ -2990,6 +2980,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { ALCdevice *device = Context->Device; ALbufferlistitem *BufferList; + ALbuffer *buffer = NULL; ALsizei i; /* Check that there is a queue containing at least one valid, non zero @@ -2997,7 +2988,6 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) BufferList = ATOMIC_LOAD_SEQ(&Source->queue); while(BufferList) { - ALbuffer *buffer; if((buffer=BufferList->buffer) != NULL && buffer->SampleLen > 0) break; BufferList = BufferList->next; @@ -3064,6 +3054,9 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) if(Source->OffsetType != AL_NONE) ApplyOffset(Source, voice); + voice->NumChannels = ChannelsFromFmt(buffer->FmtChannels); + voice->SampleSize = BytesFromFmt(buffer->FmtType); + /* Clear previous samples. */ memset(voice->PrevSamples, 0, sizeof(voice->PrevSamples)); -- cgit v1.2.3 From 5ffb0842ac5022b1e5d34973ed6f512b5f0d7434 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 8 Mar 2017 03:38:28 -0800 Subject: Remove unnecessary atomic members --- Alc/ALu.c | 195 ++++++++++++++++--------------------- OpenAL32/Include/alAuxEffectSlot.h | 8 +- OpenAL32/Include/alListener.h | 34 +++---- OpenAL32/Include/alSource.h | 82 ++++++++-------- OpenAL32/alAuxEffectSlot.c | 25 +++-- OpenAL32/alListener.c | 48 ++++----- OpenAL32/alSource.c | 79 ++++++++------- 7 files changed, 221 insertions(+), 250 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index e14c2013..04b9c89d 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -245,13 +245,13 @@ static ALboolean CalcListenerParams(ALCcontext *Context) if(!props) return AL_FALSE; /* AT then UP */ - N[0] = ATOMIC_LOAD(&props->Forward[0], almemory_order_relaxed); - N[1] = ATOMIC_LOAD(&props->Forward[1], almemory_order_relaxed); - N[2] = ATOMIC_LOAD(&props->Forward[2], almemory_order_relaxed); + N[0] = props->Forward[0]; + N[1] = props->Forward[1]; + N[2] = props->Forward[2]; aluNormalize(N); - V[0] = ATOMIC_LOAD(&props->Up[0], almemory_order_relaxed); - V[1] = ATOMIC_LOAD(&props->Up[1], almemory_order_relaxed); - V[2] = ATOMIC_LOAD(&props->Up[2], almemory_order_relaxed); + V[0] = props->Up[0]; + V[1] = props->Up[1]; + V[2] = props->Up[2]; aluNormalize(V); /* Build and normalize right-vector */ aluCrossproduct(N, V, U); @@ -264,27 +264,23 @@ static ALboolean CalcListenerParams(ALCcontext *Context) 0.0, 0.0, 0.0, 1.0 ); - P[0] = ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed); - P[1] = ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed); - P[2] = ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed); + P[0] = props->Position[0]; + P[1] = props->Position[1]; + P[2] = props->Position[2]; aluMatrixfFloat3(P, 1.0, &Listener->Params.Matrix); aluMatrixfSetRow(&Listener->Params.Matrix, 3, -P[0], -P[1], -P[2], 1.0f); - aluVectorSet(&vel, ATOMIC_LOAD(&props->Velocity[0], almemory_order_relaxed), - ATOMIC_LOAD(&props->Velocity[1], almemory_order_relaxed), - ATOMIC_LOAD(&props->Velocity[2], almemory_order_relaxed), - 0.0f); + aluVectorSet(&vel, props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f); Listener->Params.Velocity = aluMatrixfVector(&Listener->Params.Matrix, &vel); - Listener->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed) * Context->GainBoost; - Listener->Params.MetersPerUnit = ATOMIC_LOAD(&props->MetersPerUnit, almemory_order_relaxed); + Listener->Params.Gain = props->Gain * Context->GainBoost; + Listener->Params.MetersPerUnit = props->MetersPerUnit; - Listener->Params.DopplerFactor = ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed); - Listener->Params.SpeedOfSound = ATOMIC_LOAD(&props->SpeedOfSound, almemory_order_relaxed) * - ATOMIC_LOAD(&props->DopplerVelocity, almemory_order_relaxed); + Listener->Params.DopplerFactor = props->DopplerFactor; + Listener->Params.SpeedOfSound = props->SpeedOfSound * props->DopplerVelocity; - Listener->Params.SourceDistanceModel = ATOMIC_LOAD(&props->SourceDistanceModel, almemory_order_relaxed); - Listener->Params.DistanceModel = ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed); + Listener->Params.SourceDistanceModel = props->SourceDistanceModel; + Listener->Params.DistanceModel = props->DistanceModel; ATOMIC_REPLACE_HEAD(struct ALlistenerProps*, &Listener->FreeList, props); return AL_TRUE; @@ -298,9 +294,9 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, NULL, almemory_order_acq_rel); if(!props) return AL_FALSE; - slot->Params.Gain = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); - slot->Params.AuxSendAuto = ATOMIC_LOAD(&props->AuxSendAuto, almemory_order_relaxed); - slot->Params.EffectType = ATOMIC_LOAD(&props->Type, almemory_order_relaxed); + slot->Params.Gain = props->Gain; + slot->Params.AuxSendAuto = props->AuxSendAuto; + slot->Params.EffectType = props->Type; if(IsReverbEffect(slot->Params.EffectType)) { slot->Params.RoomRolloff = props->Props.Reverb.RoomRolloffFactor; @@ -317,8 +313,8 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) /* Swap effect states. No need to play with the ref counts since they keep * the same number of refs. */ - state = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Params.EffectState, - almemory_order_relaxed); + state = props->State; + props->State = slot->Params.EffectState; slot->Params.EffectState = state; V(state,update)(device, slot, &props->Props); @@ -396,22 +392,22 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * ListenerGain = Listener->Params.Gain; /* Get source properties */ - SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); - MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed); - MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed); - Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed); - Relative = ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed); - DirectChannels = ATOMIC_LOAD(&props->DirectChannels, almemory_order_relaxed); + SourceVolume = props->Gain; + MinVolume = props->MinGain; + MaxVolume = props->MaxGain; + Pitch = props->Pitch; + Relative = props->HeadRelative; + DirectChannels = props->DirectChannels; /* Convert counter-clockwise to clockwise. */ - StereoMap[0].angle = -ATOMIC_LOAD(&props->StereoPan[0], almemory_order_relaxed); - StereoMap[1].angle = -ATOMIC_LOAD(&props->StereoPan[1], almemory_order_relaxed); + StereoMap[0].angle = -props->StereoPan[0]; + StereoMap[1].angle = -props->StereoPan[1]; voice->Direct.Buffer = Device->Dry.Buffer; voice->Direct.Channels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { - SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); + SendSlots[i] = props->Send[i].Slot; if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) @@ -437,17 +433,17 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); - DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain; + DryGain *= props->Direct.Gain * ListenerGain; DryGain = minf(DryGain, GAIN_MIX_MAX); - DryGainHF = ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed); - DryGainLF = ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed); + DryGainHF = props->Direct.GainHF; + DryGainLF = props->Direct.GainLF; for(i = 0;i < NumSends;i++) { WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume); - WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain; + WetGain[i] *= props->Send[i].Gain * ListenerGain; WetGain[i] = minf(WetGain[i], GAIN_MIX_MAX); - WetGainHF[i] = ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed); - WetGainLF[i] = ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed); + WetGainHF[i] = props->Send[i].GainHF; + WetGainLF[i] = props->Send[i].GainLF; } switch(ALBuffer->FmtChannels) @@ -507,13 +503,13 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * ALfloat scale; /* AT then UP */ - N[0] = ATOMIC_LOAD(&props->Orientation[0][0], almemory_order_relaxed); - N[1] = ATOMIC_LOAD(&props->Orientation[0][1], almemory_order_relaxed); - N[2] = ATOMIC_LOAD(&props->Orientation[0][2], almemory_order_relaxed); + N[0] = props->Orientation[0][0]; + N[1] = props->Orientation[0][1]; + N[2] = props->Orientation[0][2]; aluNormalize(N); - V[0] = ATOMIC_LOAD(&props->Orientation[1][0], almemory_order_relaxed); - V[1] = ATOMIC_LOAD(&props->Orientation[1][1], almemory_order_relaxed); - V[2] = ATOMIC_LOAD(&props->Orientation[1][2], almemory_order_relaxed); + V[0] = props->Orientation[1][0]; + V[1] = props->Orientation[1][1]; + V[2] = props->Orientation[1][2]; aluNormalize(V); if(!Relative) { @@ -704,8 +700,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * } { - HFScale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) / Frequency; - LFScale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) / Frequency; + HFScale = props->Direct.HFReference / Frequency; + LFScale = props->Direct.LFReference / Frequency; DryGainHF = maxf(DryGainHF, 0.0625f); /* Limit -24dB */ DryGainLF = maxf(DryGainLF, 0.0625f); for(c = 0;c < num_channels;c++) @@ -725,8 +721,8 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * } for(i = 0;i < NumSends;i++) { - HFScale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) / Frequency; - LFScale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) / Frequency; + HFScale = props->Send[i].HFReference / Frequency; + LFScale = props->Send[i].LFReference / Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0625f); WetGainLF[i] = maxf(WetGainLF[i], 0.0625f); for(c = 0;c < num_channels;c++) @@ -790,40 +786,30 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro MetersPerUnit = Listener->Params.MetersPerUnit; /* Get source properties */ - SourceVolume = ATOMIC_LOAD(&props->Gain, almemory_order_relaxed); - MinVolume = ATOMIC_LOAD(&props->MinGain, almemory_order_relaxed); - MaxVolume = ATOMIC_LOAD(&props->MaxGain, almemory_order_relaxed); - Pitch = ATOMIC_LOAD(&props->Pitch, almemory_order_relaxed); - aluVectorSet(&Position, ATOMIC_LOAD(&props->Position[0], almemory_order_relaxed), - ATOMIC_LOAD(&props->Position[1], almemory_order_relaxed), - ATOMIC_LOAD(&props->Position[2], almemory_order_relaxed), - 1.0f); - aluVectorSet(&Direction, ATOMIC_LOAD(&props->Direction[0], almemory_order_relaxed), - ATOMIC_LOAD(&props->Direction[1], almemory_order_relaxed), - ATOMIC_LOAD(&props->Direction[2], almemory_order_relaxed), - 0.0f); - aluVectorSet(&Velocity, ATOMIC_LOAD(&props->Velocity[0], almemory_order_relaxed), - ATOMIC_LOAD(&props->Velocity[1], almemory_order_relaxed), - ATOMIC_LOAD(&props->Velocity[2], almemory_order_relaxed), - 0.0f); - MinDist = ATOMIC_LOAD(&props->RefDistance, almemory_order_relaxed); - MaxDist = ATOMIC_LOAD(&props->MaxDistance, almemory_order_relaxed); - Rolloff = ATOMIC_LOAD(&props->RollOffFactor, almemory_order_relaxed); - DopplerFactor *= ATOMIC_LOAD(&props->DopplerFactor, almemory_order_relaxed); - InnerAngle = ATOMIC_LOAD(&props->InnerAngle, almemory_order_relaxed); - OuterAngle = ATOMIC_LOAD(&props->OuterAngle, almemory_order_relaxed); - AirAbsorptionFactor = ATOMIC_LOAD(&props->AirAbsorptionFactor, almemory_order_relaxed); - DryGainHFAuto = ATOMIC_LOAD(&props->DryGainHFAuto, almemory_order_relaxed); - WetGainAuto = ATOMIC_LOAD(&props->WetGainAuto, almemory_order_relaxed); - WetGainHFAuto = ATOMIC_LOAD(&props->WetGainHFAuto, almemory_order_relaxed); - RoomRolloffBase = ATOMIC_LOAD(&props->RoomRolloffFactor, almemory_order_relaxed); + SourceVolume = props->Gain; + MinVolume = props->MinGain; + MaxVolume = props->MaxGain; + Pitch = props->Pitch; + aluVectorSet(&Position, props->Position[0], props->Position[1], props->Position[2], 1.0f); + aluVectorSet(&Direction, props->Direction[0], props->Direction[1], props->Direction[2], 0.0f); + aluVectorSet(&Velocity, props->Velocity[0], props->Velocity[1], props->Velocity[2], 0.0f); + MinDist = props->RefDistance; + MaxDist = props->MaxDistance; + Rolloff = props->RollOffFactor; + DopplerFactor *= props->DopplerFactor; + InnerAngle = props->InnerAngle; + OuterAngle = props->OuterAngle; + AirAbsorptionFactor = props->AirAbsorptionFactor; + DryGainHFAuto = props->DryGainHFAuto; + WetGainAuto = props->WetGainAuto; + WetGainHFAuto = props->WetGainHFAuto; + RoomRolloffBase = props->RoomRolloffFactor; voice->Direct.Buffer = Device->Dry.Buffer; voice->Direct.Channels = Device->Dry.NumChannels; for(i = 0;i < NumSends;i++) { - SendSlots[i] = ATOMIC_LOAD(&props->Send[i].Slot, almemory_order_relaxed); - + SendSlots[i] = props->Send[i].Slot; if(!SendSlots[i] && i == 0) SendSlots[i] = Device->DefaultSlot; if(!SendSlots[i] || SendSlots[i]->Params.EffectType == AL_EFFECT_NULL) @@ -862,7 +848,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } /* Transform source to listener space (convert to head relative) */ - if(ATOMIC_LOAD(&props->HeadRelative, almemory_order_relaxed) == AL_FALSE) + if(props->HeadRelative == AL_FALSE) { const aluMatrixf *Matrix = &Listener->Params.Matrix; /* Transform source vectors */ @@ -893,8 +879,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro for(i = 0;i < NumSends;i++) RoomAttenuation[i] = 1.0f; switch(Listener->Params.SourceDistanceModel ? - ATOMIC_LOAD(&props->DistanceModel, almemory_order_relaxed) : - Listener->Params.DistanceModel) + props->DistanceModel : Listener->Params.DistanceModel) { case InverseDistanceClamped: ClampedDist = clampf(ClampedDist, MinDist, MaxDist); @@ -1003,17 +988,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro if(Angle < OuterAngle) { scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle); - ConeVolume = lerp( - 1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), scale - ); - ConeHF = lerp( - 1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), scale - ); + ConeVolume = lerp(1.0f, props->OuterGain, scale); + ConeHF = lerp(1.0f, props->OuterGainHF, scale); } else { - ConeVolume = ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed); - ConeHF = ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed); + ConeVolume = props->OuterGain; + ConeHF = props->OuterGainHF; } DryGain *= ConeVolume; if(DryGainHFAuto) @@ -1027,17 +1008,13 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro (InnerAngle/360.0f); if(WetGainAuto) { - ConeVolume = lerp( - 1.0f, ATOMIC_LOAD(&props->OuterGain, almemory_order_relaxed), scale - ); + ConeVolume = lerp(1.0f, props->OuterGain, scale); for(i = 0;i < NumSends;i++) WetGain[i] *= ConeVolume; } if(WetGainHFAuto) { - ConeHF = lerp( - 1.0f, ATOMIC_LOAD(&props->OuterGainHF, almemory_order_relaxed), scale - ); + ConeHF = lerp(1.0f, props->OuterGainHF, scale); for(i = 0;i < NumSends;i++) WetGainHF[i] *= ConeHF; } @@ -1045,17 +1022,17 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro /* Apply gain and frequency filters */ DryGain = clampf(DryGain, MinVolume, MaxVolume); - DryGain *= ATOMIC_LOAD(&props->Direct.Gain, almemory_order_relaxed) * ListenerGain; + DryGain *= props->Direct.Gain * ListenerGain; DryGain = minf(DryGain, GAIN_MIX_MAX); - DryGainHF *= ATOMIC_LOAD(&props->Direct.GainHF, almemory_order_relaxed); - DryGainLF *= ATOMIC_LOAD(&props->Direct.GainLF, almemory_order_relaxed); + DryGainHF *= props->Direct.GainHF; + DryGainLF *= props->Direct.GainLF; for(i = 0;i < NumSends;i++) { WetGain[i] = clampf(WetGain[i], MinVolume, MaxVolume); - WetGain[i] *= ATOMIC_LOAD(&props->Send[i].Gain, almemory_order_relaxed) * ListenerGain; + WetGain[i] *= props->Send[i].Gain * ListenerGain; WetGain[i] = minf(WetGain[i], GAIN_MIX_MAX); - WetGainHF[i] *= ATOMIC_LOAD(&props->Send[i].GainHF, almemory_order_relaxed); - WetGainLF[i] *= ATOMIC_LOAD(&props->Send[i].GainLF, almemory_order_relaxed); + WetGainHF[i] *= props->Send[i].GainHF; + WetGainLF[i] *= props->Send[i].GainLF; } /* Calculate velocity-based doppler effect */ @@ -1093,9 +1070,9 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro * real outputs. */ ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; - ALfloat ev = 0.0f, az = 0.0f; - ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed); ALfloat coeffs[MAX_AMBI_COEFFS]; + ALfloat radius = props->Radius; + ALfloat ev = 0.0f, az = 0.0f; ALfloat spread = 0.0f; voice->Direct.Buffer = Device->RealOut.Buffer; @@ -1144,8 +1121,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro { /* Non-HRTF rendering. */ ALfloat dir[3] = { 0.0f, 0.0f, -1.0f }; - ALfloat radius = ATOMIC_LOAD(&props->Radius, almemory_order_relaxed); ALfloat coeffs[MAX_AMBI_COEFFS]; + ALfloat radius = props->Radius; ALfloat spread = 0.0f; /* Get the localized direction, and compute panned gains. */ @@ -1188,8 +1165,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } { - HFScale = ATOMIC_LOAD(&props->Direct.HFReference, almemory_order_relaxed) / Frequency; - LFScale = ATOMIC_LOAD(&props->Direct.LFReference, almemory_order_relaxed) / Frequency; + HFScale = props->Direct.HFReference / Frequency; + LFScale = props->Direct.LFReference / Frequency; DryGainHF = maxf(DryGainHF, 0.0625f); /* Limit -24dB */ DryGainLF = maxf(DryGainLF, 0.0625f); voice->Direct.Params[0].FilterType = AF_None; @@ -1206,8 +1183,8 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } for(i = 0;i < NumSends;i++) { - HFScale = ATOMIC_LOAD(&props->Send[i].HFReference, almemory_order_relaxed) / Frequency; - LFScale = ATOMIC_LOAD(&props->Send[i].LFReference, almemory_order_relaxed) / Frequency; + HFScale = props->Send[i].HFReference / Frequency; + LFScale = props->Send[i].LFReference / Frequency; WetGainHF[i] = maxf(WetGainHF[i], 0.0625f); WetGainLF[i] = maxf(WetGainLF[i], 0.0625f); voice->Send[i].Params[0].FilterType = AF_None; diff --git a/OpenAL32/Include/alAuxEffectSlot.h b/OpenAL32/Include/alAuxEffectSlot.h index 40ff1393..3c24f80c 100644 --- a/OpenAL32/Include/alAuxEffectSlot.h +++ b/OpenAL32/Include/alAuxEffectSlot.h @@ -75,13 +75,13 @@ static const struct ALeffectStateFactoryVtable T##_ALeffectStateFactory_vtable = struct ALeffectslotProps { - ATOMIC(ALfloat) Gain; - ATOMIC(ALboolean) AuxSendAuto; + ALfloat Gain; + ALboolean AuxSendAuto; - ATOMIC(ALenum) Type; + ALenum Type; ALeffectProps Props; - ATOMIC(ALeffectState*) State; + ALeffectState *State; ATOMIC(struct ALeffectslotProps*) next; }; diff --git a/OpenAL32/Include/alListener.h b/OpenAL32/Include/alListener.h index b89a00e7..9a7f9d49 100644 --- a/OpenAL32/Include/alListener.h +++ b/OpenAL32/Include/alListener.h @@ -9,29 +9,29 @@ extern "C" { #endif struct ALlistenerProps { - ATOMIC(ALfloat) Position[3]; - ATOMIC(ALfloat) Velocity[3]; - ATOMIC(ALfloat) Forward[3]; - ATOMIC(ALfloat) Up[3]; - ATOMIC(ALfloat) Gain; - ATOMIC(ALfloat) MetersPerUnit; + ALfloat Position[3]; + ALfloat Velocity[3]; + ALfloat Forward[3]; + ALfloat Up[3]; + ALfloat Gain; + ALfloat MetersPerUnit; - ATOMIC(ALfloat) DopplerFactor; - ATOMIC(ALfloat) DopplerVelocity; - ATOMIC(ALfloat) SpeedOfSound; - ATOMIC(ALboolean) SourceDistanceModel; - ATOMIC(enum DistanceModel) DistanceModel; + ALfloat DopplerFactor; + ALfloat DopplerVelocity; + ALfloat SpeedOfSound; + ALboolean SourceDistanceModel; + enum DistanceModel DistanceModel; ATOMIC(struct ALlistenerProps*) next; }; typedef struct ALlistener { - volatile ALfloat Position[3]; - volatile ALfloat Velocity[3]; - volatile ALfloat Forward[3]; - volatile ALfloat Up[3]; - volatile ALfloat Gain; - volatile ALfloat MetersPerUnit; + ALfloat Position[3]; + ALfloat Velocity[3]; + 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/alSource.h b/OpenAL32/Include/alSource.h index 2525f107..12b4587b 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -27,52 +27,52 @@ typedef struct ALbufferlistitem { struct ALsourceProps { ATOMIC(struct ALsourceProps*) next; - ATOMIC(ALfloat) Pitch; - ATOMIC(ALfloat) Gain; - ATOMIC(ALfloat) OuterGain; - ATOMIC(ALfloat) MinGain; - ATOMIC(ALfloat) MaxGain; - ATOMIC(ALfloat) InnerAngle; - ATOMIC(ALfloat) OuterAngle; - ATOMIC(ALfloat) RefDistance; - ATOMIC(ALfloat) MaxDistance; - ATOMIC(ALfloat) RollOffFactor; - ATOMIC(ALfloat) Position[3]; - ATOMIC(ALfloat) Velocity[3]; - ATOMIC(ALfloat) Direction[3]; - ATOMIC(ALfloat) Orientation[2][3]; - ATOMIC(ALboolean) HeadRelative; - ATOMIC(enum DistanceModel) DistanceModel; - ATOMIC(ALboolean) DirectChannels; - - ATOMIC(ALboolean) DryGainHFAuto; - ATOMIC(ALboolean) WetGainAuto; - ATOMIC(ALboolean) WetGainHFAuto; - ATOMIC(ALfloat) OuterGainHF; - - ATOMIC(ALfloat) AirAbsorptionFactor; - ATOMIC(ALfloat) RoomRolloffFactor; - ATOMIC(ALfloat) DopplerFactor; - - ATOMIC(ALfloat) StereoPan[2]; - - ATOMIC(ALfloat) Radius; + 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 { - ATOMIC(ALfloat) Gain; - ATOMIC(ALfloat) GainHF; - ATOMIC(ALfloat) HFReference; - ATOMIC(ALfloat) GainLF; - ATOMIC(ALfloat) LFReference; + ALfloat Gain; + ALfloat GainHF; + ALfloat HFReference; + ALfloat GainLF; + ALfloat LFReference; } Direct; struct { - ATOMIC(struct ALeffectslot*) Slot; - ATOMIC(ALfloat) Gain; - ATOMIC(ALfloat) GainHF; - ATOMIC(ALfloat) HFReference; - ATOMIC(ALfloat) GainLF; - ATOMIC(ALfloat) LFReference; + struct ALeffectslot *Slot; + ALfloat Gain; + ALfloat GainHF; + ALfloat HFReference; + ALfloat GainLF; + ALfloat LFReference; } Send[]; }; diff --git a/OpenAL32/alAuxEffectSlot.c b/OpenAL32/alAuxEffectSlot.c index e6b4ff68..37316549 100644 --- a/OpenAL32/alAuxEffectSlot.c +++ b/OpenAL32/alAuxEffectSlot.c @@ -530,8 +530,9 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e props = ATOMIC_LOAD_SEQ(&EffectSlot->FreeList); while(props) { - State = ATOMIC_EXCHANGE(ALeffectState*, &props->State, NULL, almemory_order_relaxed); - if(State) ALeffectState_DecRef(State); + if(props->State) + ALeffectState_DecRef(props->State); + props->State = NULL; props = ATOMIC_LOAD(&props->next, almemory_order_relaxed); } @@ -602,24 +603,20 @@ ALenum InitEffectSlot(ALeffectslot *slot) void DeinitEffectSlot(ALeffectslot *slot) { struct ALeffectslotProps *props; - ALeffectState *state; size_t count = 0; props = ATOMIC_LOAD_SEQ(&slot->Update); if(props) { - state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); - if(state) ALeffectState_DecRef(state); + if(props->State) ALeffectState_DecRef(props->State); TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); al_free(props); } props = ATOMIC_LOAD(&slot->FreeList, almemory_order_relaxed); while(props) { - struct ALeffectslotProps *next; - state = ATOMIC_LOAD(&props->State, almemory_order_relaxed); - next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); - if(state) ALeffectState_DecRef(state); + struct ALeffectslotProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + if(props->State) ALeffectState_DecRef(props->State); al_free(props); props = next; ++count; @@ -651,17 +648,17 @@ void UpdateEffectSlotProps(ALeffectslot *slot) } /* Copy in current property values. */ - ATOMIC_STORE(&props->Gain, slot->Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->AuxSendAuto, slot->AuxSendAuto, almemory_order_relaxed); + props->Gain = slot->Gain; + props->AuxSendAuto = slot->AuxSendAuto; - ATOMIC_STORE(&props->Type, slot->Effect.Type, almemory_order_relaxed); + props->Type = slot->Effect.Type; props->Props = slot->Effect.Props; /* Swap out any stale effect state object there may be in the container, to * delete it. */ ALeffectState_IncRef(slot->Effect.State); - oldstate = ATOMIC_EXCHANGE(ALeffectState*, &props->State, slot->Effect.State, - almemory_order_relaxed); + oldstate = props->State; + props->State = slot->Effect.State; /* Set the new container for updating internal parameters. */ props = ATOMIC_EXCHANGE(struct ALeffectslotProps*, &slot->Update, props, diff --git a/OpenAL32/alListener.c b/OpenAL32/alListener.c index 9c237e99..e3d71435 100644 --- a/OpenAL32/alListener.c +++ b/OpenAL32/alListener.c @@ -474,30 +474,30 @@ void UpdateListenerProps(ALCcontext *context) } /* Copy in current property values. */ - ATOMIC_STORE(&props->Position[0], listener->Position[0], almemory_order_relaxed); - ATOMIC_STORE(&props->Position[1], listener->Position[1], almemory_order_relaxed); - ATOMIC_STORE(&props->Position[2], listener->Position[2], almemory_order_relaxed); - - ATOMIC_STORE(&props->Velocity[0], listener->Velocity[0], almemory_order_relaxed); - ATOMIC_STORE(&props->Velocity[1], listener->Velocity[1], almemory_order_relaxed); - ATOMIC_STORE(&props->Velocity[2], listener->Velocity[2], almemory_order_relaxed); - - ATOMIC_STORE(&props->Forward[0], listener->Forward[0], almemory_order_relaxed); - ATOMIC_STORE(&props->Forward[1], listener->Forward[1], almemory_order_relaxed); - ATOMIC_STORE(&props->Forward[2], listener->Forward[2], almemory_order_relaxed); - ATOMIC_STORE(&props->Up[0], listener->Up[0], almemory_order_relaxed); - ATOMIC_STORE(&props->Up[1], listener->Up[1], almemory_order_relaxed); - ATOMIC_STORE(&props->Up[2], listener->Up[2], almemory_order_relaxed); - - ATOMIC_STORE(&props->Gain, listener->Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->MetersPerUnit, listener->MetersPerUnit, almemory_order_relaxed); - - ATOMIC_STORE(&props->DopplerFactor, context->DopplerFactor, almemory_order_relaxed); - ATOMIC_STORE(&props->DopplerVelocity, context->DopplerVelocity, almemory_order_relaxed); - ATOMIC_STORE(&props->SpeedOfSound, context->SpeedOfSound, almemory_order_relaxed); - - ATOMIC_STORE(&props->SourceDistanceModel, context->SourceDistanceModel, almemory_order_relaxed); - ATOMIC_STORE(&props->DistanceModel, context->DistanceModel, almemory_order_relaxed); + props->Position[0] = listener->Position[0]; + props->Position[1] = listener->Position[1]; + props->Position[2] = listener->Position[2]; + + props->Velocity[0] = listener->Velocity[0]; + props->Velocity[1] = listener->Velocity[1]; + props->Velocity[2] = listener->Velocity[2]; + + props->Forward[0] = listener->Forward[0]; + props->Forward[1] = listener->Forward[1]; + props->Forward[2] = listener->Forward[2]; + props->Up[0] = listener->Up[0]; + props->Up[1] = listener->Up[1]; + 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(struct ALlistenerProps*, &listener->Update, props, almemory_order_acq_rel); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index e81fd853..c4c0bfb1 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2892,63 +2892,60 @@ static void UpdateSourceProps(ALsource *source, ALsizei num_sends) } /* Copy in current property values. */ - ATOMIC_STORE(&props->Pitch, source->Pitch, almemory_order_relaxed); - ATOMIC_STORE(&props->Gain, source->Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->OuterGain, source->OuterGain, almemory_order_relaxed); - ATOMIC_STORE(&props->MinGain, source->MinGain, almemory_order_relaxed); - ATOMIC_STORE(&props->MaxGain, source->MaxGain, almemory_order_relaxed); - ATOMIC_STORE(&props->InnerAngle, source->InnerAngle, almemory_order_relaxed); - ATOMIC_STORE(&props->OuterAngle, source->OuterAngle, almemory_order_relaxed); - ATOMIC_STORE(&props->RefDistance, source->RefDistance, almemory_order_relaxed); - ATOMIC_STORE(&props->MaxDistance, source->MaxDistance, almemory_order_relaxed); - ATOMIC_STORE(&props->RollOffFactor, source->RollOffFactor, almemory_order_relaxed); + props->Pitch = source->Pitch; + props->Gain = source->Gain; + props->OuterGain = source->OuterGain; + props->MinGain = source->MinGain; + props->MaxGain = source->MaxGain; + props->InnerAngle = source->InnerAngle; + props->OuterAngle = source->OuterAngle; + props->RefDistance = source->RefDistance; + props->MaxDistance = source->MaxDistance; + props->RollOffFactor = source->RollOffFactor; for(i = 0;i < 3;i++) - ATOMIC_STORE(&props->Position[i], source->Position[i], almemory_order_relaxed); + props->Position[i] = source->Position[i]; for(i = 0;i < 3;i++) - ATOMIC_STORE(&props->Velocity[i], source->Velocity[i], almemory_order_relaxed); + props->Velocity[i] = source->Velocity[i]; for(i = 0;i < 3;i++) - ATOMIC_STORE(&props->Direction[i], source->Direction[i], almemory_order_relaxed); + props->Direction[i] = source->Direction[i]; for(i = 0;i < 2;i++) { ALsizei j; for(j = 0;j < 3;j++) - ATOMIC_STORE(&props->Orientation[i][j], source->Orientation[i][j], - almemory_order_relaxed); + props->Orientation[i][j] = source->Orientation[i][j]; } - ATOMIC_STORE(&props->HeadRelative, source->HeadRelative, almemory_order_relaxed); - ATOMIC_STORE(&props->DistanceModel, source->DistanceModel, almemory_order_relaxed); - ATOMIC_STORE(&props->DirectChannels, source->DirectChannels, almemory_order_relaxed); + props->HeadRelative = source->HeadRelative; + props->DistanceModel = source->DistanceModel; + props->DirectChannels = source->DirectChannels; - ATOMIC_STORE(&props->DryGainHFAuto, source->DryGainHFAuto, almemory_order_relaxed); - ATOMIC_STORE(&props->WetGainAuto, source->WetGainAuto, almemory_order_relaxed); - ATOMIC_STORE(&props->WetGainHFAuto, source->WetGainHFAuto, almemory_order_relaxed); - ATOMIC_STORE(&props->OuterGainHF, source->OuterGainHF, almemory_order_relaxed); + props->DryGainHFAuto = source->DryGainHFAuto; + props->WetGainAuto = source->WetGainAuto; + props->WetGainHFAuto = source->WetGainHFAuto; + props->OuterGainHF = source->OuterGainHF; - ATOMIC_STORE(&props->AirAbsorptionFactor, source->AirAbsorptionFactor, almemory_order_relaxed); - ATOMIC_STORE(&props->RoomRolloffFactor, source->RoomRolloffFactor, almemory_order_relaxed); - ATOMIC_STORE(&props->DopplerFactor, source->DopplerFactor, almemory_order_relaxed); + props->AirAbsorptionFactor = source->AirAbsorptionFactor; + props->RoomRolloffFactor = source->RoomRolloffFactor; + props->DopplerFactor = source->DopplerFactor; - ATOMIC_STORE(&props->StereoPan[0], source->StereoPan[0], almemory_order_relaxed); - ATOMIC_STORE(&props->StereoPan[1], source->StereoPan[1], almemory_order_relaxed); + props->StereoPan[0] = source->StereoPan[0]; + props->StereoPan[1] = source->StereoPan[1]; - ATOMIC_STORE(&props->Radius, source->Radius, almemory_order_relaxed); + props->Radius = source->Radius; - ATOMIC_STORE(&props->Direct.Gain, source->Direct.Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->Direct.GainHF, source->Direct.GainHF, almemory_order_relaxed); - ATOMIC_STORE(&props->Direct.HFReference, source->Direct.HFReference, almemory_order_relaxed); - ATOMIC_STORE(&props->Direct.GainLF, source->Direct.GainLF, almemory_order_relaxed); - ATOMIC_STORE(&props->Direct.LFReference, source->Direct.LFReference, almemory_order_relaxed); + props->Direct.Gain = source->Direct.Gain; + props->Direct.GainHF = source->Direct.GainHF; + props->Direct.HFReference = source->Direct.HFReference; + props->Direct.GainLF = source->Direct.GainLF; + props->Direct.LFReference = source->Direct.LFReference; for(i = 0;i < num_sends;i++) { - ATOMIC_STORE(&props->Send[i].Slot, source->Send[i].Slot, almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].Gain, source->Send[i].Gain, almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].GainHF, source->Send[i].GainHF, almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].HFReference, source->Send[i].HFReference, - almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].GainLF, source->Send[i].GainLF, almemory_order_relaxed); - ATOMIC_STORE(&props->Send[i].LFReference, source->Send[i].LFReference, - almemory_order_relaxed); + props->Send[i].Slot = source->Send[i].Slot; + props->Send[i].Gain = source->Send[i].Gain; + props->Send[i].GainHF = source->Send[i].GainHF; + props->Send[i].HFReference = source->Send[i].HFReference; + props->Send[i].GainLF = source->Send[i].GainLF; + props->Send[i].LFReference = source->Send[i].LFReference; } /* Set the new container for updating internal parameters. */ -- cgit v1.2.3 From 9454d3e776792ed5762d72f28f6785b4b2d1606c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 9 Mar 2017 07:23:12 -0800 Subject: Move ALvoice declaration to alu.h --- OpenAL32/Include/alSource.h | 54 ------------------------------------------- OpenAL32/Include/alu.h | 56 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 55 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 12b4587b..1dd835c4 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -77,60 +77,6 @@ struct ALsourceProps { }; -typedef struct ALvoice { - struct ALsourceProps *Props; - - ATOMIC(struct ALsource*) Source; - ATOMIC(bool) Playing; - - /* Current buffer queue item being played. */ - ATOMIC(ALbufferlistitem*) current_buffer; - - /** - * Source offset in samples, relative to the currently playing buffer, NOT - * the whole queue, and the fractional (fixed-point) offset to the next - * sample. - */ - ATOMIC(ALuint) position; - ATOMIC(ALuint) position_fraction; - - /** - * Number of channels and bytes-per-sample for the attached source's - * buffer(s). - */ - ALsizei NumChannels; - ALsizei SampleSize; - - /** Current target parameters used for mixing. */ - ALint Step; - - /* If not 'moving', gain/coefficients are set directly without fading. */ - ALboolean Moving; - - ALboolean IsHrtf; - - ALuint Offset; /* Number of output samples mixed since starting. */ - - alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES]; - - InterpState ResampleState; - - struct { - DirectParams Params[MAX_INPUT_CHANNELS]; - - ALfloat (*Buffer)[BUFFERSIZE]; - ALsizei Channels; - } Direct; - - struct { - SendParams Params[MAX_INPUT_CHANNELS]; - - ALfloat (*Buffer)[BUFFERSIZE]; - ALsizei Channels; - } Send[]; -} ALvoice; - - typedef struct ALsource { /** Source properties. */ ALfloat Pitch; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index b6f0e769..03f0090d 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -35,9 +35,9 @@ extern "C" { struct ALsource; struct ALsourceProps; +struct ALbufferlistitem; struct ALvoice; struct ALeffectslot; -struct ALbuffer; /* The number of distinct scale and phase intervals within the filter table. */ @@ -123,6 +123,7 @@ typedef struct MixHrtfParams { } Steps; } MixHrtfParams; + typedef struct DirectParams { enum ActiveFilters FilterType; ALfilterState LowPass; @@ -151,6 +152,59 @@ typedef struct SendParams { } Gains; } SendParams; +typedef struct ALvoice { + struct ALsourceProps *Props; + + ATOMIC(struct ALsource*) Source; + ATOMIC(bool) Playing; + + /* Current buffer queue item being played. */ + ATOMIC(struct ALbufferlistitem*) current_buffer; + + /** + * Source offset in samples, relative to the currently playing buffer, NOT + * the whole queue, and the fractional (fixed-point) offset to the next + * sample. + */ + ATOMIC(ALuint) position; + ATOMIC(ALuint) position_fraction; + + /** + * Number of channels and bytes-per-sample for the attached source's + * buffer(s). + */ + ALsizei NumChannels; + ALsizei SampleSize; + + /** Current target parameters used for mixing. */ + ALint Step; + + /* If not 'moving', gain/coefficients are set directly without fading. */ + ALboolean Moving; + + ALboolean IsHrtf; + + ALuint Offset; /* Number of output samples mixed since starting. */ + + alignas(16) ALfloat PrevSamples[MAX_INPUT_CHANNELS][MAX_PRE_SAMPLES]; + + InterpState ResampleState; + + struct { + DirectParams Params[MAX_INPUT_CHANNELS]; + + ALfloat (*Buffer)[BUFFERSIZE]; + ALsizei Channels; + } Direct; + + struct { + SendParams Params[MAX_INPUT_CHANNELS]; + + ALfloat (*Buffer)[BUFFERSIZE]; + ALsizei Channels; + } Send[]; +} ALvoice; + typedef const ALfloat* (*ResamplerFunc)(const InterpState *state, const ALfloat *restrict src, ALuint frac, ALint increment, -- cgit v1.2.3 From ecfa1dcb6ffb79c74c0f6629f395c7619a6a3add Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 19 Mar 2017 13:48:40 -0700 Subject: Don't defer source state or offset changes --- Alc/ALc.c | 35 +++------------------------------ OpenAL32/Include/alMain.h | 8 +------- OpenAL32/Include/alSource.h | 4 ---- OpenAL32/alSource.c | 48 ++++++++++++--------------------------------- OpenAL32/alState.c | 12 ++++++------ 5 files changed, 22 insertions(+), 85 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 7513d7b5..f275871e 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -1679,9 +1679,9 @@ extern inline ALint GetChannelIndex(const enum Channel names[MAX_OUTPUT_CHANNELS * does *NOT* stop mixing, but rather prevents certain property changes from * taking effect. */ -void ALCcontext_DeferUpdates(ALCcontext *context, ALenum type) +void ALCcontext_DeferUpdates(ALCcontext *context) { - ATOMIC_STORE_SEQ(&context->DeferUpdates, type); + ATOMIC_STORE_SEQ(&context->DeferUpdates, AL_TRUE); } /* ALCcontext_ProcessUpdates @@ -1690,13 +1690,9 @@ void ALCcontext_DeferUpdates(ALCcontext *context, ALenum type) */ void ALCcontext_ProcessUpdates(ALCcontext *context) { - ALCdevice *device = context->Device; - ReadLock(&context->PropLock); if(ATOMIC_EXCHANGE_SEQ(ALenum, &context->DeferUpdates, AL_FALSE)) { - ALsizei pos; - /* Tell the mixer to stop applying updates, then wait for any active * updating to finish, before providing updates. */ @@ -1706,31 +1702,6 @@ void ALCcontext_ProcessUpdates(ALCcontext *context) UpdateListenerProps(context); UpdateAllEffectSlotProps(context); - - LockUIntMapRead(&context->SourceMap); - V0(device->Backend,lock)(); - for(pos = 0;pos < context->VoiceCount;pos++) - { - ALvoice *voice = context->Voices[pos]; - ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire); - if(source && source->OffsetType != AL_NONE) - { - WriteLock(&source->queue_lock); - ApplyOffset(source, voice); - WriteUnlock(&source->queue_lock); - } - } - for(pos = 0;pos < context->SourceMap.size;pos++) - { - ALsource *source = context->SourceMap.values[pos]; - ALenum new_state = source->new_state; - source->new_state = AL_NONE; - if(new_state) - SetSourceState(source, context, new_state); - } - V0(device->Backend,unlock)(); - UnlockUIntMapRead(&context->SourceMap); - UpdateAllSourceProps(context); /* Now with all updates declared, let the mixer continue applying them @@ -2819,7 +2790,7 @@ ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *context) alcSetError(NULL, ALC_INVALID_CONTEXT); else { - ALCcontext_DeferUpdates(context, DeferAllowPlay); + ALCcontext_DeferUpdates(context); ALCcontext_DecRef(context); } } diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index ac89adf8..2182d3f0 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -879,15 +879,9 @@ void AppendCaptureDeviceList(const ALCchar *name); void ALCdevice_Lock(ALCdevice *device); void ALCdevice_Unlock(ALCdevice *device); -void ALCcontext_DeferUpdates(ALCcontext *context, ALenum type); +void ALCcontext_DeferUpdates(ALCcontext *context); void ALCcontext_ProcessUpdates(ALCcontext *context); -enum { - DeferOff = AL_FALSE, - DeferAll, - DeferAllowPlay -}; - typedef struct { #ifdef HAVE_FENV_H diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 1dd835c4..284d5cbe 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -142,7 +142,6 @@ typedef struct ALsource { /** Source state (initial, playing, paused, or stopped) */ ATOMIC(ALenum) state; - ALenum new_state; /** Source Buffer Queue head. */ RWLock queue_lock; @@ -174,9 +173,6 @@ inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) { return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); } void UpdateAllSourceProps(ALCcontext *context); -ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); -ALboolean ApplyOffset(ALsource *Source, ALvoice *voice); - ALvoid ReleaseALSources(ALCcontext *Context); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index c4cdf16e..540821eb 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -54,6 +54,8 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALui static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime); static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context); static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALuint *frac); +static void SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); +static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice); typedef enum SourceProp { srcPitch = AL_PITCH, @@ -543,7 +545,7 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p Source->OffsetType = prop; Source->Offset = *values; - if(SourceShouldUpdate(Source, Context)) + if(IsPlayingOrPaused(Source)) { ALvoice *voice; @@ -749,7 +751,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->OffsetType = prop; Source->Offset = *values; - if(SourceShouldUpdate(Source, Context)) + if(IsPlayingOrPaused(Source)) { ALvoice *voice; @@ -2354,7 +2356,6 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) { source = LookupSource(context, sources[i]); ATOMIC_STORE(&source->state, AL_STOPPED, almemory_order_relaxed); - source->new_state = AL_NONE; } ALCdevice_Unlock(device); goto done; @@ -2371,21 +2372,10 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) AllocateVoices(context, newcount, device->NumAuxSends); } - if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll) - { - for(i = 0;i < n;i++) - { - source = LookupSource(context, sources[i]); - source->new_state = AL_PLAYING; - } - } - else + for(i = 0;i < n;i++) { - for(i = 0;i < n;i++) - { - source = LookupSource(context, sources[i]); - SetSourceState(source, context, AL_PLAYING); - } + source = LookupSource(context, sources[i]); + SetSourceState(source, context, AL_PLAYING); } ALCdevice_Unlock(device); @@ -2417,21 +2407,10 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) } ALCdevice_Lock(context->Device); - if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) - { - for(i = 0;i < n;i++) - { - source = LookupSource(context, sources[i]); - source->new_state = AL_PAUSED; - } - } - else + for(i = 0;i < n;i++) { - for(i = 0;i < n;i++) - { - source = LookupSource(context, sources[i]); - SetSourceState(source, context, AL_PAUSED); - } + source = LookupSource(context, sources[i]); + SetSourceState(source, context, AL_PAUSED); } ALCdevice_Unlock(context->Device); @@ -2466,7 +2445,6 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - source->new_state = AL_NONE; SetSourceState(source, context, AL_STOPPED); } ALCdevice_Unlock(context->Device); @@ -2502,7 +2480,6 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - source->new_state = AL_NONE; SetSourceState(source, context, AL_INITIAL); } ALCdevice_Unlock(context->Device); @@ -2810,7 +2787,6 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) Source->OffsetType = AL_NONE; Source->SourceType = AL_UNDETERMINED; ATOMIC_INIT(&Source->state, AL_INITIAL); - Source->new_state = AL_NONE; ATOMIC_INIT(&Source->queue, NULL); @@ -2979,7 +2955,7 @@ void UpdateAllSourceProps(ALCcontext *context) * * Sets the source's new play state given its current state. */ -ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) +static void SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) { ALCdevice *device = Context->Device; ALvoice *voice; @@ -3372,7 +3348,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte * Apply the stored playback offset to the Source. This function will update * the number of buffers "played" given the stored offset. */ -ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) +static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) { ALbufferlistitem *BufferList; const ALbuffer *Buffer; diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c index e633a86b..eddd2999 100644 --- a/OpenAL32/alState.c +++ b/OpenAL32/alState.c @@ -152,7 +152,7 @@ AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll) + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) value = AL_TRUE; break; @@ -198,7 +198,7 @@ AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll) + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) value = (ALdouble)AL_TRUE; break; @@ -243,7 +243,7 @@ AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll) + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) value = (ALfloat)AL_TRUE; break; @@ -288,7 +288,7 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll) + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) value = (ALint)AL_TRUE; break; @@ -333,7 +333,7 @@ AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname) break; case AL_DEFERRED_UPDATES_SOFT: - if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire) == DeferAll) + if(ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire)) value = (ALint64SOFT)AL_TRUE; break; @@ -671,7 +671,7 @@ AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void) context = GetContextRef(); if(!context) return; - ALCcontext_DeferUpdates(context, DeferAll); + ALCcontext_DeferUpdates(context); ALCcontext_DecRef(context); } -- cgit v1.2.3 From cdfe0d8f5af871258f1f58493e9659148659cacb Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 20 Mar 2017 21:25:39 -0700 Subject: Use an atomic flag to test if a source needs to update --- Alc/ALc.c | 2 +- OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index f275871e..f830a602 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2254,7 +2254,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) } } - source->NeedsUpdate = AL_TRUE; + ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release); /* Clear any pre-existing source property structs, in case the * number of auxiliary sends changed. Playing (or paused) sources diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 284d5cbe..5b1e2547 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -149,7 +149,7 @@ typedef struct ALsource { ATOMIC(ALboolean) looping; - ALenum NeedsUpdate; + ATOMIC_FLAG PropsClean; ATOMIC(struct ALsourceProps*) Update; ATOMIC(struct ALsourceProps*) FreeList; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index fef00e5a..e32bb5c8 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -421,7 +421,7 @@ static ALint Int64ValsByProp(ALenum prop) if(SourceShouldUpdate(Source, Context)) \ UpdateSourceProps(Source, device->NumAuxSends); \ else \ - Source->NeedsUpdate = AL_TRUE; \ + ATOMIC_FLAG_CLEAR(&Source->PropsClean, almemory_order_release); \ } while(0) static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp prop, const ALfloat *values) @@ -2429,7 +2429,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) break; } - source->NeedsUpdate = AL_FALSE; + 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 @@ -2948,7 +2948,10 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) ATOMIC_INIT(&Source->looping, AL_FALSE); - Source->NeedsUpdate = AL_TRUE; + /* No way to do an 'init' here, so just test+set with relaxed ordering and + * ignore the test. + */ + ATOMIC_FLAG_TEST_AND_SET(&Source->PropsClean, almemory_order_relaxed); ATOMIC_INIT(&Source->Update, NULL); ATOMIC_INIT(&Source->FreeList, NULL); @@ -3098,11 +3101,8 @@ void UpdateAllSourceProps(ALCcontext *context) { ALvoice *voice = context->Voices[pos]; ALsource *source = ATOMIC_LOAD(&voice->Source, almemory_order_acquire); - if(source != NULL && source->NeedsUpdate) - { - source->NeedsUpdate = AL_FALSE; + if(source != NULL && ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acq_rel)) UpdateSourceProps(source, num_sends); - } } } -- cgit v1.2.3 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. --- Alc/ALc.c | 57 +++++++++++++++++++++++-------------- Alc/ALu.c | 43 ++++++++++++++++++++++------ OpenAL32/Include/alSource.h | 57 ------------------------------------- OpenAL32/Include/alu.h | 61 ++++++++++++++++++++++++++++++++++++++-- OpenAL32/alSource.c | 68 +++++++++++++++++---------------------------- 5 files changed, 154 insertions(+), 132 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALc.c b/Alc/ALc.c index 7c6956ad..a352cacd 100644 --- a/Alc/ALc.c +++ b/Alc/ALc.c @@ -2232,7 +2232,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) for(pos = 0;pos < context->SourceMap.size;pos++) { ALsource *source = context->SourceMap.values[pos]; - struct ALsourceProps *props; if(old_sends != device->NumAuxSends) { @@ -2262,26 +2261,28 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) } ATOMIC_FLAG_CLEAR(&source->PropsClean, almemory_order_release); + } + AllocateVoices(context, context->MaxVoices, old_sends); + for(pos = 0;pos < context->VoiceCount;pos++) + { + ALvoice *voice = context->Voices[pos]; + struct ALvoiceProps *props; - /* Clear any pre-existing source property structs, in case the - * number of auxiliary sends changed. Playing (or paused) sources - * will have updates respecified in UpdateAllSourceProps. + /* Clear any pre-existing voice property structs, in case the + * number of auxiliary sends changed. Active sources will have + * updates respecified in UpdateAllSourceProps. */ - props = ATOMIC_EXCHANGE_PTR_SEQ(&source->Update, NULL); + props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_relaxed); al_free(props); - props = ATOMIC_EXCHANGE_PTR(&source->FreeList, NULL, almemory_order_relaxed); + props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed); while(props) { - struct ALsourceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + struct ALvoiceProps *next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); al_free(props); props = next; } - } - AllocateVoices(context, context->MaxVoices, old_sends); - for(pos = 0;pos < context->VoiceCount;pos++) - { - ALvoice *voice = context->Voices[pos]; + if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == NULL) continue; @@ -2527,6 +2528,7 @@ static void FreeContext(ALCcontext *context) struct ALeffectslotArray *auxslots; struct ALlistenerProps *lprops; size_t count; + ALsizei i; TRACE("%p\n", context); @@ -2549,6 +2551,8 @@ static void FreeContext(ALCcontext *context) } ResetUIntMap(&context->EffectSlotMap); + for(i = 0;i < context->VoiceCount;i++) + DeinitVoice(context->Voices[i]); al_free(context->Voices); context->Voices = NULL; context->VoiceCount = 0; @@ -2706,7 +2710,7 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) { ALCdevice *device = context->Device; ALsizei num_sends = device->NumAuxSends; - struct ALsourceProps *props; + struct ALvoiceProps *props; size_t sizeof_props; size_t sizeof_voice; ALvoice **voices; @@ -2721,7 +2725,7 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) * property set (including the dynamically-sized Send[] array) in one * chunk. */ - sizeof_props = RoundUp(offsetof(struct ALsourceProps, Send[num_sends]), 16); + sizeof_props = RoundUp(offsetof(struct ALvoiceProps, Send[num_sends]), 16); sizeof_voice = RoundUp(offsetof(ALvoice, Send[num_sends]), 16); size = sizeof(ALvoice*) + sizeof_voice + sizeof_props; @@ -2730,7 +2734,7 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) * paired together. */ voice = (ALvoice*)((char*)voices + RoundUp(num_voices*sizeof(ALvoice*), 16)); - props = (struct ALsourceProps*)((char*)voice + sizeof_voice); + props = (struct ALvoiceProps*)((char*)voice + sizeof_voice); if(context->Voices) { @@ -2738,17 +2742,18 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) for(;v < v_count;v++) { ALsizei s_count = mini(old_sends, num_sends); + ALvoice *old_voice = context->Voices[v]; ALsizei i; /* Copy the old voice data and source property set to the new * storage. */ - *voice = *(context->Voices[v]); + *voice = *old_voice; for(i = 0;i < s_count;i++) - voice->Send[i] = context->Voices[v]->Send[i]; - *props = *(context->Voices[v]->Props); + voice->Send[i] = old_voice->Send[i]; + *props = *(old_voice->Props); for(i = 0;i < s_count;i++) - props->Send[i] = context->Voices[v]->Props->Send[i]; + props->Send[i] = old_voice->Props->Send[i]; /* Set this voice's property set pointer and voice reference. */ voice->Props = props; @@ -2756,17 +2761,27 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends) /* Increment pointers to the next storage space. */ voice = (ALvoice*)((char*)props + sizeof_props); - props = (struct ALsourceProps*)((char*)voice + sizeof_voice); + props = (struct ALvoiceProps*)((char*)voice + sizeof_voice); } + /* Deinit any left over voices that weren't copied over to the new + * array. NOTE: If this does anything, v equals num_voices and + * num_voices is less than VoiceCount, so the following loop won't do + * anything. + */ + for(;v < context->VoiceCount;v++) + DeinitVoice(context->Voices[v]); } /* Finish setting the voices' property set pointers and references. */ for(;v < num_voices;v++) { + ATOMIC_INIT(&voice->Update, NULL); + ATOMIC_INIT(&voice->FreeList, NULL); + voice->Props = props; voices[v] = voice; voice = (ALvoice*)((char*)props + sizeof_props); - props = (struct ALsourceProps*)((char*)voice + sizeof_voice); + props = (struct ALvoiceProps*)((char*)voice + sizeof_voice); } al_free(context->Voices); diff --git a/Alc/ALu.c b/Alc/ALu.c index 89689fba..4a4709b0 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -100,6 +100,31 @@ const aluMatrixf IdentityMatrixf = {{ }}; +void DeinitVoice(ALvoice *voice) +{ + struct ALvoiceProps *props; + size_t count = 0; + + props = ATOMIC_EXCHANGE_PTR_SEQ(&voice->Update, NULL); + if(props) al_free(props); + + props = ATOMIC_EXCHANGE_PTR(&voice->FreeList, NULL, almemory_order_relaxed); + while(props) + { + struct ALvoiceProps *next; + next = ATOMIC_LOAD(&props->next, almemory_order_relaxed); + al_free(props); + props = next; + ++count; + } + /* This is excessively spammy if it traces every voice destruction, so just + * warn if it was unexpectedly large. + */ + if(count > 3) + WARN("Freed "SZFMT" voice property objects\n", count); +} + + static inline HrtfDirectMixerFunc SelectHrtfMixer(void) { #ifdef HAVE_NEON @@ -324,7 +349,7 @@ static ALboolean CalcEffectSlotParams(ALeffectslot *slot, ALCdevice *device) } -static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f, 0.0f } @@ -749,7 +774,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * } } -static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) +static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *props, const ALbuffer *ALBuffer, const ALCcontext *ALContext) { const ALCdevice *Device = ALContext->Device; const ALlistener *Listener = ALContext->Listener; @@ -1247,24 +1272,24 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro } } -static void CalcSourceParams(ALvoice *voice, ALsource *source, ALCcontext *context, ALboolean force) +static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean force) { const ALbufferlistitem *BufferListItem; - struct ALsourceProps *props; + struct ALvoiceProps *props; - props = ATOMIC_EXCHANGE_PTR(&source->Update, NULL, almemory_order_acq_rel); + props = ATOMIC_EXCHANGE_PTR(&voice->Update, NULL, almemory_order_acq_rel); if(!props && !force) return; if(props) { memcpy(voice->Props, props, - offsetof(struct ALsourceProps, Send[context->Device->NumAuxSends]) + offsetof(struct ALvoiceProps, Send[context->Device->NumAuxSends]) ); - ATOMIC_REPLACE_HEAD(struct ALsourceProps*, &source->FreeList, props); + ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props); } - BufferListItem = ATOMIC_LOAD(&source->queue, almemory_order_relaxed); + BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); while(BufferListItem != NULL) { const ALbuffer *buffer; @@ -1299,7 +1324,7 @@ static void UpdateContextSources(ALCcontext *ctx, const struct ALeffectslotArray for(;voice != voice_end;++voice) { source = ATOMIC_LOAD(&(*voice)->Source, almemory_order_acquire); - if(source) CalcSourceParams(*voice, source, ctx, force); + if(source) CalcSourceParams(*voice, ctx, force); } } IncrementRef(&ctx->UpdateCount); 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 From de62ab97e912525f20272153f6a4c896e833839d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 18 Apr 2017 00:58:33 -0700 Subject: Store the source queue head in the voice to signify looping This removes the need to access a couple more source fields in the mixer, and also makes the looping and queue fields non-atomic. --- Alc/mixer.c | 21 ++-- OpenAL32/Include/alSource.h | 5 +- OpenAL32/Include/alu.h | 11 +- OpenAL32/alSource.c | 279 +++++++++++++++++++++----------------------- 4 files changed, 153 insertions(+), 163 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/mixer.c b/Alc/mixer.c index 90f3e05e..8996499d 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -268,6 +268,7 @@ static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei SamplesToDo) { ALbufferlistitem *BufferListItem; + ALbufferlistitem *BufferLoopItem; ALsizei NumChannels, SampleSize; ResamplerFunc Resample; ALsizei DataPosInt; @@ -278,16 +279,15 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei ALsizei OutPos; ALsizei IrSize; bool isplaying; - bool islooping; ALsizei chan; ALsizei send; /* Get source info */ isplaying = true; /* Will only be called while playing. */ - islooping = ATOMIC_LOAD(&Source->looping, almemory_order_acquire); - DataPosInt = ATOMIC_LOAD(&voice->position, almemory_order_relaxed); + DataPosInt = ATOMIC_LOAD(&voice->position, almemory_order_acquire); DataPosFrac = ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed); BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); + BufferLoopItem = ATOMIC_LOAD(&voice->loop_buffer, almemory_order_relaxed); NumChannels = voice->NumChannels; SampleSize = voice->SampleSize; increment = voice->Step; @@ -345,9 +345,9 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei Data += chan*SampleSize; /* If current pos is beyond the loop range, do not loop */ - if(!islooping || DataPosInt >= ALBuffer->LoopEnd) + if(!BufferLoopItem || DataPosInt >= ALBuffer->LoopEnd) { - islooping = false; + BufferLoopItem = NULL; /* Load what's left to play from the source buffer, and * clear the rest of the temp buffer */ @@ -415,8 +415,8 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei } } tmpiter = tmpiter->next; - if(!tmpiter && islooping) - tmpiter = ATOMIC_LOAD(&Source->queue, almemory_order_acquire); + if(!tmpiter && BufferLoopItem) + tmpiter = BufferLoopItem; else if(!tmpiter) { SilenceSamples(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize); @@ -602,7 +602,7 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei break; } - if(islooping && Source->SourceType == AL_STATIC) + if(BufferLoopItem && Source->SourceType == AL_STATIC) { assert(LoopEnd > LoopStart); DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart; @@ -614,12 +614,9 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei if(!(BufferListItem=BufferListItem->next)) { - if(islooping) - BufferListItem = ATOMIC_LOAD(&Source->queue, almemory_order_acquire); - else + if(!(BufferListItem=BufferLoopItem)) { isplaying = false; - BufferListItem = NULL; DataPosInt = 0; DataPosFrac = 0; break; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 265a8f47..795ddf24 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -40,6 +40,7 @@ typedef struct ALsource { ALfloat Direction[3]; ALfloat Orientation[2][3]; ALboolean HeadRelative; + ALboolean Looping; enum DistanceModel DistanceModel; ALboolean DirectChannels; @@ -91,9 +92,7 @@ typedef struct ALsource { /** Source Buffer Queue head. */ RWLock queue_lock; - ATOMIC(ALbufferlistitem*) queue; - - ATOMIC(ALboolean) looping; + ALbufferlistitem *queue; ATOMIC_FLAG PropsClean; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index a2ba4fae..96c7d4c4 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -219,9 +219,6 @@ typedef struct ALvoice { ATOMIC(struct ALsource*) Source; ATOMIC(bool) Playing; - /* Current buffer queue item being played. */ - ATOMIC(struct ALbufferlistitem*) current_buffer; - /** * Source offset in samples, relative to the currently playing buffer, NOT * the whole queue, and the fractional (fixed-point) offset to the next @@ -230,6 +227,14 @@ typedef struct ALvoice { ATOMIC(ALuint) position; ATOMIC(ALsizei) position_fraction; + /* Current buffer queue item being played. */ + ATOMIC(struct ALbufferlistitem*) current_buffer; + + /* Buffer queue item to loop to at end of queue (will be NULL for non- + * looping voices). + */ + ATOMIC(struct ALbufferlistitem*) loop_buffer; + /** * Number of channels and bytes-per-sample for the attached source's * buffer(s). diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index dcf9821e..236188cf 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -674,7 +674,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p ALfilter *filter = NULL; ALeffectslot *slot = NULL; ALbufferlistitem *oldlist; - ALbufferlistitem *newlist; ALfloat fvals[6]; switch(prop) @@ -700,15 +699,24 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); WriteLock(&Source->queue_lock); - ATOMIC_STORE_SEQ(&Source->looping, *values); - if(ATOMIC_LOAD(&Source->state, almemory_order_acquire) == AL_PLAYING) + Source->Looping = (ALboolean)*values; + if(IsPlayingOrPaused(Source)) { - /* If the source is playing, wait for the current mix to finish - * to ensure it isn't currently looping back or reaching the - * end. - */ - while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) - althrd_yield(); + ALvoice *voice = GetSourceVoice(Source, Context); + if(voice) + { + if(Source->Looping) + ATOMIC_STORE(&voice->loop_buffer, Source->queue, almemory_order_release); + else + ATOMIC_STORE(&voice->loop_buffer, NULL, almemory_order_release); + + /* If the source is playing, wait for the current mix to finish + * to ensure it isn't currently looping back or reaching the + * end. + */ + while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1)) + althrd_yield(); + } } WriteUnlock(&Source->queue_lock); return AL_TRUE; @@ -732,24 +740,25 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } } + oldlist = Source->queue; if(buffer != NULL) { /* Add the selected buffer to a one-item queue */ - newlist = al_calloc(DEF_ALIGN, sizeof(ALbufferlistitem)); + ALbufferlistitem *newlist = al_calloc(DEF_ALIGN, sizeof(ALbufferlistitem)); newlist->buffer = buffer; newlist->next = NULL; IncrementRef(&buffer->ref); /* Source is now Static */ Source->SourceType = AL_STATIC; + Source->queue = newlist; } else { /* Source is now Undetermined */ Source->SourceType = AL_UNDETERMINED; - newlist = NULL; + Source->queue = NULL; } - oldlist = ATOMIC_EXCHANGE_PTR_SEQ(&Source->queue, newlist); WriteUnlock(&Source->queue_lock); UnlockBuffersRead(device); @@ -1153,7 +1162,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SEC_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) + if(!(BufferList=Source->queue)) *values = 0; else { @@ -1270,13 +1279,12 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_LOOPING: - *values = ATOMIC_LOAD_SEQ(&Source->looping); + *values = Source->Looping; return AL_TRUE; case AL_BUFFER: ReadLock(&Source->queue_lock); - BufferList = (Source->SourceType == AL_STATIC) ? - ATOMIC_LOAD_SEQ(&Source->queue) : NULL; + BufferList = (Source->SourceType == AL_STATIC) ? Source->queue : NULL; *values = (BufferList && BufferList->buffer) ? BufferList->buffer->id : 0; ReadUnlock(&Source->queue_lock); return AL_TRUE; @@ -1287,7 +1295,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BYTE_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) + if(!(BufferList=Source->queue)) *values = 0; else { @@ -1326,7 +1334,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_SAMPLE_LENGTH_SOFT: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) + if(!(BufferList=Source->queue)) *values = 0; else { @@ -1342,7 +1350,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFERS_QUEUED: ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD_SEQ(&Source->queue))) + if(!(BufferList=Source->queue)) *values = 0; else { @@ -1357,7 +1365,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFERS_PROCESSED: ReadLock(&Source->queue_lock); - if(ATOMIC_LOAD_SEQ(&Source->looping) || Source->SourceType != AL_STREAMING) + if(Source->Looping || Source->SourceType != AL_STREAMING) { /* Buffers on a looping source are in a perpetual state of * PENDING, so don't report any as PROCESSED */ @@ -1365,7 +1373,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } else { - const ALbufferlistitem *BufferList = ATOMIC_LOAD_SEQ(&Source->queue); + const ALbufferlistitem *BufferList = Source->queue; const ALbufferlistitem *Current = NULL; ALsizei played = 0; ALvoice *voice; @@ -2409,7 +2417,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) /* Check that there is a queue containing at least one valid, non zero * length Buffer. */ - BufferList = ATOMIC_LOAD_SEQ(&source->queue); + BufferList = source->queue; while(BufferList) { if((buffer=BufferList->buffer) != NULL && buffer->SampleLen > 0) @@ -2478,6 +2486,10 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) /* A source that's not playing or paused has any offset applied when it * starts playing. */ + if(source->Looping) + ATOMIC_STORE(&voice->loop_buffer, source->queue, almemory_order_relaxed); + else + ATOMIC_STORE(&voice->loop_buffer, NULL, almemory_order_relaxed); ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed); ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_relaxed); @@ -2705,7 +2717,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu } /* Check for a valid Buffer, for its frequency and format */ - BufferList = ATOMIC_LOAD_SEQ(&source->queue); + BufferList = source->queue; while(BufferList) { if(BufferList->buffer) @@ -2788,11 +2800,10 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu /* Source is now streaming */ source->SourceType = AL_STREAMING; - BufferList = NULL; - if(!ATOMIC_COMPARE_EXCHANGE_PTR_STRONG_SEQ(&source->queue, &BufferList, - BufferListStart)) + if(!(BufferList=source->queue)) + source->queue = BufferListStart; + else { - /* Queue head is not NULL, append to the end of the queue */ while(BufferList->next != NULL) BufferList = BufferList->next; BufferList->next = BufferListStart; @@ -2828,7 +2839,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint if(nb == 0) goto done; WriteLock(&source->queue_lock); - if(ATOMIC_LOAD_SEQ(&source->looping) || source->SourceType != AL_STREAMING) + if(source->Looping || source->SourceType != AL_STREAMING) { WriteUnlock(&source->queue_lock); /* Trying to unqueue buffers on a looping or non-streaming source. */ @@ -2836,7 +2847,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } /* Find the new buffer queue head */ - OldTail = ATOMIC_LOAD_SEQ(&source->queue); + OldTail = source->queue; Current = NULL; if((voice=GetSourceVoice(source, context)) != NULL) Current = ATOMIC_LOAD_SEQ(&voice->current_buffer); @@ -2859,23 +2870,9 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } /* Swap it, and cut the new head from the old. */ - OldHead = ATOMIC_EXCHANGE_PTR_SEQ(&source->queue, OldTail->next); - if(OldTail->next) - { - ALCdevice *device = context->Device; - uint count; - - /* Once the active mix (if any) is done, it's safe to cut the old tail - * from the new head. - */ - if(((count=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1)) - { - while(count == ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)) - althrd_yield(); - } - ATOMIC_THREAD_FENCE(almemory_order_acq_rel); - OldTail->next = NULL; - } + OldHead = source->queue; + source->queue = OldTail->next; + OldTail->next = NULL; WriteUnlock(&source->queue_lock); while(OldHead != NULL) @@ -2940,6 +2937,9 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) Source->AirAbsorptionFactor = 0.0f; Source->RoomRolloffFactor = 0.0f; Source->DopplerFactor = 1.0f; + Source->HeadRelative = AL_FALSE; + Source->Looping = AL_FALSE; + Source->DistanceModel = DefaultDistanceModel; Source->DirectChannels = AL_FALSE; Source->StereoPan[0] = DEG2RAD( 30.0f); @@ -2947,8 +2947,6 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) Source->Radius = 0.0f; - Source->DistanceModel = DefaultDistanceModel; - Source->Direct.Gain = 1.0f; Source->Direct.GainHF = 1.0f; Source->Direct.HFReference = LOWPASSFREQREF; @@ -2970,9 +2968,7 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) Source->SourceType = AL_UNDETERMINED; ATOMIC_INIT(&Source->state, AL_INITIAL); - ATOMIC_INIT(&Source->queue, NULL); - - ATOMIC_INIT(&Source->looping, AL_FALSE); + Source->queue = NULL; /* No way to do an 'init' here, so just test+set with relaxed ordering and * ignore the test. @@ -2985,7 +2981,7 @@ static void DeinitSource(ALsource *source, ALsizei num_sends) ALbufferlistitem *BufferList; ALsizei i; - BufferList = ATOMIC_EXCHANGE_PTR_SEQ(&source->queue, NULL); + BufferList = source->queue; while(BufferList != NULL) { ALbufferlistitem *next = BufferList->next; @@ -2994,6 +2990,7 @@ static void DeinitSource(ALsource *source, ALsizei num_sends) al_free(BufferList); BufferList = next; } + source->queue = NULL; if(source->Send) { @@ -3118,14 +3115,12 @@ void UpdateAllSourceProps(ALCcontext *context) static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime) { ALCdevice *device = context->Device; - const ALbufferlistitem *BufferList; const ALbufferlistitem *Current; ALuint64 readPos; ALuint refcount; ALvoice *voice; ReadLock(&Source->queue_lock); - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); do { Current = NULL; readPos = 0; @@ -3147,6 +3142,7 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALui if(voice) { + const ALbufferlistitem *BufferList = Source->queue; while(BufferList && BufferList != Current) { if(BufferList->buffer) @@ -3168,7 +3164,6 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALui static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint64 *clocktime) { ALCdevice *device = context->Device; - const ALbufferlistitem *BufferList; const ALbufferlistitem *Current; ALuint64 readPos; ALuint refcount; @@ -3176,7 +3171,6 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint ALvoice *voice; ReadLock(&Source->queue_lock); - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); do { Current = NULL; readPos = 0; @@ -3199,27 +3193,28 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint offset = 0.0; if(voice) { - const ALbuffer *Buffer = NULL; + const ALbufferlistitem *BufferList = Source->queue; + const ALbuffer *BufferFmt = NULL; while(BufferList && BufferList != Current) { const ALbuffer *buffer = BufferList->buffer; if(buffer != NULL) { - if(!Buffer) Buffer = buffer; + if(!BufferFmt) BufferFmt = buffer; readPos += (ALuint64)buffer->SampleLen << FRACTIONBITS; } BufferList = BufferList->next; } - while(BufferList && !Buffer) + while(BufferList && !BufferFmt) { - Buffer = BufferList->buffer; + BufferFmt = BufferList->buffer; BufferList = BufferList->next; } - assert(Buffer != NULL); + assert(BufferFmt != NULL); offset = (ALdouble)readPos / (ALdouble)FRACTIONONE / - (ALdouble)Buffer->Frequency; + (ALdouble)BufferFmt->Frequency; } ReadUnlock(&Source->queue_lock); @@ -3235,21 +3230,14 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context) { ALCdevice *device = context->Device; - const ALbufferlistitem *BufferList; const ALbufferlistitem *Current; - const ALbuffer *Buffer = NULL; - ALboolean readFin = AL_FALSE; ALuint readPos; ALsizei readPosFrac; - ALuint totalBufferLen; - ALboolean looping; ALuint refcount; ALdouble offset; ALvoice *voice; ReadLock(&Source->queue_lock); - BufferList = ATOMIC_LOAD(&Source->queue, almemory_order_relaxed); - looping = ATOMIC_LOAD(&Source->looping, almemory_order_relaxed); do { Current = NULL; readPos = readPosFrac = 0; @@ -3266,72 +3254,75 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte ATOMIC_THREAD_FENCE(almemory_order_acquire); } while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed)); - if(!voice) + offset = 0.0; + if(voice) { - ReadUnlock(&Source->queue_lock); - return 0.0; - } + const ALbufferlistitem *BufferList = Source->queue; + const ALbuffer *BufferFmt = NULL; + ALboolean readFin = AL_FALSE; + ALuint totalBufferLen = 0; - totalBufferLen = 0; - while(BufferList != NULL) - { - const ALbuffer *buffer; - readFin = readFin || (BufferList == Current); - if((buffer=BufferList->buffer) != NULL) + while(BufferList != NULL) { - if(!Buffer) Buffer = buffer; - totalBufferLen += buffer->SampleLen; - if(!readFin) readPos += buffer->SampleLen; + const ALbuffer *buffer; + readFin = readFin || (BufferList == Current); + if((buffer=BufferList->buffer) != NULL) + { + if(!BufferFmt) BufferFmt = buffer; + totalBufferLen += buffer->SampleLen; + if(!readFin) readPos += buffer->SampleLen; + } + BufferList = BufferList->next; } - BufferList = BufferList->next; - } - assert(Buffer != NULL); + assert(BufferFmt != NULL); - if(looping) - readPos %= totalBufferLen; - else - { - /* Wrap back to 0 */ - if(readPos >= totalBufferLen) - readPos = readPosFrac = 0; - } + if(Source->Looping) + readPos %= totalBufferLen; + else + { + /* Wrap back to 0 */ + if(readPos >= totalBufferLen) + readPos = readPosFrac = 0; + } - offset = 0.0; - switch(name) - { - case AL_SEC_OFFSET: - offset = (readPos + (ALdouble)readPosFrac/FRACTIONONE)/Buffer->Frequency; - break; + offset = 0.0; + switch(name) + { + case AL_SEC_OFFSET: + offset = (readPos + (ALdouble)readPosFrac/FRACTIONONE) / BufferFmt->Frequency; + break; - case AL_SAMPLE_OFFSET: - offset = readPos + (ALdouble)readPosFrac/FRACTIONONE; - break; + case AL_SAMPLE_OFFSET: + offset = readPos + (ALdouble)readPosFrac/FRACTIONONE; + break; - case AL_BYTE_OFFSET: - if(Buffer->OriginalType == UserFmtIMA4) - { - ALsizei align = (Buffer->OriginalAlign-1)/2 + 4; - ALuint BlockSize = align * ChannelsFromFmt(Buffer->FmtChannels); - ALuint FrameBlockSize = Buffer->OriginalAlign; + case AL_BYTE_OFFSET: + if(BufferFmt->OriginalType == UserFmtIMA4) + { + ALsizei align = (BufferFmt->OriginalAlign-1)/2 + 4; + ALuint BlockSize = align * ChannelsFromFmt(BufferFmt->FmtChannels); + ALuint FrameBlockSize = BufferFmt->OriginalAlign; - /* Round down to nearest ADPCM block */ - offset = (ALdouble)(readPos / FrameBlockSize * BlockSize); - } - else if(Buffer->OriginalType == UserFmtMSADPCM) - { - ALsizei align = (Buffer->OriginalAlign-2)/2 + 7; - ALuint BlockSize = align * ChannelsFromFmt(Buffer->FmtChannels); - ALuint FrameBlockSize = Buffer->OriginalAlign; + /* Round down to nearest ADPCM block */ + offset = (ALdouble)(readPos / FrameBlockSize * BlockSize); + } + else if(BufferFmt->OriginalType == UserFmtMSADPCM) + { + ALsizei align = (BufferFmt->OriginalAlign-2)/2 + 7; + ALuint BlockSize = align * ChannelsFromFmt(BufferFmt->FmtChannels); + ALuint FrameBlockSize = BufferFmt->OriginalAlign; - /* Round down to nearest ADPCM block */ - offset = (ALdouble)(readPos / FrameBlockSize * BlockSize); - } - else - { - ALuint FrameSize = FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType); - offset = (ALdouble)(readPos * FrameSize); - } - break; + /* Round down to nearest ADPCM block */ + offset = (ALdouble)(readPos / FrameBlockSize * BlockSize); + } + else + { + ALuint FrameSize = FrameSizeFromUserFmt(BufferFmt->OriginalChannels, + BufferFmt->OriginalType); + offset = (ALdouble)(readPos * FrameSize); + } + break; + } } ReadUnlock(&Source->queue_lock); @@ -3357,7 +3348,7 @@ static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) return AL_FALSE; totalBufferLen = 0; - BufferList = ATOMIC_LOAD_SEQ(&Source->queue); + BufferList = Source->queue; while(BufferList && totalBufferLen <= offset) { Buffer = BufferList->buffer; @@ -3366,9 +3357,9 @@ static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) if(bufferLen > offset-totalBufferLen) { /* Offset is in this buffer */ - ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); ATOMIC_STORE(&voice->position, offset - totalBufferLen, almemory_order_relaxed); - ATOMIC_STORE(&voice->position_fraction, frac, almemory_order_release); + ATOMIC_STORE(&voice->position_fraction, frac, almemory_order_relaxed); + ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_release); return AL_TRUE; } @@ -3390,22 +3381,19 @@ static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) */ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALsizei *frac) { - const ALbuffer *Buffer = NULL; + const ALbuffer *BufferFmt = NULL; const ALbufferlistitem *BufferList; ALdouble dbloff, dblfrac; /* Find the first valid Buffer in the Queue */ - BufferList = ATOMIC_LOAD_SEQ(&Source->queue); + BufferList = Source->queue; while(BufferList) { - if(BufferList->buffer) - { - Buffer = BufferList->buffer; + if((BufferFmt=BufferList->buffer) != NULL) break; - } BufferList = BufferList->next; } - if(!Buffer) + if(!BufferFmt) { Source->OffsetType = AL_NONE; Source->Offset = 0.0; @@ -3417,20 +3405,21 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALsizei *frac case AL_BYTE_OFFSET: /* Determine the ByteOffset (and ensure it is block aligned) */ *offset = (ALuint)Source->Offset; - if(Buffer->OriginalType == UserFmtIMA4) + if(BufferFmt->OriginalType == UserFmtIMA4) { - ALsizei align = (Buffer->OriginalAlign-1)/2 + 4; - *offset /= align * ChannelsFromUserFmt(Buffer->OriginalChannels); - *offset *= Buffer->OriginalAlign; + ALsizei align = (BufferFmt->OriginalAlign-1)/2 + 4; + *offset /= align * ChannelsFromUserFmt(BufferFmt->OriginalChannels); + *offset *= BufferFmt->OriginalAlign; } - else if(Buffer->OriginalType == UserFmtMSADPCM) + else if(BufferFmt->OriginalType == UserFmtMSADPCM) { - ALsizei align = (Buffer->OriginalAlign-2)/2 + 7; - *offset /= align * ChannelsFromUserFmt(Buffer->OriginalChannels); - *offset *= Buffer->OriginalAlign; + ALsizei align = (BufferFmt->OriginalAlign-2)/2 + 7; + *offset /= align * ChannelsFromUserFmt(BufferFmt->OriginalChannels); + *offset *= BufferFmt->OriginalAlign; } else - *offset /= FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType); + *offset /= FrameSizeFromUserFmt(BufferFmt->OriginalChannels, + BufferFmt->OriginalType); *frac = 0; break; @@ -3441,7 +3430,7 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALsizei *frac break; case AL_SEC_OFFSET: - dblfrac = modf(Source->Offset*Buffer->Frequency, &dbloff); + dblfrac = modf(Source->Offset*BufferFmt->Frequency, &dbloff); *offset = (ALuint)mind(dbloff, UINT_MAX); *frac = (ALsizei)mind(dblfrac*FRACTIONONE, FRACTIONONE-1.0); break; -- cgit v1.2.3 From 5dcbb8db38bb9aa88d3be45cf84f2e7d993acdd0 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 19 Apr 2017 19:54:17 -0700 Subject: Make the buffer list next pointer atomic --- Alc/ALu.c | 2 +- Alc/mixer.c | 8 +++--- OpenAL32/Include/alSource.h | 3 ++- OpenAL32/alSource.c | 59 ++++++++++++++++++++++++--------------------- 4 files changed, 40 insertions(+), 32 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index da3ae9d5..065371d1 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1301,7 +1301,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc CalcNonAttnSourceParams(voice, voice->Props, buffer, context); break; } - BufferListItem = BufferListItem->next; + BufferListItem = ATOMIC_LOAD(&BufferListItem->next, almemory_order_acquire); } } diff --git a/Alc/mixer.c b/Alc/mixer.c index 8996499d..a2a56dbc 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -414,7 +414,7 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei SrcDataSize += DataSize; } } - tmpiter = tmpiter->next; + tmpiter = ATOMIC_LOAD(&tmpiter->next, almemory_order_acquire); if(!tmpiter && BufferLoopItem) tmpiter = BufferLoopItem; else if(!tmpiter) @@ -612,9 +612,11 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei if(DataSize > DataPosInt) break; - if(!(BufferListItem=BufferListItem->next)) + BufferListItem = ATOMIC_LOAD(&BufferListItem->next, almemory_order_acquire); + if(!BufferListItem) { - if(!(BufferListItem=BufferLoopItem)) + BufferListItem = BufferLoopItem; + if(!BufferListItem) { isplaying = false; DataPosInt = 0; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 795ddf24..d069abcd 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -5,6 +5,7 @@ #include "alMain.h" #include "alu.h" #include "hrtf.h" +#include "atomic.h" #define MAX_SENDS 16 #define DEFAULT_SENDS 2 @@ -19,7 +20,7 @@ struct ALsource; typedef struct ALbufferlistitem { struct ALbuffer *buffer; - struct ALbufferlistitem *volatile next; + ATOMIC(struct ALbufferlistitem*) next; } ALbufferlistitem; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 9fc22205..0da513aa 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -746,7 +746,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p /* Add the selected buffer to a one-item queue */ ALbufferlistitem *newlist = al_calloc(DEF_ALIGN, sizeof(ALbufferlistitem)); newlist->buffer = buffer; - newlist->next = NULL; + ATOMIC_INIT(&newlist->next, NULL); IncrementRef(&buffer->ref); /* Source is now Static */ @@ -766,7 +766,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p while(oldlist != NULL) { ALbufferlistitem *temp = oldlist; - oldlist = temp->next; + oldlist = ATOMIC_LOAD(&temp->next, almemory_order_relaxed); if(temp->buffer) DecrementRef(&temp->buffer->ref); @@ -1175,7 +1175,8 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p freq = buffer->Frequency; length += buffer->SampleLen; } - } while((BufferList=BufferList->next) != NULL); + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); + } while(BufferList != NULL); *values = (ALdouble)length / (ALdouble)freq; } ReadUnlock(&Source->queue_lock); @@ -1326,7 +1327,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p length += buffer->SampleLen / sample_align * byte_align; } - } while((BufferList=BufferList->next) != NULL); + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); + } while(BufferList != NULL); *values = length; } ReadUnlock(&Source->queue_lock); @@ -1342,7 +1344,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p do { ALbuffer *buffer = BufferList->buffer; if(buffer) length += buffer->SampleLen; - } while((BufferList=BufferList->next) != NULL); + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); + } while(BufferList != NULL); *values = length; } ReadUnlock(&Source->queue_lock); @@ -1357,7 +1360,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p ALsizei count = 0; do { ++count; - } while((BufferList=BufferList->next) != NULL); + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); + } while(BufferList != NULL); *values = count; } ReadUnlock(&Source->queue_lock); @@ -1386,7 +1390,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p while(BufferList && BufferList != Current) { played++; - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } *values = played; } @@ -2422,7 +2426,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) { if((buffer=BufferList->buffer) != NULL && buffer->SampleLen > 0) break; - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } /* If there's nothing to play, go right to stopped. */ @@ -2725,7 +2729,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferFmt = BufferList->buffer; break; } - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } LockBuffersRead(device); @@ -2747,11 +2751,12 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu } else { - BufferList->next = al_calloc(DEF_ALIGN, sizeof(ALbufferlistitem)); - BufferList = BufferList->next; + ALbufferlistitem *item = al_calloc(DEF_ALIGN, sizeof(ALbufferlistitem)); + ATOMIC_STORE(&BufferList->next, item, almemory_order_relaxed); + BufferList = item; } BufferList->buffer = buffer; - BufferList->next = NULL; + ATOMIC_INIT(&BufferList->next, NULL); if(!buffer) continue; /* Hold a read lock on each buffer being queued while checking all @@ -2774,7 +2779,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu * each buffer we had. */ while(BufferListStart) { - ALbufferlistitem *next = BufferListStart->next; + ALbufferlistitem *next = ATOMIC_LOAD(&BufferListStart->next, + almemory_order_relaxed); if((buffer=BufferListStart->buffer) != NULL) { DecrementRef(&buffer->ref); @@ -2793,7 +2799,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu { ALbuffer *buffer = BufferList->buffer; if(buffer) ReadUnlock(&buffer->lock); - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } UnlockBuffersRead(device); @@ -2805,8 +2811,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu else { while(BufferList->next != NULL) - BufferList = BufferList->next; - BufferList->next = BufferListStart; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); + ATOMIC_STORE(&BufferList->next, BufferListStart, almemory_order_release); } WriteUnlock(&source->queue_lock); @@ -2857,7 +2863,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint { for(i = 1;i < nb;i++) { - ALbufferlistitem *next = OldTail->next; + ALbufferlistitem *next = ATOMIC_LOAD(&OldTail->next, almemory_order_relaxed); if(!next || next == Current) break; OldTail = next; } @@ -2871,13 +2877,12 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint /* Swap it, and cut the new head from the old. */ OldHead = source->queue; - source->queue = OldTail->next; - OldTail->next = NULL; + source->queue = ATOMIC_EXCHANGE_PTR(&OldTail->next, NULL, almemory_order_acq_rel); WriteUnlock(&source->queue_lock); while(OldHead != NULL) { - ALbufferlistitem *next = OldHead->next; + ALbufferlistitem *next = ATOMIC_LOAD(&OldHead->next, almemory_order_relaxed); ALbuffer *buffer = OldHead->buffer; if(!buffer) @@ -2984,7 +2989,7 @@ static void DeinitSource(ALsource *source, ALsizei num_sends) BufferList = source->queue; while(BufferList != NULL) { - ALbufferlistitem *next = BufferList->next; + ALbufferlistitem *next = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); if(BufferList->buffer != NULL) DecrementRef(&BufferList->buffer->ref); al_free(BufferList); @@ -3147,7 +3152,7 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALui { if(BufferList->buffer) readPos += (ALuint64)BufferList->buffer->SampleLen << 32; - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } readPos = minu64(readPos, U64(0x7fffffffffffffff)); } @@ -3203,13 +3208,13 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint if(!BufferFmt) BufferFmt = buffer; readPos += (ALuint64)buffer->SampleLen << FRACTIONBITS; } - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } while(BufferList && !BufferFmt) { BufferFmt = BufferList->buffer; - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } assert(BufferFmt != NULL); @@ -3272,7 +3277,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte totalBufferLen += buffer->SampleLen; if(!readFin) readPos += buffer->SampleLen; } - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } assert(BufferFmt != NULL); @@ -3365,7 +3370,7 @@ static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) totalBufferLen += bufferLen; - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } /* Offset is out of range of the queue */ @@ -3391,7 +3396,7 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALsizei *frac { if((BufferFmt=BufferList->buffer) != NULL) break; - BufferList = BufferList->next; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } if(!BufferFmt) { -- cgit v1.2.3 From 26b49c54afb9868115e495098ce69f2d2487c932 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 21 Apr 2017 00:06:40 -0700 Subject: Store the resampler as part of the source --- Alc/ALu.c | 2 ++ Alc/mixer.c | 4 +--- OpenAL32/Include/alSource.h | 1 + OpenAL32/Include/alu.h | 30 ++++++++++++++++-------------- OpenAL32/alSource.c | 2 ++ 5 files changed, 22 insertions(+), 17 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 065371d1..baa94148 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -455,6 +455,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *p else voice->Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1); BsincPrepare(voice->Step, &voice->ResampleState.bsinc); + voice->Resampler = SelectResampler(props->Resampler); /* Calculate gains */ DryGain = clampf(SourceVolume, MinVolume, MaxVolume); @@ -1095,6 +1096,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop else voice->Step = maxi(fastf2i(Pitch*FRACTIONONE + 0.5f), 1); BsincPrepare(voice->Step, &voice->ResampleState.bsinc); + voice->Resampler = SelectResampler(props->Resampler); voice->Flags &= ~(VOICE_IS_HRTF | VOICE_HAS_NFC); if(Device->Render_Mode == HrtfRender) diff --git a/Alc/mixer.c b/Alc/mixer.c index b1d014a7..2070f859 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -53,7 +53,6 @@ enum Resampler ResamplerDefault = LinearResampler; static MixerFunc MixSamples = Mix_C; static HrtfMixerFunc MixHrtfSamples = MixHrtf_C; -static ResamplerFunc ResampleSamples = Resample_point32_C; MixerFunc SelectMixer(void) { @@ -177,7 +176,6 @@ void aluInitMixer(void) MixHrtfSamples = SelectHrtfMixer(); MixSamples = SelectMixer(); - ResampleSamples = SelectResampler(ResamplerDefault); } @@ -295,7 +293,7 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei IrSize = (Device->HrtfHandle ? Device->HrtfHandle->irSize : 0); Resample = ((increment == FRACTIONONE && DataPosFrac == 0) ? - Resample_copy32_C : ResampleSamples); + Resample_copy32_C : voice->Resampler); Counter = (voice->Flags&VOICE_IS_MOVING) ? SamplesToDo : 0; OutPos = 0; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index d069abcd..f9cbc55b 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -43,6 +43,7 @@ typedef struct ALsource { ALboolean HeadRelative; ALboolean Looping; enum DistanceModel DistanceModel; + enum Resampler Resampler; ALboolean DirectChannels; ALboolean DryGainHFAuto; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 9b267d15..071ef3d2 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -40,6 +40,14 @@ struct ALvoice; struct ALeffectslot; +enum Resampler { + PointResampler, + LinearResampler, + FIR4Resampler, + BSincResampler, +}; +extern enum Resampler ResamplerDefault; + /* The number of distinct scale and phase intervals within the filter table. */ #define BSINC_SCALE_BITS 4 #define BSINC_SCALE_COUNT (1<HeadRelative = AL_FALSE; Source->Looping = AL_FALSE; Source->DistanceModel = DefaultDistanceModel; + Source->Resampler = ResamplerDefault; Source->DirectChannels = AL_FALSE; Source->StereoPan[0] = DEG2RAD( 30.0f); @@ -3054,6 +3055,7 @@ static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_send } props->HeadRelative = source->HeadRelative; props->DistanceModel = source->DistanceModel; + props->Resampler = source->Resampler; props->DirectChannels = source->DirectChannels; props->DryGainHFAuto = source->DryGainHFAuto; -- cgit v1.2.3 From b639bc99132015217ff173680e1a43f44fad2ce3 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 4 May 2017 12:17:50 -0700 Subject: Add a property to force source spatialization on or off --- Alc/ALu.c | 8 +++++--- OpenAL32/Include/alSource.h | 1 + OpenAL32/Include/alu.h | 7 +++++++ OpenAL32/alSource.c | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index e3160dab..9ce452e9 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1355,6 +1355,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc ATOMIC_REPLACE_HEAD(struct ALvoiceProps*, &voice->FreeList, props); } + props = voice->Props; BufferListItem = ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed); while(BufferListItem != NULL) @@ -1362,10 +1363,11 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, ALboolean forc const ALbuffer *buffer; if((buffer=BufferListItem->buffer) != NULL) { - if(buffer->FmtChannels == FmtMono) - CalcAttnSourceParams(voice, voice->Props, buffer, context); + if(props->SpatializeMode == SpatializeOn || + (props->SpatializeMode == SpatializeAuto && buffer->FmtChannels == FmtMono)) + CalcAttnSourceParams(voice, props, buffer, context); else - CalcNonAttnSourceParams(voice, voice->Props, buffer, context); + CalcNonAttnSourceParams(voice, props, buffer, context); break; } BufferListItem = ATOMIC_LOAD(&BufferListItem->next, almemory_order_acquire); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index f9cbc55b..7d2ff59a 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -45,6 +45,7 @@ typedef struct ALsource { enum DistanceModel DistanceModel; enum Resampler Resampler; ALboolean DirectChannels; + enum SpatializeMode Spatialize; ALboolean DryGainHFAuto; ALboolean WetGainAuto; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 168a754f..cccc9719 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -40,6 +40,12 @@ struct ALvoice; struct ALeffectslot; +enum SpatializeMode { + SpatializeOff, + SpatializeOn, + SpatializeAuto +}; + enum Resampler { PointResampler, LinearResampler, @@ -189,6 +195,7 @@ struct ALvoiceProps { enum DistanceModel DistanceModel; enum Resampler Resampler; ALboolean DirectChannels; + enum SpatializeMode SpatializeMode; ALboolean DryGainHFAuto; ALboolean WetGainAuto; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a1ba0ebc..9ef9a4eb 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -2984,6 +2984,7 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) Source->DistanceModel = DefaultDistanceModel; Source->Resampler = ResamplerDefault; Source->DirectChannels = AL_FALSE; + Source->Spatialize = SpatializeAuto; Source->StereoPan[0] = DEG2RAD( 30.0f); Source->StereoPan[1] = DEG2RAD(-30.0f); @@ -3093,6 +3094,7 @@ static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_send props->DistanceModel = source->DistanceModel; props->Resampler = source->Resampler; props->DirectChannels = source->DirectChannels; + props->SpatializeMode = source->Spatialize; props->DryGainHFAuto = source->DryGainHFAuto; props->WetGainAuto = source->WetGainAuto; -- cgit v1.2.3 From db6f14748c0fce4d43d2e2c27a4c2847638297d1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 5 May 2017 03:19:50 -0700 Subject: Rename RollOff to Rolloff --- Alc/ALu.c | 8 ++++---- OpenAL32/Include/alSource.h | 2 +- OpenAL32/Include/alu.h | 2 +- OpenAL32/alSource.c | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 9ce452e9..2817f982 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1074,7 +1074,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop { /* If the slot's auxiliary send auto is off, the data sent to the * effect slot is the same as the dry path, sans filter effects */ - RoomRolloff[i] = props->RollOffFactor; + RoomRolloff[i] = props->RolloffFactor; DecayDistance[i] = 0.0f; RoomAirAbsorption[i] = AIRABSORBGAINHF; } @@ -1133,7 +1133,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop case InverseDistance: if(props->RefDistance > 0.0f) { - ALfloat dist = lerp(props->RefDistance, ClampedDist, props->RollOffFactor); + ALfloat dist = lerp(props->RefDistance, ClampedDist, props->RolloffFactor); if(dist > 0.0f) Attenuation = props->RefDistance / dist; for(i = 0;i < NumSends;i++) { @@ -1151,7 +1151,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop case LinearDistance: if(props->MaxDistance != props->RefDistance) { - Attenuation = props->RollOffFactor * (ClampedDist-props->RefDistance) / + Attenuation = props->RolloffFactor * (ClampedDist-props->RefDistance) / (props->MaxDistance-props->RefDistance); Attenuation = maxf(1.0f - Attenuation, 0.0f); for(i = 0;i < NumSends;i++) @@ -1171,7 +1171,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALvoiceProps *prop case ExponentDistance: if(ClampedDist > 0.0f && props->RefDistance > 0.0f) { - Attenuation = powf(ClampedDist/props->RefDistance, -props->RollOffFactor); + Attenuation = powf(ClampedDist/props->RefDistance, -props->RolloffFactor); for(i = 0;i < NumSends;i++) RoomAttenuation[i] = powf(ClampedDist/props->RefDistance, -RoomRolloff[i]); } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 7d2ff59a..03034ce8 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -35,7 +35,7 @@ typedef struct ALsource { ALfloat OuterAngle; ALfloat RefDistance; ALfloat MaxDistance; - ALfloat RollOffFactor; + ALfloat RolloffFactor; ALfloat Position[3]; ALfloat Velocity[3]; ALfloat Direction[3]; diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h index 5cd233b9..8e2fe1e9 100644 --- a/OpenAL32/Include/alu.h +++ b/OpenAL32/Include/alu.h @@ -186,7 +186,7 @@ struct ALvoiceProps { ALfloat OuterAngle; ALfloat RefDistance; ALfloat MaxDistance; - ALfloat RollOffFactor; + ALfloat RolloffFactor; ALfloat Position[3]; ALfloat Velocity[3]; ALfloat Direction[3]; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 6030bd3c..46f23a75 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -504,7 +504,7 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_ROLLOFF_FACTOR: CHECKVAL(*values >= 0.0f); - Source->RollOffFactor = *values; + Source->RolloffFactor = *values; DO_UPDATEPROPS(); return AL_TRUE; @@ -1143,7 +1143,7 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_ROLLOFF_FACTOR: - *values = Source->RollOffFactor; + *values = Source->RolloffFactor; return AL_TRUE; case AL_REFERENCE_DISTANCE: @@ -2988,7 +2988,7 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) Source->Orientation[1][2] = 0.0f; Source->RefDistance = 1.0f; Source->MaxDistance = FLT_MAX; - Source->RollOffFactor = 1.0f; + Source->RolloffFactor = 1.0f; Source->Gain = 1.0f; Source->MinGain = 0.0f; Source->MaxGain = 1.0f; @@ -3099,7 +3099,7 @@ static void UpdateSourceProps(ALsource *source, ALvoice *voice, ALsizei num_send props->OuterAngle = source->OuterAngle; props->RefDistance = source->RefDistance; props->MaxDistance = source->MaxDistance; - props->RollOffFactor = source->RollOffFactor; + props->RolloffFactor = source->RolloffFactor; for(i = 0;i < 3;i++) props->Position[i] = source->Position[i]; for(i = 0;i < 3;i++) -- cgit v1.2.3 From 30007263e5ffe1883d634081dcbfcc65dbf58cc4 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 15 Dec 2017 22:59:51 -0800 Subject: Allow storing multiple buffers in a ALbufferlistitem This will be to allow buffer layering, multiple buffers of the same format and sample rate that are mixed together prior to resampling, filtering, and panning. This will allow composing sounds from individual components that can be swapped around on different invocations (e.g. layer SoundA and SoundB on one instance and SoundA and SoundC on a different instance for a slightly different sound, then just SoundA for a third instance, and so on). The longest buffer within the list item determines the length of the list item. More work needs to be done to fully support it, namely the ability to specity multiple buffers to layer for static and streaming sources. Also the behavior of loop points for layered static sources should be worked out. Should also consider allowing each layer to have a sample offset. --- Alc/ALu.c | 2 +- Alc/mixer.c | 10 ++- OpenAL32/Include/alSource.h | 3 +- OpenAL32/alSource.c | 210 ++++++++++++++++++++++++++++++-------------- 4 files changed, 153 insertions(+), 72 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/ALu.c b/Alc/ALu.c index 0da610d1..5f0c556a 100644 --- a/Alc/ALu.c +++ b/Alc/ALu.c @@ -1450,7 +1450,7 @@ static void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force) while(BufferListItem != NULL) { const ALbuffer *buffer; - if((buffer=BufferListItem->buffer) != NULL) + if(BufferListItem->num_buffers >= 1 && (buffer=BufferListItem->buffers[0]) != NULL) { if(props->SpatializeMode == SpatializeOn || (props->SpatializeMode == SpatializeAuto && buffer->FmtChannels == FmtMono)) diff --git a/Alc/mixer.c b/Alc/mixer.c index c77488bc..37bdf6ac 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -362,9 +362,13 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei memcpy(SrcData, voice->PrevSamples[chan], MAX_PRE_SAMPLES*sizeof(ALfloat)); SrcDataSize = MAX_PRE_SAMPLES; + /* TODO: Handle multi-buffer items by adding them together in + * SrcData. Need to work out how to deal with looping (loop + * points). + */ if(isstatic) { - const ALbuffer *ALBuffer = BufferListItem->buffer; + const ALbuffer *ALBuffer = BufferListItem->buffers[0]; const ALubyte *Data = ALBuffer->data; ALsizei DataSize; @@ -421,7 +425,7 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei while(tmpiter && SrcBufferSize > SrcDataSize) { const ALbuffer *ALBuffer; - if((ALBuffer=tmpiter->buffer) != NULL) + if(tmpiter->num_buffers >= 1 && (ALBuffer=tmpiter->buffers[0]) != NULL) { const ALubyte *Data = ALBuffer->data; ALsizei DataSize = ALBuffer->SampleLen; @@ -637,7 +641,7 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei ALsizei LoopStart = 0; ALsizei LoopEnd = 0; - if((ALBuffer=BufferListItem->buffer) != NULL) + if(BufferListItem->num_buffers >= 1 && (ALBuffer=BufferListItem->buffers[0]) != NULL) { DataSize = ALBuffer->SampleLen; LoopStart = ALBuffer->LoopStart; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 03034ce8..970ea07c 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -19,8 +19,9 @@ struct ALsource; typedef struct ALbufferlistitem { - struct ALbuffer *buffer; ATOMIC(struct ALbufferlistitem*) next; + ALsizei num_buffers; + struct ALbuffer *buffers[]; } ALbufferlistitem; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index cc19a0c3..f4d82c68 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -774,9 +774,11 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p if(buffer != NULL) { /* Add the selected buffer to a one-item queue */ - ALbufferlistitem *newlist = al_calloc(DEF_ALIGN, sizeof(ALbufferlistitem)); - newlist->buffer = buffer; + ALbufferlistitem *newlist = al_calloc(DEF_ALIGN, + FAM_SIZE(ALbufferlistitem, buffers, 1)); ATOMIC_INIT(&newlist->next, NULL); + newlist->num_buffers = 1; + newlist->buffers[0] = buffer; IncrementRef(&buffer->ref); /* Source is now Static */ @@ -795,11 +797,15 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p /* Delete all elements in the previous queue */ while(oldlist != NULL) { + ALsizei i; ALbufferlistitem *temp = oldlist; oldlist = ATOMIC_LOAD(&temp->next, almemory_order_relaxed); - if(temp->buffer) - DecrementRef(&temp->buffer->ref); + for(i = 0;i < temp->num_buffers;i++) + { + if(temp->buffers[i]) + DecrementRef(&temp->buffers[i]->ref); + } al_free(temp); } return AL_TRUE; @@ -1219,12 +1225,18 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p ALint length = 0; ALsizei freq = 1; do { - ALbuffer *buffer = BufferList->buffer; - if(buffer && buffer->SampleLen > 0) + ALsizei max_len = 0; + ALsizei i; + for(i = 0;i < BufferList->num_buffers;i++) { - freq = buffer->Frequency; - length += buffer->SampleLen; + ALbuffer *buffer = BufferList->buffers[i]; + if(buffer && buffer->SampleLen > 0) + { + freq = buffer->Frequency; + max_len = maxi(max_len, buffer->SampleLen); + } } + length += max_len; BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } while(BufferList != NULL); *values = (ALdouble)length / (ALdouble)freq; @@ -1344,7 +1356,8 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_BUFFER: ReadLock(&Source->queue_lock); BufferList = (Source->SourceType == AL_STATIC) ? Source->queue : NULL; - *values = (BufferList && BufferList->buffer) ? BufferList->buffer->id : 0; + *values = (BufferList && BufferList->num_buffers >= 1 && BufferList->buffers[0]) ? + BufferList->buffers[0]->id : 0; ReadUnlock(&Source->queue_lock); return AL_TRUE; @@ -1360,31 +1373,38 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { ALint length = 0; do { - ALbuffer *buffer = BufferList->buffer; - if(buffer && buffer->SampleLen > 0) + ALsizei max_len = 0; + ALsizei i; + for(i = 0;i < BufferList->num_buffers;i++) { - ALuint byte_align, sample_align; - if(buffer->OriginalType == UserFmtIMA4) - { - ALsizei align = (buffer->OriginalAlign-1)/2 + 4; - byte_align = align * ChannelsFromFmt(buffer->FmtChannels); - sample_align = buffer->OriginalAlign; - } - else if(buffer->OriginalType == UserFmtMSADPCM) - { - ALsizei align = (buffer->OriginalAlign-2)/2 + 7; - byte_align = align * ChannelsFromFmt(buffer->FmtChannels); - sample_align = buffer->OriginalAlign; - } - else + ALbuffer *buffer = BufferList->buffers[i]; + if(buffer && buffer->SampleLen > 0) { - ALsizei align = buffer->OriginalAlign; - byte_align = align * ChannelsFromFmt(buffer->FmtChannels); - sample_align = buffer->OriginalAlign; + ALuint byte_align, sample_align; + if(buffer->OriginalType == UserFmtIMA4) + { + ALsizei align = (buffer->OriginalAlign-1)/2 + 4; + byte_align = align * ChannelsFromFmt(buffer->FmtChannels); + sample_align = buffer->OriginalAlign; + } + else if(buffer->OriginalType == UserFmtMSADPCM) + { + ALsizei align = (buffer->OriginalAlign-2)/2 + 7; + byte_align = align * ChannelsFromFmt(buffer->FmtChannels); + sample_align = buffer->OriginalAlign; + } + else + { + ALsizei align = buffer->OriginalAlign; + byte_align = align * ChannelsFromFmt(buffer->FmtChannels); + sample_align = buffer->OriginalAlign; + } + + max_len = maxi(max_len, buffer->SampleLen / sample_align * byte_align); } - - length += buffer->SampleLen / sample_align * byte_align; } + length += max_len; + BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } while(BufferList != NULL); *values = length; @@ -1400,8 +1420,14 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p { ALint length = 0; do { - ALbuffer *buffer = BufferList->buffer; - if(buffer) length += buffer->SampleLen; + ALsizei max_len = 0; + ALsizei i; + for(i = 0;i < BufferList->num_buffers;i++) + { + ALbuffer *buffer = BufferList->buffers[i]; + if(buffer) max_len = maxi(max_len, buffer->SampleLen); + } + length += max_len; BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } while(BufferList != NULL); *values = length; @@ -2503,8 +2529,13 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) BufferList = source->queue; while(BufferList) { - if((buffer=BufferList->buffer) != NULL && buffer->SampleLen > 0) - break; + ALsizei b; + for(b = 0;b < BufferList->num_buffers;b++) + { + buffer = BufferList->buffers[b]; + if(buffer && buffer->SampleLen > 0) break; + } + if(buffer && buffer->SampleLen > 0) break; BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } @@ -2804,11 +2835,12 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferList = source->queue; while(BufferList) { - if(BufferList->buffer) + for(i = 0;i < BufferList->num_buffers;i++) { - BufferFmt = BufferList->buffer; - break; + if((BufferFmt=BufferList->buffers[i]) != NULL) + break; } + if(BufferFmt) break; BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } @@ -2826,17 +2858,20 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu if(!BufferListStart) { - BufferListStart = al_calloc(DEF_ALIGN, sizeof(ALbufferlistitem)); + BufferListStart = al_calloc(DEF_ALIGN, + FAM_SIZE(ALbufferlistitem, buffers, 1)); BufferList = BufferListStart; } else { - ALbufferlistitem *item = al_calloc(DEF_ALIGN, sizeof(ALbufferlistitem)); + ALbufferlistitem *item = al_calloc(DEF_ALIGN, + FAM_SIZE(ALbufferlistitem, buffers, 1)); ATOMIC_STORE(&BufferList->next, item, almemory_order_relaxed); BufferList = item; } - BufferList->buffer = buffer; ATOMIC_INIT(&BufferList->next, NULL); + BufferList->num_buffers = 1; + BufferList->buffers[0] = buffer; if(!buffer) continue; /* Hold a read lock on each buffer being queued while checking all @@ -2861,10 +2896,13 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu { ALbufferlistitem *next = ATOMIC_LOAD(&BufferListStart->next, almemory_order_relaxed); - if((buffer=BufferListStart->buffer) != NULL) + for(i = 0;i < BufferListStart->num_buffers;i++) { - DecrementRef(&buffer->ref); - ReadUnlock(&buffer->lock); + if((buffer=BufferListStart->buffers[i]) != NULL) + { + DecrementRef(&buffer->ref); + ReadUnlock(&buffer->lock); + } } al_free(BufferListStart); BufferListStart = next; @@ -2877,8 +2915,11 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferList = BufferListStart; while(BufferList != NULL) { - ALbuffer *buffer = BufferList->buffer; - if(buffer) ReadUnlock(&buffer->lock); + for(i = 0;i < BufferList->num_buffers;i++) + { + ALbuffer *buffer = BufferList->buffers[i]; + if(buffer) ReadUnlock(&buffer->lock); + } BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } UnlockBuffersRead(device); @@ -2940,12 +2981,12 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint Current = ATOMIC_LOAD_SEQ(&voice->current_buffer); else if(ATOMIC_LOAD_SEQ(&source->state) == AL_INITIAL) Current = OldTail; - if(OldTail != Current) + if(OldTail != Current && OldTail->num_buffers == 1) { for(i = 1;i < nb;i++) { ALbufferlistitem *next = ATOMIC_LOAD(&OldTail->next, almemory_order_relaxed); - if(!next || next == Current) break; + if(!next || next == Current || next->num_buffers != 1) break; OldTail = next; } } @@ -2964,7 +3005,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint while(OldHead != NULL) { ALbufferlistitem *next = ATOMIC_LOAD(&OldHead->next, almemory_order_relaxed); - ALbuffer *buffer = OldHead->buffer; + ALbuffer *buffer = OldHead->buffers[0]; if(!buffer) *(buffers++) = 0; @@ -3073,8 +3114,11 @@ static void DeinitSource(ALsource *source, ALsizei num_sends) while(BufferList != NULL) { ALbufferlistitem *next = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); - if(BufferList->buffer != NULL) - DecrementRef(&BufferList->buffer->ref); + for(i = 0;i < BufferList->num_buffers;i++) + { + if(BufferList->buffers[i] != NULL) + DecrementRef(&BufferList->buffers[i]->ref); + } al_free(BufferList); BufferList = next; } @@ -3235,8 +3279,15 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALui const ALbufferlistitem *BufferList = Source->queue; while(BufferList && BufferList != Current) { - if(BufferList->buffer) - readPos += (ALuint64)BufferList->buffer->SampleLen << 32; + ALsizei max_len = 0; + ALsizei i; + + for(i = 0;i < BufferList->num_buffers;i++) + { + ALbuffer *buffer = BufferList->buffers[i]; + if(buffer) max_len = maxi(max_len, buffer->SampleLen); + } + readPos += (ALuint64)max_len << 32; BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); } @@ -3288,19 +3339,28 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint const ALbuffer *BufferFmt = NULL; while(BufferList && BufferList != Current) { - const ALbuffer *buffer = BufferList->buffer; - if(buffer != NULL) + ALsizei max_len = 0; + ALsizei i; + + for(i = 0;i < BufferList->num_buffers;i++) { - if(!BufferFmt) BufferFmt = buffer; - readPos += (ALuint64)buffer->SampleLen << FRACTIONBITS; + ALbuffer *buffer = BufferList->buffers[i]; + if(buffer) + { + if(!BufferFmt) BufferFmt = buffer; + max_len = maxi(max_len, buffer->SampleLen); + } } + readPos += (ALuint64)max_len << FRACTIONBITS; BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); } while(BufferList && !BufferFmt) { - BufferFmt = BufferList->buffer; + ALsizei i; + for(i = 0;i < BufferList->num_buffers && !BufferFmt;i++) + BufferFmt = BufferList->buffers[i]; BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); } @@ -3357,14 +3417,22 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte while(BufferList != NULL) { - const ALbuffer *buffer; + ALsizei max_len = 0; + ALsizei i; + readFin = readFin || (BufferList == Current); - if((buffer=BufferList->buffer) != NULL) + for(i = 0;i < BufferList->num_buffers;i++) { - if(!BufferFmt) BufferFmt = buffer; - totalBufferLen += buffer->SampleLen; - if(!readFin) readPos += buffer->SampleLen; + ALbuffer *buffer = BufferList->buffers[i]; + if(buffer) + { + if(!BufferFmt) BufferFmt = buffer; + max_len = maxi(max_len, buffer->SampleLen); + } } + totalBufferLen += max_len; + if(!readFin) readPos += max_len; + BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); } @@ -3432,7 +3500,6 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) { ALbufferlistitem *BufferList; - const ALbuffer *Buffer; ALuint bufferLen, totalBufferLen; ALuint offset = 0; ALsizei frac = 0; @@ -3445,8 +3512,15 @@ static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) BufferList = Source->queue; while(BufferList && totalBufferLen <= offset) { - Buffer = BufferList->buffer; - bufferLen = Buffer ? Buffer->SampleLen : 0; + ALsizei max_len = 0; + ALsizei i; + + for(i = 0;i < BufferList->num_buffers;i++) + { + ALbuffer *buffer = BufferList->buffers[i]; + if(buffer) max_len = maxi(max_len, buffer->SampleLen); + } + bufferLen = max_len; if(bufferLen > offset-totalBufferLen) { @@ -3483,8 +3557,10 @@ static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALsizei *frac BufferList = Source->queue; while(BufferList) { - if((BufferFmt=BufferList->buffer) != NULL) - break; + ALsizei i; + for(i = 0;i < BufferList->num_buffers && !BufferFmt;i++) + BufferFmt = BufferList->buffers[i]; + if(BufferFmt) break; BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); } -- cgit v1.2.3 From 38261a0f2a5a17683ce90cbe86267669717a6df0 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 27 Jan 2018 11:56:31 -0800 Subject: Make some more functions static where they're used --- OpenAL32/Include/alSource.h | 14 -------------- OpenAL32/alSource.c | 21 ++++++++++++++------- 2 files changed, 14 insertions(+), 21 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 970ea07c..b346e619 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -104,20 +104,6 @@ typedef struct ALsource { ALuint id; } ALsource; -inline void LockSourcesRead(ALCcontext *context) -{ LockUIntMapRead(&context->SourceMap); } -inline void UnlockSourcesRead(ALCcontext *context) -{ UnlockUIntMapRead(&context->SourceMap); } -inline void LockSourcesWrite(ALCcontext *context) -{ LockUIntMapWrite(&context->SourceMap); } -inline void UnlockSourcesWrite(ALCcontext *context) -{ UnlockUIntMapWrite(&context->SourceMap); } - -inline struct ALsource *LookupSource(ALCcontext *context, ALuint id) -{ return (struct ALsource*)LookupUIntMapKeyNoLock(&context->SourceMap, id); } -inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) -{ return (struct ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); } - void UpdateAllSourceProps(ALCcontext *context); ALvoid ReleaseALSources(ALCcontext *Context); diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 17d57852..b5f8a94f 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -40,13 +40,6 @@ #include "almalloc.h" -extern inline void LockSourcesRead(ALCcontext *context); -extern inline void UnlockSourcesRead(ALCcontext *context); -extern inline void LockSourcesWrite(ALCcontext *context); -extern inline void UnlockSourcesWrite(ALCcontext *context); -extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); -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, ALvoice *voice, ALsizei num_sends, ALCcontext *context); @@ -56,6 +49,20 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte static ALboolean GetSampleOffset(ALsource *Source, ALuint *offset, ALsizei *frac); static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice); +static inline void LockSourcesRead(ALCcontext *context) +{ LockUIntMapRead(&context->SourceMap); } +static inline void UnlockSourcesRead(ALCcontext *context) +{ UnlockUIntMapRead(&context->SourceMap); } +static inline void LockSourcesWrite(ALCcontext *context) +{ LockUIntMapWrite(&context->SourceMap); } +static inline void UnlockSourcesWrite(ALCcontext *context) +{ UnlockUIntMapWrite(&context->SourceMap); } + +static inline ALsource *LookupSource(ALCcontext *context, ALuint id) +{ return (ALsource*)LookupUIntMapKeyNoLock(&context->SourceMap, id); } +static inline ALsource *RemoveSource(ALCcontext *context, ALuint id) +{ return (ALsource*)RemoveUIntMapKeyNoLock(&context->SourceMap, id); } + static inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id) { BufferSubList *sublist; -- cgit v1.2.3 From 6a4a88f8f5c050b2a1e312984d072d806d7c387c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 1 Feb 2018 23:56:35 -0800 Subject: Store an index to a given source's voice For more efficient voice lookups when needed. --- OpenAL32/Include/alSource.h | 5 +++++ OpenAL32/alSource.c | 25 +++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index b346e619..2892a245 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -100,6 +100,11 @@ typedef struct ALsource { ATOMIC_FLAG PropsClean; + /* Index into the context's Voices array. Lazily updated, only checked and + * reset when looking up the voice. + */ + ALint VoiceIdx; + /** Self ID */ ALuint id; } ALsource; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index b3e98bc9..a7e5fc17 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -187,16 +187,16 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint *values); static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SourceProp prop, ALint64 *values); -static inline ALvoice *GetSourceVoice(const ALsource *source, const ALCcontext *context) +static inline ALvoice *GetSourceVoice(ALsource *source, ALCcontext *context) { - ALvoice **voice = context->Voices; - ALvoice **voice_end = voice + context->VoiceCount; - while(voice != voice_end) + ALint idx = source->VoiceIdx; + if(idx >= 0 && idx < context->VoiceCount) { - if(ATOMIC_LOAD(&(*voice)->Source, almemory_order_acquire) == source) - return *voice; - ++voice; + ALvoice *voice = context->Voices[idx]; + if(ATOMIC_LOAD(&voice->Source, almemory_order_acquire) == source) + return voice; } + source->VoiceIdx = -1; return NULL; } @@ -2567,6 +2567,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ALbufferlistitem *BufferList; ALbuffer *buffer = NULL; bool start_fading = false; + ALint vidx = -1; ALsizei s; source = LookupSource(context, sources[i]); @@ -2630,12 +2631,13 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) { if(ATOMIC_LOAD(&context->Voices[j]->Source, almemory_order_acquire) == NULL) { - voice = context->Voices[j]; + vidx = j; break; } } - if(voice == NULL) - voice = context->Voices[context->VoiceCount++]; + if(vidx == -1) + vidx = context->VoiceCount++; + voice = context->Voices[vidx]; ATOMIC_STORE(&voice->Playing, false, almemory_order_release); ATOMIC_FLAG_TEST_AND_SET(&source->PropsClean, almemory_order_acquire); @@ -2690,6 +2692,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&voice->Source, source, almemory_order_relaxed); ATOMIC_STORE(&voice->Playing, true, almemory_order_release); ATOMIC_STORE(&source->state, AL_PLAYING, almemory_order_release); + source->VoiceIdx = vidx; finish_play: WriteUnlock(&source->queue_lock); } @@ -3163,6 +3166,8 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) * ignore the test. */ ATOMIC_FLAG_TEST_AND_SET(&Source->PropsClean, almemory_order_relaxed); + + Source->VoiceIdx = -1; } static void DeinitSource(ALsource *source, ALsizei num_sends) -- cgit v1.2.3 From 28fa82378b54ecbf3fb04de2ba1c61d7b6d90503 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 2 Feb 2018 22:24:33 -0800 Subject: Remove the individual source queue and buffer locks They're inherently protected by the mutex for their respective lists. Should those mutexes be replaced by rwlocks the individual locks should also be reinstated, but they're unlikely to be unless a lot of contention starts happening in the read-only case. --- OpenAL32/Include/alBuffer.h | 2 -- OpenAL32/Include/alSource.h | 1 - OpenAL32/alBuffer.c | 68 +++++++++++------------------------ OpenAL32/alSource.c | 87 +++------------------------------------------ 4 files changed, 24 insertions(+), 134 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h index 8eedddbc..fbe3e6e5 100644 --- a/OpenAL32/Include/alBuffer.h +++ b/OpenAL32/Include/alBuffer.h @@ -102,8 +102,6 @@ typedef struct ALbuffer { /* Number of times buffer was attached to a source (deletion can only occur when 0) */ RefCount ref; - RWLock lock; - /* Self ID */ ALuint id; } ALbuffer; diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 2892a245..277cf7f2 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -95,7 +95,6 @@ typedef struct ALsource { ATOMIC(ALenum) state; /** Source Buffer Queue head. */ - RWLock queue_lock; ALbufferlistitem *queue; ATOMIC_FLAG PropsClean; diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 10f661f6..02071abf 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -192,11 +192,7 @@ AL_API void AL_APIENTRY alBufferStorageSOFT(ALuint buffer, ALenum format, const else if(UNLIKELY(DecomposeUserFormat(format, &srcchannels, &srctype) == AL_FALSE)) alSetError(context, AL_INVALID_ENUM, "Invalid format 0x%04x", format); else - { - WriteLock(&albuf->lock); LoadData(context, albuf, freq, size, srcchannels, srctype, data, flags); - WriteUnlock(&albuf->lock); - } UnlockBufferList(device); ALCcontext_DecRef(context); @@ -223,9 +219,7 @@ AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei buffer); else { - ALbitfieldSOFT unavailable; - WriteLock(&albuf->lock); - unavailable = (albuf->Access^access) & access; + ALbitfieldSOFT unavailable = (albuf->Access^access) & access; if(UNLIKELY(ReadRef(&albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT))) alSetError(context, AL_INVALID_OPERATION, "Mapping in-use buffer %u without persistent mapping", buffer); @@ -251,8 +245,6 @@ AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei albuf->MappedOffset = offset; albuf->MappedSize = length; } - - WriteUnlock(&albuf->lock); } UnlockBufferList(device); @@ -273,18 +265,13 @@ AL_API void AL_APIENTRY alUnmapBufferSOFT(ALuint buffer) LockBufferList(device); if((albuf=LookupBuffer(device, buffer)) == NULL) alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer); + else if(albuf->MappedAccess == 0) + alSetError(context, AL_INVALID_OPERATION, "Unmapping unmapped buffer %u", buffer); else { - WriteLock(&albuf->lock); - if(albuf->MappedAccess == 0) - alSetError(context, AL_INVALID_OPERATION, "Unmapping unmapped buffer %u", buffer); - else - { - albuf->MappedAccess = 0; - albuf->MappedOffset = 0; - albuf->MappedSize = 0; - } - WriteUnlock(&albuf->lock); + albuf->MappedAccess = 0; + albuf->MappedOffset = 0; + albuf->MappedSize = 0; } UnlockBufferList(device); @@ -304,27 +291,22 @@ AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, A LockBufferList(device); if(UNLIKELY((albuf=LookupBuffer(device, buffer)) == NULL)) alSetError(context, AL_INVALID_NAME, "Invalid buffer ID %u", buffer); + else if(UNLIKELY(!(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT))) + alSetError(context, AL_INVALID_OPERATION, + "Flushing buffer %u while not mapped for writing", buffer); + else if(UNLIKELY(offset < albuf->MappedOffset || + offset >= albuf->MappedOffset+albuf->MappedSize || + length <= 0 || length > albuf->MappedOffset+albuf->MappedSize-offset)) + alSetError(context, AL_INVALID_VALUE, "Flushing invalid range %d+%d on buffer %u", + offset, length, buffer); else { - WriteLock(&albuf->lock); - if(UNLIKELY(!(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT))) - alSetError(context, AL_INVALID_OPERATION, - "Flushing buffer %u while not mapped for writing", buffer); - else if(UNLIKELY(offset < albuf->MappedOffset || - offset >= albuf->MappedOffset+albuf->MappedSize || - length <= 0 || length > albuf->MappedOffset+albuf->MappedSize-offset)) - alSetError(context, AL_INVALID_VALUE, "Flushing invalid range %d+%d on buffer %u", - offset, length, buffer); - else - { - /* FIXME: Need to use some method of double-buffering for the mixer - * and app to hold separate memory, which can be safely transfered - * asynchronously. Currently we just say the app shouldn't write - * where OpenAL's reading, and hope for the best... - */ - ATOMIC_THREAD_FENCE(almemory_order_seq_cst); - } - WriteUnlock(&albuf->lock); + /* FIXME: Need to use some method of double-buffering for the mixer and + * app to hold separate memory, which can be safely transfered + * asynchronously. Currently we just say the app shouldn't write where + * OpenAL's reading, and hope for the best... + */ + ATOMIC_THREAD_FENCE(almemory_order_seq_cst); } UnlockBufferList(device); @@ -356,7 +338,6 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons ALsizei num_chans; void *dst; - WriteLock(&albuf->lock); unpack_align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign); align = SanitizeAlignment(srctype, unpack_align); if(UNLIKELY(align < 1)) @@ -412,8 +393,6 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons } } } - - WriteUnlock(&albuf->lock); } UnlockBufferList(device); @@ -638,7 +617,6 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val else switch(param) { case AL_LOOP_POINTS_SOFT: - WriteLock(&albuf->lock); if(UNLIKELY(ReadRef(&albuf->ref) != 0)) alSetError(context, AL_INVALID_OPERATION, "Modifying in-use buffer %u's loop points", buffer); @@ -650,7 +628,6 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *val albuf->LoopStart = values[0]; albuf->LoopEnd = values[1]; } - WriteUnlock(&albuf->lock); break; default: @@ -776,10 +753,8 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value break; case AL_SIZE: - ReadLock(&albuf->lock); *value = albuf->SampleLen * FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType); - ReadUnlock(&albuf->lock); break; case AL_UNPACK_BLOCK_ALIGNMENT_SOFT: @@ -857,10 +832,8 @@ AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values else switch(param) { case AL_LOOP_POINTS_SOFT: - ReadLock(&albuf->lock); values[0] = albuf->LoopStart; values[1] = albuf->LoopEnd; - ReadUnlock(&albuf->lock); break; default: @@ -1279,7 +1252,6 @@ static ALbuffer *AllocBuffer(ALCcontext *context) } memset(buffer, 0, sizeof(*buffer)); - RWLockInit(&buffer->lock); /* Add 1 to avoid buffer ID 0. */ buffer->id = ((lidx<<6) | slidx) + 1; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index a7e5fc17..7c978b98 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -651,14 +651,11 @@ static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SourceProp p voice = GetSourceVoice(Source, Context); if(voice) { - WriteLock(&Source->queue_lock); if(ApplyOffset(Source, voice) == AL_FALSE) { - WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid offset"); } - WriteUnlock(&Source->queue_lock); } ALCdevice_Unlock(Context->Device); } @@ -784,7 +781,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p case AL_LOOPING: CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - WriteLock(&Source->queue_lock); Source->Looping = (ALboolean)*values; if(IsPlayingOrPaused(Source)) { @@ -804,7 +800,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p althrd_yield(); } } - WriteUnlock(&Source->queue_lock); return AL_TRUE; case AL_BUFFER: @@ -816,11 +811,9 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p *values); } - WriteLock(&Source->queue_lock); if(buffer && buffer->MappedAccess != 0 && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT)) { - WriteUnlock(&Source->queue_lock); UnlockBufferList(device); SETERR_RETURN(Context, AL_INVALID_OPERATION, AL_FALSE, "Setting non-persistently mapped buffer %u", buffer->id); @@ -830,7 +823,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p ALenum state = GetSourceState(Source, GetSourceVoice(Source, Context)); if(state == AL_PLAYING || state == AL_PAUSED) { - WriteUnlock(&Source->queue_lock); UnlockBufferList(device); SETERR_RETURN(Context, AL_INVALID_OPERATION, AL_FALSE, "Setting buffer on playing or paused source %u", Source->id); @@ -858,7 +850,6 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p Source->SourceType = AL_UNDETERMINED; Source->queue = NULL; } - WriteUnlock(&Source->queue_lock); UnlockBufferList(device); /* Delete all elements in the previous queue */ @@ -893,15 +884,12 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p voice = GetSourceVoice(Source, Context); if(voice) { - WriteLock(&Source->queue_lock); if(ApplyOffset(Source, voice) == AL_FALSE) { - WriteUnlock(&Source->queue_lock); ALCdevice_Unlock(Context->Device); SETERR_RETURN(Context, AL_INVALID_VALUE, AL_FALSE, "Invalid source offset"); } - WriteUnlock(&Source->queue_lock); } ALCdevice_Unlock(Context->Device); } @@ -1298,7 +1286,6 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_SEC_LENGTH_SOFT: - ReadLock(&Source->queue_lock); if(!(BufferList=Source->queue)) *values = 0; else @@ -1322,7 +1309,6 @@ static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SourceProp p } while(BufferList != NULL); *values = (ALdouble)length / (ALdouble)freq; } - ReadUnlock(&Source->queue_lock); return AL_TRUE; case AL_SOURCE_RADIUS: @@ -1436,11 +1422,9 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_BUFFER: - ReadLock(&Source->queue_lock); BufferList = (Source->SourceType == AL_STATIC) ? Source->queue : NULL; *values = (BufferList && BufferList->num_buffers >= 1 && BufferList->buffers[0]) ? BufferList->buffers[0]->id : 0; - ReadUnlock(&Source->queue_lock); return AL_TRUE; case AL_SOURCE_STATE: @@ -1448,7 +1432,6 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p return AL_TRUE; case AL_BYTE_LENGTH_SOFT: - ReadLock(&Source->queue_lock); if(!(BufferList=Source->queue)) *values = 0; else @@ -1491,11 +1474,9 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } while(BufferList != NULL); *values = length; } - ReadUnlock(&Source->queue_lock); return AL_TRUE; case AL_SAMPLE_LENGTH_SOFT: - ReadLock(&Source->queue_lock); if(!(BufferList=Source->queue)) *values = 0; else @@ -1514,11 +1495,9 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } while(BufferList != NULL); *values = length; } - ReadUnlock(&Source->queue_lock); return AL_TRUE; case AL_BUFFERS_QUEUED: - ReadLock(&Source->queue_lock); if(!(BufferList=Source->queue)) *values = 0; else @@ -1530,11 +1509,9 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } while(BufferList != NULL); *values = count; } - ReadUnlock(&Source->queue_lock); return AL_TRUE; case AL_BUFFERS_PROCESSED: - ReadLock(&Source->queue_lock); if(Source->Looping || Source->SourceType != AL_STREAMING) { /* Buffers on a looping source are in a perpetual state of @@ -1561,7 +1538,6 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p } *values = played; } - ReadUnlock(&Source->queue_lock); return AL_TRUE; case AL_SOURCE_TYPE: @@ -2571,7 +2547,6 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ALsizei s; source = LookupSource(context, sources[i]); - WriteLock(&source->queue_lock); /* Check that there is a queue containing at least one valid, non zero * length Buffer. */ @@ -2598,7 +2573,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&source->state, AL_STOPPED, almemory_order_relaxed); source->OffsetType = AL_NONE; source->Offset = 0.0; - goto finish_play; + continue; } voice = GetSourceVoice(source, context); @@ -2610,14 +2585,14 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed); ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_release); - goto finish_play; + continue; case AL_PAUSED: assert(voice != NULL); /* A source that's paused simply resumes. */ ATOMIC_STORE(&voice->Playing, true, almemory_order_release); ATOMIC_STORE(&source->state, AL_PLAYING, almemory_order_release); - goto finish_play; + continue; default: break; @@ -2693,8 +2668,6 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&voice->Playing, true, almemory_order_release); ATOMIC_STORE(&source->state, AL_PLAYING, almemory_order_release); source->VoiceIdx = vidx; - finish_play: - WriteUnlock(&source->queue_lock); } ALCdevice_Unlock(device); @@ -2732,7 +2705,6 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - WriteLock(&source->queue_lock); if((voice=GetSourceVoice(source, context)) != NULL) { ATOMIC_STORE(&voice->Playing, false, almemory_order_release); @@ -2741,7 +2713,6 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) } if(GetSourceState(source, voice) == AL_PLAYING) ATOMIC_STORE(&source->state, AL_PAUSED, almemory_order_release); - WriteUnlock(&source->queue_lock); } ALCdevice_Unlock(device); @@ -2779,7 +2750,6 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - WriteLock(&source->queue_lock); if((voice=GetSourceVoice(source, context)) != NULL) { ATOMIC_STORE(&voice->Source, NULL, almemory_order_relaxed); @@ -2791,7 +2761,6 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&source->state, AL_STOPPED, almemory_order_relaxed); source->OffsetType = AL_NONE; source->Offset = 0.0; - WriteUnlock(&source->queue_lock); } ALCdevice_Unlock(device); @@ -2829,7 +2798,6 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - WriteLock(&source->queue_lock); if((voice=GetSourceVoice(source, context)) != NULL) { ATOMIC_STORE(&voice->Source, NULL, almemory_order_relaxed); @@ -2841,7 +2809,6 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&source->state, AL_INITIAL, almemory_order_relaxed); source->OffsetType = AL_NONE; source->Offset = 0.0; - WriteUnlock(&source->queue_lock); } ALCdevice_Unlock(device); @@ -2875,10 +2842,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu if((source=LookupSource(context, src)) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid source ID %u", src); - WriteLock(&source->queue_lock); if(source->SourceType == AL_STATIC) { - WriteUnlock(&source->queue_lock); /* Can't queue on a Static Source */ SETERR_GOTO(context, AL_INVALID_OPERATION, done, "Queueing onto static source %u", src); } @@ -2903,11 +2868,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu { ALbuffer *buffer = NULL; if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL) - { - WriteUnlock(&source->queue_lock); SETERR_GOTO(context, AL_INVALID_NAME, buffer_error, "Queueing invalid buffer ID %u", buffers[i]); - } if(!BufferListStart) { @@ -2927,18 +2889,11 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferList->buffers[0] = buffer; if(!buffer) continue; - /* Hold a read lock on each buffer being queued while checking all - * provided buffers. This is done so other threads don't see an extra - * reference on some buffers if this operation ends up failing. */ - ReadLock(&buffer->lock); IncrementRef(&buffer->ref); if(buffer->MappedAccess != 0 && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT)) - { - WriteUnlock(&source->queue_lock); SETERR_GOTO(context, AL_INVALID_OPERATION, buffer_error, "Queueing non-persistently mapped buffer %u", buffer->id); - } if(BufferFmt == NULL) BufferFmt = buffer; @@ -2946,7 +2901,6 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferFmt->FmtChannels != buffer->FmtChannels || BufferFmt->OriginalType != buffer->OriginalType) { - WriteUnlock(&source->queue_lock); alSetError(context, AL_INVALID_OPERATION, "Queueing buffer with mismatched format"); buffer_error: @@ -2959,10 +2913,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu for(i = 0;i < BufferListStart->num_buffers;i++) { if((buffer=BufferListStart->buffers[i]) != NULL) - { DecrementRef(&buffer->ref); - ReadUnlock(&buffer->lock); - } } al_free(BufferListStart); BufferListStart = next; @@ -2971,17 +2922,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu goto done; } } - /* All buffers good, unlock them now. */ - BufferList = BufferListStart; - while(BufferList != NULL) - { - for(i = 0;i < BufferList->num_buffers;i++) - { - ALbuffer *buffer = BufferList->buffers[i]; - if(buffer) ReadUnlock(&buffer->lock); - } - BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); - } + /* All buffers good. */ UnlockBufferList(device); /* Source is now streaming */ @@ -2996,7 +2937,6 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferList = next; ATOMIC_STORE(&BufferList->next, BufferListStart, almemory_order_release); } - WriteUnlock(&source->queue_lock); done: UnlockSourceList(context); @@ -3025,18 +2965,11 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint /* Nothing to unqueue. */ if(nb == 0) goto done; - WriteLock(&source->queue_lock); if(source->Looping) - { - WriteUnlock(&source->queue_lock); SETERR_GOTO(context, AL_INVALID_VALUE, done, "Unqueueing from looping source %u", src); - } if(source->SourceType != AL_STREAMING) - { - WriteUnlock(&source->queue_lock); SETERR_GOTO(context, AL_INVALID_VALUE, done, "Unqueueing from a non-streaming source %u", src); - } /* Find the new buffer queue head */ OldTail = source->queue; @@ -3055,15 +2988,11 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint } } if(i != nb) - { - WriteUnlock(&source->queue_lock); SETERR_GOTO(context, AL_INVALID_VALUE, done, "Unqueueing pending buffers"); - } /* Swap it, and cut the new head from the old. */ OldHead = source->queue; source->queue = ATOMIC_EXCHANGE_PTR(&OldTail->next, NULL, almemory_order_acq_rel); - WriteUnlock(&source->queue_lock); while(OldHead != NULL) { @@ -3092,8 +3021,6 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) { ALsizei i; - RWLockInit(&Source->queue_lock); - Source->InnerAngle = 360.0f; Source->OuterAngle = 360.0f; Source->Pitch = 1.0f; @@ -3319,7 +3246,6 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALui ALuint refcount; ALvoice *voice; - ReadLock(&Source->queue_lock); do { Current = NULL; readPos = 0; @@ -3359,7 +3285,6 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALui readPos = minu64(readPos, U64(0x7fffffffffffffff)); } - ReadUnlock(&Source->queue_lock); return (ALint64)readPos; } @@ -3377,7 +3302,6 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint ALdouble offset; ALvoice *voice; - ReadLock(&Source->queue_lock); do { Current = NULL; readPos = 0; @@ -3435,7 +3359,6 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint (ALdouble)BufferFmt->Frequency; } - ReadUnlock(&Source->queue_lock); return offset; } @@ -3455,7 +3378,6 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte ALdouble offset; ALvoice *voice; - ReadLock(&Source->queue_lock); do { Current = NULL; readPos = readPosFrac = 0; @@ -3552,7 +3474,6 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte } } - ReadUnlock(&Source->queue_lock); return offset; } -- cgit v1.2.3 From c7456affd541b7aef9ff252da51031e671c30734 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 24 Feb 2018 09:44:52 -0800 Subject: Don't make the source state atomic --- OpenAL32/Include/alSource.h | 2 +- OpenAL32/alSource.c | 39 ++++++++++++++++----------------------- 2 files changed, 17 insertions(+), 24 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 277cf7f2..5b9d66dc 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -92,7 +92,7 @@ typedef struct ALsource { ALint SourceType; /** Source state (initial, playing, paused, or stopped) */ - ATOMIC(ALenum) state; + ALenum state; /** Source Buffer Queue head. */ ALbufferlistitem *queue; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index bb3a62c3..d9a9da95 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -201,10 +201,7 @@ static inline ALvoice *GetSourceVoice(ALsource *source, ALCcontext *context) * not sync with the mixer voice. */ static inline bool IsPlayingOrPaused(ALsource *source) -{ - ALenum state = ATOMIC_LOAD(&source->state, almemory_order_acquire); - return state == AL_PLAYING || state == AL_PAUSED; -} +{ return source->state == AL_PLAYING || source->state == AL_PAUSED; } /** * Returns an updated source state using the matching voice's status (or lack @@ -212,15 +209,9 @@ static inline bool IsPlayingOrPaused(ALsource *source) */ static inline ALenum GetSourceState(ALsource *source, ALvoice *voice) { - if(!voice) - { - ALenum state = AL_PLAYING; - if(ATOMIC_COMPARE_EXCHANGE_STRONG(&source->state, &state, AL_STOPPED, - almemory_order_acq_rel, almemory_order_acquire)) - return AL_STOPPED; - return state; - } - return ATOMIC_LOAD(&source->state, almemory_order_acquire); + if(!voice && source->state == AL_PLAYING) + source->state = AL_STOPPED; + return source->state; } /** @@ -1439,7 +1430,7 @@ static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p if((voice=GetSourceVoice(Source, Context)) != NULL) Current = ATOMIC_LOAD_SEQ(&voice->current_buffer); - else if(ATOMIC_LOAD_SEQ(&Source->state) == AL_INITIAL) + else if(Source->state == AL_INITIAL) Current = BufferList; while(BufferList && BufferList != Current) @@ -2431,9 +2422,9 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { source = LookupSource(context, sources[i]); - ATOMIC_STORE(&source->state, AL_STOPPED, almemory_order_relaxed); source->OffsetType = AL_NONE; source->Offset = 0.0; + source->state = AL_STOPPED; } ALCdevice_Unlock(device); goto done; @@ -2484,11 +2475,13 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) * there's no need to look up its voice and clear the source. */ ALenum oldstate = GetSourceState(source, NULL); - ATOMIC_STORE(&source->state, AL_STOPPED, almemory_order_relaxed); source->OffsetType = AL_NONE; source->Offset = 0.0; if(oldstate != AL_STOPPED) + { + source->state = AL_STOPPED; SendStateChangeEvent(context, source->id, AL_STOPPED); + } continue; } @@ -2507,7 +2500,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) assert(voice != NULL); /* A source that's paused simply resumes. */ ATOMIC_STORE(&voice->Playing, true, almemory_order_release); - ATOMIC_STORE(&source->state, AL_PLAYING, almemory_order_release); + source->state = AL_PLAYING; SendStateChangeEvent(context, source->id, AL_PLAYING); continue; @@ -2579,7 +2572,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&voice->Source, source, almemory_order_relaxed); ATOMIC_STORE(&voice->Playing, true, almemory_order_release); - ATOMIC_STORE(&source->state, AL_PLAYING, almemory_order_release); + source->state = AL_PLAYING; source->VoiceIdx = vidx; SendStateChangeEvent(context, source->id, AL_PLAYING); @@ -2624,7 +2617,7 @@ AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) ATOMIC_STORE(&voice->Playing, false, almemory_order_release); if(GetSourceState(source, voice) == AL_PLAYING) { - ATOMIC_STORE(&source->state, AL_PAUSED, almemory_order_release); + source->state = AL_PAUSED; SendStateChangeEvent(context, source->id, AL_PAUSED); } } @@ -2674,7 +2667,7 @@ AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) oldstate = GetSourceState(source, voice); if(oldstate != AL_INITIAL && oldstate != AL_STOPPED) { - ATOMIC_STORE(&source->state, AL_STOPPED, almemory_order_relaxed); + source->state = AL_STOPPED; SendStateChangeEvent(context, source->id, AL_STOPPED); } source->OffsetType = AL_NONE; @@ -2724,7 +2717,7 @@ AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) } if(GetSourceState(source, voice) != AL_INITIAL) { - ATOMIC_STORE(&source->state, AL_INITIAL, almemory_order_relaxed); + source->state = AL_INITIAL; SendStateChangeEvent(context, source->id, AL_INITIAL); } source->OffsetType = AL_NONE; @@ -2896,7 +2889,7 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint Current = NULL; if((voice=GetSourceVoice(source, context)) != NULL) Current = ATOMIC_LOAD_SEQ(&voice->current_buffer); - else if(ATOMIC_LOAD_SEQ(&source->state) == AL_INITIAL) + else if(source->state == AL_INITIAL) Current = OldTail; if(OldTail != Current && OldTail->num_buffers == 1) { @@ -3005,7 +2998,7 @@ static void InitSourceParams(ALsource *Source, ALsizei num_sends) Source->Offset = 0.0; Source->OffsetType = AL_NONE; Source->SourceType = AL_UNDETERMINED; - ATOMIC_INIT(&Source->state, AL_INITIAL); + Source->state = AL_INITIAL; Source->queue = NULL; -- cgit v1.2.3 From 5aecce5a0dfb7784bfa3cc72642255872e0a4061 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 27 Mar 2018 08:27:16 -0700 Subject: Store the ALbufferlistitem's composited/max sample length --- Alc/mixvoice.c | 32 +++--------- OpenAL32/Include/alSource.h | 1 + OpenAL32/alSource.c | 122 ++++++++++++++++---------------------------- 3 files changed, 50 insertions(+), 105 deletions(-) (limited to 'OpenAL32/Include/alSource.h') diff --git a/Alc/mixvoice.c b/Alc/mixvoice.c index 8a382ffd..d01ca781 100644 --- a/Alc/mixvoice.c +++ b/Alc/mixvoice.c @@ -487,14 +487,12 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize while(tmpiter && SrcBufferSize > FilledAmt) { ALsizei SizeToDo = SrcBufferSize - FilledAmt; - ALsizei CompLen = 0; ALsizei i; for(i = 0;i < tmpiter->num_buffers;i++) { const ALbuffer *ALBuffer = tmpiter->buffers[i]; ALsizei DataSize = ALBuffer ? ALBuffer->SampleLen : 0; - CompLen = maxi(CompLen, DataSize); if(DataSize > pos) { @@ -506,11 +504,11 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize ALBuffer->FmtType, DataSize); } } - if(pos > CompLen) - pos -= CompLen; + if(pos > tmpiter->max_samples) + pos -= tmpiter->max_samples; else { - FilledAmt += CompLen - pos; + FilledAmt += tmpiter->max_samples - pos; pos = 0; } if(SrcBufferSize > FilledAmt) @@ -715,16 +713,7 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize else { /* Handle non-looping static source */ - ALsizei CompLen = 0; - ALsizei i; - - for(i = 0;i < BufferListItem->num_buffers;i++) - { - const ALbuffer *buffer = BufferListItem->buffers[i]; - if(buffer) CompLen = maxi(CompLen, buffer->SampleLen); - } - - if(DataPosInt >= CompLen) + if(DataPosInt >= BufferListItem->max_samples) { isplaying = false; BufferListItem = NULL; @@ -737,16 +726,7 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize else while(1) { /* Handle streaming source */ - ALsizei CompLen = 0; - ALsizei i; - - for(i = 0;i < BufferListItem->num_buffers;i++) - { - const ALbuffer *buffer = BufferListItem->buffers[i]; - if(buffer) CompLen = maxi(CompLen, buffer->SampleLen); - } - - if(CompLen > DataPosInt) + if(BufferListItem->max_samples > DataPosInt) break; buffers_done += BufferListItem->num_buffers; @@ -759,7 +739,7 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize break; } - DataPosInt -= CompLen; + DataPosInt -= BufferListItem->max_samples; } } while(isplaying && OutPos < SamplesToDo); diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 5b9d66dc..5f07c09d 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -20,6 +20,7 @@ struct ALsource; typedef struct ALbufferlistitem { ATOMIC(struct ALbufferlistitem*) next; + ALsizei max_samples; ALsizei num_buffers; struct ALbuffer *buffers[]; } ALbufferlistitem; diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index e3e40166..ed6bd8ee 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -835,6 +835,7 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p ALbufferlistitem *newlist = al_calloc(DEF_ALIGN, FAM_SIZE(ALbufferlistitem, buffers, 1)); ATOMIC_INIT(&newlist->next, NULL); + newlist->max_samples = buffer->SampleLen; newlist->num_buffers = 1; newlist->buffers[0] = buffer; IncrementRef(&buffer->ref); @@ -2421,27 +2422,16 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) for(i = 0;i < n;i++) { ALbufferlistitem *BufferList; - ALbuffer *buffer = NULL; bool start_fading = false; ALint vidx = -1; - ALsizei s; source = LookupSource(context, sources[i]); /* Check that there is a queue containing at least one valid, non zero - * length Buffer. + * length buffer. */ BufferList = source->queue; - while(BufferList) - { - ALsizei b; - for(b = 0;b < BufferList->num_buffers;b++) - { - buffer = BufferList->buffers[b]; - if(buffer && buffer->SampleLen > 0) break; - } - if(buffer && buffer->SampleLen > 0) break; + while(BufferList && BufferList->max_samples == 0) BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); - } /* If there's nothing to play, go right to stopped. */ if(UNLIKELY(!BufferList)) @@ -2484,9 +2474,7 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) break; } - /* Make sure this source isn't already active, and if not, look for an - * unused voice to put it in. - */ + /* Look for an unused voice to play this source with. */ assert(voice == NULL); for(j = 0;j < context->VoiceCount;j++) { @@ -2514,16 +2502,21 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_relaxed); ATOMIC_STORE(&voice->position, 0, almemory_order_relaxed); ATOMIC_STORE(&voice->position_fraction, 0, almemory_order_relaxed); - if(source->OffsetType != AL_NONE) - { - ApplyOffset(source, voice); + if(ApplyOffset(source, voice) != AL_FALSE) start_fading = ATOMIC_LOAD(&voice->position, almemory_order_relaxed) != 0 || ATOMIC_LOAD(&voice->position_fraction, almemory_order_relaxed) != 0 || ATOMIC_LOAD(&voice->current_buffer, almemory_order_relaxed) != BufferList; - } - voice->NumChannels = ChannelsFromFmt(buffer->FmtChannels); - voice->SampleSize = BytesFromFmt(buffer->FmtType); + for(j = 0;j < BufferList->num_buffers;j++) + { + ALbuffer *buffer = BufferList->buffers[j]; + if(buffer) + { + voice->NumChannels = ChannelsFromFmt(buffer->FmtChannels); + voice->SampleSize = BytesFromFmt(buffer->FmtType); + break; + } + } /* Clear previous samples. */ memset(voice->PrevSamples, 0, sizeof(voice->PrevSamples)); @@ -2536,8 +2529,8 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) voice->Flags = start_fading ? VOICE_IS_FADING : 0; if(source->SourceType == AL_STATIC) voice->Flags |= VOICE_IS_STATIC; memset(voice->Direct.Params, 0, sizeof(voice->Direct.Params[0])*voice->NumChannels); - for(s = 0;s < device->NumAuxSends;s++) - memset(voice->Send[s].Params, 0, sizeof(voice->Send[s].Params[0])*voice->NumChannels); + for(j = 0;j < device->NumAuxSends;j++) + memset(voice->Send[j].Params, 0, sizeof(voice->Send[j].Params[0])*voice->NumChannels); if(device->AvgSpeakerDist > 0.0f) { ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC / @@ -2774,6 +2767,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu BufferList = item; } ATOMIC_INIT(&BufferList->next, NULL); + BufferList->max_samples = buffer ? buffer->SampleLen : 0; BufferList->num_buffers = 1; BufferList->buffers[0] = buffer; if(!buffer) continue; @@ -2901,11 +2895,17 @@ AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint if(i < head->num_buffers) { /* This head has some buffers left over, so move them to the front - * and update the count. + * and update the sample and buffer count. */ + ALsizei max_length = 0; ALsizei j = 0; while(i < head->num_buffers) - head->buffers[j++] = head->buffers[i++]; + { + ALbuffer *buffer = head->buffers[i++]; + if(buffer) max_length = maxi(max_length, buffer->SampleLen); + head->buffers[j++] = buffer; + } + head->max_samples = max_length; head->num_buffers = j; break; } @@ -3176,15 +3176,7 @@ static ALint64 GetSourceSampleOffset(ALsource *Source, ALCcontext *context, ALui const ALbufferlistitem *BufferList = Source->queue; while(BufferList && BufferList != Current) { - ALsizei max_len = 0; - ALsizei i; - - for(i = 0;i < BufferList->num_buffers;i++) - { - ALbuffer *buffer = BufferList->buffers[i]; - if(buffer) max_len = maxi(max_len, buffer->SampleLen); - } - readPos += (ALuint64)max_len << 32; + readPos += (ALuint64)BufferList->max_samples << 32; BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); } @@ -3234,28 +3226,19 @@ static ALdouble GetSourceSecOffset(ALsource *Source, ALCcontext *context, ALuint const ALbuffer *BufferFmt = NULL; while(BufferList && BufferList != Current) { - ALsizei max_len = 0; - ALsizei i; - - for(i = 0;i < BufferList->num_buffers;i++) - { - ALbuffer *buffer = BufferList->buffers[i]; - if(buffer) - { - if(!BufferFmt) BufferFmt = buffer; - max_len = maxi(max_len, buffer->SampleLen); - } - } - readPos += (ALuint64)max_len << FRACTIONBITS; + ALsizei i = 0; + while(!BufferFmt && i < BufferList->num_buffers) + BufferFmt = BufferList->buffers[i++]; + readPos += (ALuint64)BufferList->max_samples << FRACTIONBITS; BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); } while(BufferList && !BufferFmt) { - ALsizei i; - for(i = 0;i < BufferList->num_buffers && !BufferFmt;i++) - BufferFmt = BufferList->buffers[i]; + ALsizei i = 0; + while(!BufferFmt && i < BufferList->num_buffers) + BufferFmt = BufferList->buffers[i++]; BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); } @@ -3310,21 +3293,13 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte while(BufferList != NULL) { - ALsizei max_len = 0; - ALsizei i; + ALsizei i = 0; + while(!BufferFmt && i < BufferList->num_buffers) + BufferFmt = BufferList->buffers[i++]; - readFin = readFin || (BufferList == Current); - for(i = 0;i < BufferList->num_buffers;i++) - { - ALbuffer *buffer = BufferList->buffers[i]; - if(buffer) - { - if(!BufferFmt) BufferFmt = buffer; - max_len = maxi(max_len, buffer->SampleLen); - } - } - totalBufferLen += max_len; - if(!readFin) readPos += max_len; + readFin |= (BufferList == Current); + totalBufferLen += BufferList->max_samples; + if(!readFin) readPos += BufferList->max_samples; BufferList = ATOMIC_LOAD(&CONST_CAST(ALbufferlistitem*,BufferList)->next, almemory_order_relaxed); @@ -3392,7 +3367,7 @@ static ALdouble GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *conte static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) { ALbufferlistitem *BufferList; - ALuint bufferLen, totalBufferLen; + ALuint totalBufferLen; ALuint offset = 0; ALsizei frac = 0; @@ -3404,17 +3379,7 @@ static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) BufferList = Source->queue; while(BufferList && totalBufferLen <= offset) { - ALsizei max_len = 0; - ALsizei i; - - for(i = 0;i < BufferList->num_buffers;i++) - { - ALbuffer *buffer = BufferList->buffers[i]; - if(buffer) max_len = maxi(max_len, buffer->SampleLen); - } - bufferLen = max_len; - - if(bufferLen > offset-totalBufferLen) + if((ALuint)BufferList->max_samples > offset-totalBufferLen) { /* Offset is in this buffer */ ATOMIC_STORE(&voice->position, offset - totalBufferLen, almemory_order_relaxed); @@ -3422,8 +3387,7 @@ static ALboolean ApplyOffset(ALsource *Source, ALvoice *voice) ATOMIC_STORE(&voice->current_buffer, BufferList, almemory_order_release); return AL_TRUE; } - - totalBufferLen += bufferLen; + totalBufferLen += BufferList->max_samples; BufferList = ATOMIC_LOAD(&BufferList->next, almemory_order_relaxed); } -- cgit v1.2.3