aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-02-21 16:31:59 -0800
committerChris Robinson <[email protected]>2017-02-21 16:31:59 -0800
commit864d5387dda119d9faecfd62226b62f1a8af8532 (patch)
tree482a95640ede134a44f669965eec28ea18e41de3
parent29994aa2de828ce96950451219186b44bac54a75 (diff)
Dynamically allocate the ALsource Send[] array
-rw-r--r--Alc/ALc.c102
-rw-r--r--Alc/mixer.c2
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--OpenAL32/Include/alSource.h2
-rw-r--r--OpenAL32/alSource.c55
5 files changed, 94 insertions, 69 deletions
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));