diff options
author | Chris Robinson <[email protected]> | 2017-02-21 16:31:59 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-02-21 16:31:59 -0800 |
commit | 864d5387dda119d9faecfd62226b62f1a8af8532 (patch) | |
tree | 482a95640ede134a44f669965eec28ea18e41de3 | |
parent | 29994aa2de828ce96950451219186b44bac54a75 (diff) |
Dynamically allocate the ALsource Send[] array
-rw-r--r-- | Alc/ALc.c | 102 | ||||
-rw-r--r-- | Alc/mixer.c | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 2 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 2 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 55 |
5 files changed, 94 insertions, 69 deletions
@@ -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)); |