Dynamically allocate the ALsource Send[] array
This commit is contained in:
@@ -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;
|
||||
|
||||
+1
-1
@@ -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. */
|
||||
|
||||
@@ -648,7 +648,7 @@ struct ALCdevice_struct
|
||||
|
||||
ALCuint NumMonoSources;
|
||||
ALCuint NumStereoSources;
|
||||
ALuint NumAuxSends;
|
||||
ALsizei NumAuxSends;
|
||||
|
||||
// Map of Buffers for this device
|
||||
UIntMap BufferMap;
|
||||
|
||||
@@ -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
|
||||
|
||||
+33
-22
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user