diff options
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALc.c | 287 | ||||
-rw-r--r-- | Alc/ALu.c | 31 | ||||
-rw-r--r-- | Alc/bformatdec.c | 28 | ||||
-rw-r--r-- | Alc/bformatdec.h | 1 | ||||
-rw-r--r-- | Alc/panning.c | 18 |
5 files changed, 274 insertions, 91 deletions
@@ -157,6 +157,8 @@ static const ALCfunction alcFunctions[] = { DECL(alcIsRenderFormatSupportedSOFT), DECL(alcRenderSamplesSOFT), + DECL(alcIsAmbisonicFormatSupportedSOFT), + DECL(alcDevicePauseSOFT), DECL(alcDeviceResumeSOFT), @@ -335,6 +337,7 @@ static const ALCenums enumeration[] = { DECL(ALC_5POINT1_SOFT), DECL(ALC_6POINT1_SOFT), DECL(ALC_7POINT1_SOFT), + DECL(ALC_BFORMAT3D_SOFT), DECL(ALC_BYTE_SOFT), DECL(ALC_UNSIGNED_BYTE_SOFT), @@ -357,6 +360,14 @@ static const ALCenums enumeration[] = { DECL(ALC_HRTF_SPECIFIER_SOFT), DECL(ALC_HRTF_ID_SOFT), + DECL(ALC_AMBISONIC_LAYOUT_SOFT), + DECL(ALC_AMBISONIC_SCALING_SOFT), + DECL(ALC_AMBISONIC_ORDER_SOFT), + DECL(ALC_ACN_SOFT), + DECL(ALC_FUMA_SOFT), + DECL(ALC_N3D_SOFT), + DECL(ALC_SN3D_SOFT), + DECL(ALC_NO_ERROR), DECL(ALC_INVALID_DEVICE), DECL(ALC_INVALID_CONTEXT), @@ -1478,11 +1489,34 @@ static ALCboolean IsValidALCChannels(ALCenum channels) case ALC_5POINT1_SOFT: case ALC_6POINT1_SOFT: case ALC_7POINT1_SOFT: + case ALC_BFORMAT3D_SOFT: return ALC_TRUE; } return ALC_FALSE; } +static ALCboolean IsValidAmbiLayout(ALCenum layout) +{ + switch(layout) + { + case ALC_ACN_SOFT: + case ALC_FUMA_SOFT: + return ALC_TRUE; + } + return ALC_FALSE; +} + +static ALCboolean IsValidAmbiScaling(ALCenum scaling) +{ + switch(scaling) + { + case ALC_N3D_SOFT: + case ALC_SN3D_SOFT: + case ALC_FUMA_SOFT: + return ALC_TRUE; + } + return ALC_FALSE; +} /************************************************ * Miscellaneous ALC helpers @@ -1746,12 +1780,15 @@ static void alcSetError(ALCdevice *device, ALCenum errorCode) * * Updates the device's base clock time with however many samples have been * done. This is used so frequency changes on the device don't cause the time - * to jump forward or back. + * to jump forward or back. Must not be called while the device is running/ + * mixing. */ static inline void UpdateClockBase(ALCdevice *device) { + IncrementRef(&device->MixCount); device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency; device->SamplesDone = 0; + IncrementRef(&device->MixCount); } /* UpdateDeviceParams @@ -1773,22 +1810,19 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) ALCuint oldFreq; FPUCtl oldMode; size_t size; + ALCsizei i; // Check for attributes if(device->Type == Loopback) { - enum { - GotFreq = 1<<0, - GotChans = 1<<1, - GotType = 1<<2, - GotAll = GotFreq|GotChans|GotType - }; - ALCuint freq, numMono, numStereo; - enum DevFmtChannels schans; - enum DevFmtType stype; - ALCuint attrIdx = 0; - ALCint gotFmt = 0; - ALCsizei numSends; + ALCsizei numMono, numStereo, numSends; + ALCenum alayout = AL_NONE; + ALCenum ascale = AL_NONE; + ALCenum schans = AL_NONE; + ALCenum stype = AL_NONE; + ALCsizei attrIdx = 0; + ALCsizei aorder = 0; + ALCuint freq = 0; if(!attrList) { @@ -1798,9 +1832,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) numMono = device->NumMonoSources; numStereo = device->NumStereoSources; - schans = device->FmtChans; - stype = device->FmtType; - freq = device->Frequency; numSends = old_sends; #define TRACE_ATTR(a, v) TRACE("Loopback %s = %d\n", #a, v) @@ -1808,22 +1839,18 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT) { - ALCint val = attrList[attrIdx + 1]; - TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, val); - if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val)) + schans = attrList[attrIdx + 1]; + TRACE_ATTR(ALC_FORMAT_CHANNELS_SOFT, schans); + if(!IsValidALCChannels(schans)) return ALC_INVALID_VALUE; - schans = val; - gotFmt |= GotChans; } if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT) { - ALCint val = attrList[attrIdx + 1]; - TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, val); - if(!IsValidALCType(val) || !BytesFromDevFmt(val)) + stype = attrList[attrIdx + 1]; + TRACE_ATTR(ALC_FORMAT_TYPE_SOFT, stype); + if(!IsValidALCType(stype)) return ALC_INVALID_VALUE; - stype = val; - gotFmt |= GotType; } if(attrList[attrIdx] == ALC_FREQUENCY) @@ -1832,16 +1859,38 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) TRACE_ATTR(ALC_FREQUENCY, freq); if(freq < MIN_OUTPUT_RATE) return ALC_INVALID_VALUE; - gotFmt |= GotFreq; + } + + if(attrList[attrIdx] == ALC_AMBISONIC_LAYOUT_SOFT) + { + alayout = attrList[attrIdx + 1]; + TRACE_ATTR(ALC_AMBISONIC_LAYOUT_SOFT, alayout); + if(!IsValidAmbiLayout(alayout)) + return ALC_INVALID_VALUE; + } + + if(attrList[attrIdx] == ALC_AMBISONIC_SCALING_SOFT) + { + ascale = attrList[attrIdx + 1]; + TRACE_ATTR(ALC_AMBISONIC_SCALING_SOFT, ascale); + if(!IsValidAmbiScaling(ascale)) + return ALC_INVALID_VALUE; + } + + if(attrList[attrIdx] == ALC_AMBISONIC_ORDER_SOFT) + { + aorder = attrList[attrIdx + 1]; + TRACE_ATTR(ALC_AMBISONIC_ORDER_SOFT, aorder); + if(aorder < 1 || aorder > MAX_AMBI_ORDER) + return ALC_INVALID_VALUE; } if(attrList[attrIdx] == ALC_STEREO_SOURCES) { numStereo = attrList[attrIdx + 1]; TRACE_ATTR(ALC_STEREO_SOURCES, numStereo); - if(numStereo > device->SourcesMax) - numStereo = device->SourcesMax; + numStereo = clampi(numStereo, 0, device->SourcesMax); numMono = device->SourcesMax - numStereo; } @@ -1849,14 +1898,16 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { numSends = attrList[attrIdx + 1]; TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends); + numSends = clampi(numSends, 0, MAX_SENDS); } if(attrList[attrIdx] == ALC_HRTF_SOFT) { - TRACE_ATTR(ALC_HRTF_SOFT, attrList[attrIdx + 1]); - if(attrList[attrIdx + 1] == ALC_FALSE) + ALCint val = attrList[attrIdx + 1]; + TRACE_ATTR(ALC_HRTF_SOFT, val); + if(val == ALC_FALSE) hrtf_appreq = Hrtf_Disable; - else if(attrList[attrIdx + 1] == ALC_TRUE) + else if(val == ALC_TRUE) hrtf_appreq = Hrtf_Enable; else hrtf_appreq = Hrtf_Default; @@ -1872,11 +1923,16 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) } #undef TRACE_ATTR - if(gotFmt != GotAll) + if(!schans || !stype || !freq) { WARN("Missing format for loopback device\n"); return ALC_INVALID_VALUE; } + if(schans == ALC_BFORMAT3D_SOFT && (!alayout || !ascale || !aorder)) + { + WARN("Missing ambisonic info for loopback device\n"); + return ALC_INVALID_VALUE; + } if((device->Flags&DEVICE_RUNNING)) V0(device->Backend,stop)(); @@ -1884,22 +1940,29 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) UpdateClockBase(device); + if(schans == ALC_BFORMAT3D_SOFT) + { + device->FmtChans = DevFmtAmbi1 + aorder; + device->AmbiLayout = alayout; + device->AmbiScale = ascale; + } + else + device->FmtChans = schans; device->Frequency = freq; - device->FmtChans = schans; device->FmtType = stype; device->NumMonoSources = numMono; device->NumStereoSources = numStereo; if(ConfigValueInt(NULL, NULL, "sends", &new_sends)) - new_sends = clampi(numSends, 0, clampi(new_sends, 0, MAX_SENDS)); + new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS)); else - new_sends = clampi(numSends, 0, MAX_SENDS); + new_sends = numSends; } else if(attrList && attrList[0]) { - ALCuint freq, numMono, numStereo; - ALCuint attrIdx = 0; - ALCsizei numSends; + ALCsizei numMono, numStereo, numSends; + ALCsizei attrIdx = 0; + ALCuint freq; /* If a context is already running on the device, stop playback so the * device attributes can be updated. */ @@ -1928,9 +1991,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { numStereo = attrList[attrIdx + 1]; TRACE_ATTR(ALC_STEREO_SOURCES, numStereo); - if(numStereo > device->SourcesMax) - numStereo = device->SourcesMax; + numStereo = clampi(numStereo, 0, device->SourcesMax); numMono = device->SourcesMax - numStereo; } @@ -1938,6 +2000,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) { numSends = attrList[attrIdx + 1]; TRACE_ATTR(ALC_MAX_AUXILIARY_SENDS, numSends); + numSends = clampi(numSends, 0, MAX_SENDS); } if(attrList[attrIdx] == ALC_HRTF_SOFT) @@ -1975,9 +2038,9 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) device->NumStereoSources = numStereo; if(ConfigValueInt(al_string_get_cstr(device->DeviceName), NULL, "sends", &new_sends)) - new_sends = clampi(numSends, 0, clampi(new_sends, 0, MAX_SENDS)); + new_sends = mini(numSends, clampi(new_sends, 0, MAX_SENDS)); else - new_sends = clampi(numSends, 0, MAX_SENDS); + new_sends = numSends; } if((device->Flags&DEVICE_RUNNING)) @@ -1989,6 +2052,13 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) al_free(device->Bs2b); device->Bs2b = NULL; + al_free(device->ChannelDelay[0].Buffer); + for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) + { + device->ChannelDelay[i].Length = 0; + device->ChannelDelay[i].Buffer = NULL; + } + al_free(device->Dry.Buffer); device->Dry.Buffer = NULL; device->Dry.NumChannels = 0; @@ -2270,6 +2340,8 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) */ static ALCvoid FreeDevice(ALCdevice *device) { + ALsizei i; + TRACE("%p\n", device); V0(device->Backend,close)(); @@ -2323,6 +2395,14 @@ static ALCvoid FreeDevice(ALCdevice *device) ambiup_free(device->AmbiUp); device->AmbiUp = NULL; + al_free(device->ChannelDelay[0].Buffer); + for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) + { + device->ChannelDelay[i].Gain = 1.0f; + device->ChannelDelay[i].Length = 0; + device->ChannelDelay[i].Buffer = NULL; + } + AL_STRING_DEINIT(device->DeviceName); al_free(device->Dry.Buffer); @@ -2883,6 +2963,14 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para } +static inline ALCsizei NumAttrsForDevice(ALCdevice *device) +{ + if(device->Type == Loopback && device->FmtChans >= DevFmtAmbi1 && + device->FmtChans <= DevFmtAmbi3) + return 23; + return 17; +} + static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values) { ALCsizei i; @@ -2914,6 +3002,9 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC case ALC_CAPTURE_SAMPLES: case ALC_FORMAT_CHANNELS_SOFT: case ALC_FORMAT_TYPE_SOFT: + case ALC_AMBISONIC_LAYOUT_SOFT: + case ALC_AMBISONIC_SCALING_SOFT: + case ALC_AMBISONIC_ORDER_SOFT: alcSetError(NULL, ALC_INVALID_DEVICE); return 0; @@ -2965,11 +3056,11 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC return 1; case ALC_ATTRIBUTES_SIZE: - values[0] = 17; + values[0] = NumAttrsForDevice(device); return 1; case ALC_ALL_ATTRIBUTES: - if(size < 17) + if(size < NumAttrsForDevice(device)) { alcSetError(device, ALC_INVALID_VALUE); return 0; @@ -2990,8 +3081,25 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC } else { - values[i++] = ALC_FORMAT_CHANNELS_SOFT; - values[i++] = device->FmtChans; + if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3) + { + values[i++] = ALC_FORMAT_CHANNELS_SOFT; + values[i++] = ALC_BFORMAT3D_SOFT; + + values[i++] = ALC_AMBISONIC_LAYOUT_SOFT; + values[i++] = device->AmbiLayout; + + values[i++] = ALC_AMBISONIC_SCALING_SOFT; + values[i++] = device->AmbiScale; + + values[i++] = ALC_AMBISONIC_ORDER_SOFT; + values[i++] = device->FmtChans-DevFmtAmbi1+1; + } + else + { + values[i++] = ALC_FORMAT_CHANNELS_SOFT; + values[i++] = device->FmtChans; + } values[i++] = ALC_FORMAT_TYPE_SOFT; values[i++] = device->FmtType; @@ -3046,7 +3154,10 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC alcSetError(device, ALC_INVALID_DEVICE); return 0; } - values[0] = device->FmtChans; + if(device->FmtChans >= DevFmtAmbi1 && device->FmtChans <= DevFmtAmbi3) + values[0] = ALC_BFORMAT3D_SOFT; + else + values[0] = device->FmtChans; return 1; case ALC_FORMAT_TYPE_SOFT: @@ -3058,6 +3169,36 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC values[0] = device->FmtType; return 1; + case ALC_AMBISONIC_LAYOUT_SOFT: + if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 && + device->FmtChans <= DevFmtAmbi3)) + { + alcSetError(device, ALC_INVALID_DEVICE); + return 0; + } + values[0] = device->AmbiLayout; + return 1; + + case ALC_AMBISONIC_SCALING_SOFT: + if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 && + device->FmtChans <= DevFmtAmbi3)) + { + alcSetError(device, ALC_INVALID_DEVICE); + return 0; + } + values[0] = device->AmbiScale; + return 1; + + case ALC_AMBISONIC_ORDER_SOFT: + if(device->Type != Loopback || !(device->FmtChans >= DevFmtAmbi1 && + device->FmtChans <= DevFmtAmbi3)) + { + alcSetError(device, ALC_INVALID_DEVICE); + return 0; + } + values[0] = device->FmtChans - DevFmtAmbi1 + 1; + return 1; + case ALC_MONO_SOURCES: values[0] = device->NumMonoSources; return 1; @@ -3567,6 +3708,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) const ALCchar *fmt; ALCdevice *device; ALCenum err; + ALCsizei i; DO_INITCONFIG(); @@ -3628,6 +3770,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) InitUIntMap(&device->EffectMap, ~0); InitUIntMap(&device->FilterMap, ~0); + for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) + { + device->ChannelDelay[i].Gain = 1.0f; + device->ChannelDelay[i].Length = 0; + device->ChannelDelay[i].Buffer = NULL; + } + //Set output format device->FmtChans = DevFmtChannelsDefault; device->FmtType = DevFmtTypeDefault; @@ -3871,6 +4020,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, { ALCdevice *device = NULL; ALCenum err; + ALCsizei i; DO_INITCONFIG(); @@ -3916,6 +4066,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, InitUIntMap(&device->EffectMap, ~0); InitUIntMap(&device->FilterMap, ~0); + for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) + { + device->ChannelDelay[i].Gain = 1.0f; + device->ChannelDelay[i].Length = 0; + device->ChannelDelay[i].Buffer = NULL; + } + if(!CaptureBackend.getFactory) device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs, ALCbackend_Capture); @@ -4078,6 +4235,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN { ALCbackendFactory *factory; ALCdevice *device; + ALCsizei i; DO_INITCONFIG(); @@ -4128,6 +4286,13 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN InitUIntMap(&device->EffectMap, ~0); InitUIntMap(&device->FilterMap, ~0); + for(i = 0;i < MAX_OUTPUT_CHANNELS;i++) + { + device->ChannelDelay[i].Gain = 1.0f; + device->ChannelDelay[i].Length = 0; + device->ChannelDelay[i].Buffer = NULL; + } + factory = ALCloopbackFactory_getFactory(); device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback); if(!device->Backend) @@ -4191,9 +4356,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device alcSetError(device, ALC_INVALID_VALUE); else { - if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 && - IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 && - freq >= MIN_OUTPUT_RATE) + if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE) ret = ALC_TRUE; } if(device) ALCdevice_DecRef(device); @@ -4223,6 +4386,28 @@ FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, AL /************************************************ + * ALC loopback2 functions + ************************************************/ + +ALC_API ALCboolean ALC_APIENTRY alcIsAmbisonicFormatSupportedSOFT(ALCdevice *device, ALCenum layout, ALCenum scaling, ALsizei order) +{ + ALCboolean ret = ALC_FALSE; + + if(!VerifyDevice(&device) || device->Type != Loopback) + alcSetError(device, ALC_INVALID_DEVICE); + else if(order <= 0) + alcSetError(device, ALC_INVALID_VALUE); + else + { + if(IsValidAmbiLayout(layout) && IsValidAmbiScaling(scaling) && order <= MAX_AMBI_ORDER) + ret = ALC_TRUE; + } + if(device) ALCdevice_DecRef(device); + + return ret; +} + +/************************************************ * ALC DSP pause/resume functions ************************************************/ @@ -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); @@ -1332,24 +1328,24 @@ static void Write_##T(const ALfloatBUFFERSIZE *InBuffer, ALvoid *OutBuffer, \ T *restrict out = (T*)OutBuffer + j; \ const ALfloat gain = distcomp[j].Gain; \ const ALsizei base = distcomp[j].Length; \ + ALfloat *restrict distbuf = ASSUME_ALIGNED(distcomp[j].Buffer, 16); \ if(base > 0 || gain != 1.0f) \ { \ if(SamplesToDo >= base) \ { \ for(i = 0;i < base;i++) \ - out[i*numchans] = func(distcomp[j].Buffer[i]*gain); \ + out[i*numchans] = func(distbuf[i]*gain); \ for(;i < SamplesToDo;i++) \ out[i*numchans] = func(in[i-base]*gain); \ - memcpy(distcomp[j].Buffer, &in[SamplesToDo-base], \ - base*sizeof(ALfloat)); \ + memcpy(distbuf, &in[SamplesToDo-base], base*sizeof(ALfloat)); \ } \ else \ { \ for(i = 0;i < SamplesToDo;i++) \ - out[i*numchans] = func(distcomp[j].Buffer[i]*gain); \ - memmove(distcomp[j].Buffer, distcomp[j].Buffer+SamplesToDo, \ + out[i*numchans] = func(distbuf[i]*gain); \ + memmove(distbuf, distbuf+SamplesToDo, \ (base-SamplesToDo)*sizeof(ALfloat)); \ - memcpy(distcomp[j].Buffer+base-SamplesToDo, in, \ + memcpy(distbuf+base-SamplesToDo, in, \ SamplesToDo*sizeof(ALfloat)); \ } \ } \ @@ -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/Alc/bformatdec.c b/Alc/bformatdec.c index a0aa4e44..92a2aecf 100644 --- a/Alc/bformatdec.c +++ b/Alc/bformatdec.c @@ -6,6 +6,7 @@ #include "mixer_defs.h" #include "alu.h" +#include "bool.h" #include "threads.h" #include "almalloc.h" @@ -181,7 +182,6 @@ typedef struct BFormatDec { ALsizei NumChannels; ALboolean DualBand; - ALboolean Periphonic; } BFormatDec; BFormatDec *bformatdec_alloc() @@ -204,29 +204,13 @@ void bformatdec_free(BFormatDec *dec) } } -int bformatdec_getOrder(const struct BFormatDec *dec) -{ - if(dec->Periphonic) - { - if(dec->NumChannels > 9) return 3; - if(dec->NumChannels > 4) return 2; - if(dec->NumChannels > 1) return 1; - } - else - { - if(dec->NumChannels > 5) return 3; - if(dec->NumChannels > 3) return 2; - if(dec->NumChannels > 1) return 1; - } - return 0; -} - void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS]) { static const ALsizei map2DTo3D[MAX_AMBI2D_COEFFS] = { 0, 1, 3, 4, 8, 9, 15 }; const ALfloat *coeff_scale = UnitScale; + bool periphonic; ALfloat ratio; ALsizei i; @@ -256,7 +240,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount bandsplit_init(&dec->UpSampler[i].XOver, ratio); if((conf->ChanMask&AMBI_PERIPHONIC_MASK)) { - dec->Periphonic = AL_TRUE; + periphonic = true; dec->UpSampler[0].Gains[FB_HighFreq] = (dec->NumChannels > 9) ? W_SCALE3D_THIRD : (dec->NumChannels > 4) ? W_SCALE3D_SECOND : 1.0f; @@ -270,7 +254,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount } else { - dec->Periphonic = AL_FALSE; + periphonic = false; dec->UpSampler[0].Gains[FB_HighFreq] = (dec->NumChannels > 5) ? W_SCALE2D_THIRD : (dec->NumChannels > 3) ? W_SCALE2D_SECOND : 1.0f; @@ -295,7 +279,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount ALfloat gain; ALsizei j, k; - if(!dec->Periphonic) + if(!periphonic) { for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++) { @@ -339,7 +323,7 @@ void bformatdec_reset(BFormatDec *dec, const AmbDecConf *conf, ALsizei chancount ALfloat gain; ALsizei j, k; - if(!dec->Periphonic) + if(!periphonic) { for(j = 0,k = 0;j < MAX_AMBI2D_COEFFS;j++) { diff --git a/Alc/bformatdec.h b/Alc/bformatdec.h index 889d59f4..162f2652 100644 --- a/Alc/bformatdec.h +++ b/Alc/bformatdec.h @@ -28,7 +28,6 @@ struct AmbiUpsampler; struct BFormatDec *bformatdec_alloc(); void bformatdec_free(struct BFormatDec *dec); -int bformatdec_getOrder(const struct BFormatDec *dec); void bformatdec_reset(struct BFormatDec *dec, const struct AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS]); /* Decodes the ambisonic input to the given output channels. */ diff --git a/Alc/panning.c b/Alc/panning.c index 77f8e31b..c4d3e43f 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -616,6 +616,7 @@ static void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const AL { const char *devname = al_string_get_cstr(device->DeviceName); ALfloat maxdist = 0.0f; + ALsizei total = 0; ALsizei i; for(i = 0;i < conf->NumSpeakers;i++) @@ -649,6 +650,21 @@ static void InitDistanceComp(ALCdevice *device, const AmbDecConf *conf, const AL al_string_get_cstr(conf->Speakers[i].Name), device->ChannelDelay[chan].Length, device->ChannelDelay[chan].Gain ); + + /* Round up to the next 4th sample, so each channel buffer starts + * 16-byte aligned. + */ + total += RoundUp(device->ChannelDelay[chan].Length, 4); + } + } + + if(total > 0) + { + device->ChannelDelay[0].Buffer = al_calloc(16, total * sizeof(ALfloat)); + for(i = 1;i < MAX_OUTPUT_CHANNELS;i++) + { + size_t len = RoundUp(device->ChannelDelay[i-1].Length, 4); + device->ChannelDelay[i].Buffer = device->ChannelDelay[i-1].Buffer + len; } } } @@ -775,7 +791,7 @@ static void InitHQPanning(ALCdevice *device, const AmbDecConf *conf, const ALsiz ); bformatdec_reset(device->AmbiDecoder, conf, count, device->Frequency, speakermap); - if(bformatdec_getOrder(device->AmbiDecoder) < 2) + if(!(conf->ChanMask > 0xf)) { device->FOAOut.Ambi = device->Dry.Ambi; device->FOAOut.CoeffCount = device->Dry.CoeffCount; |