diff options
author | Chris Robinson <[email protected]> | 2017-03-10 10:47:43 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-03-10 10:47:43 -0800 |
commit | 6b4b00e4625139157996bcf2161ec8688a4b11e8 (patch) | |
tree | 5fd64318d724e6d57fb1063519b65ce394d851b6 | |
parent | 51cb969446baad21d688a26e01b01c383c63c660 (diff) |
Dynamically allocate the device's HRTF state
-rw-r--r-- | Alc/ALc.c | 79 | ||||
-rw-r--r-- | Alc/ALu.c | 17 | ||||
-rw-r--r-- | Alc/mixer.c | 2 | ||||
-rw-r--r-- | Alc/panning.c | 55 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 27 |
5 files changed, 94 insertions, 86 deletions
@@ -2071,7 +2071,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) /************************************************************************* * Update device format request if HRTF is requested */ - device->Hrtf.Status = ALC_HRTF_DISABLED_SOFT; + device->HrtfStatus = ALC_HRTF_DISABLED_SOFT; if(device->Type != Loopback) { const char *hrtf; @@ -2087,31 +2087,31 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable)) { - if(VECTOR_SIZE(device->Hrtf.List) == 0) + if(VECTOR_SIZE(device->HrtfList) == 0) { - VECTOR_DEINIT(device->Hrtf.List); - device->Hrtf.List = EnumerateHrtf(device->DeviceName); + VECTOR_DEINIT(device->HrtfList); + device->HrtfList = EnumerateHrtf(device->DeviceName); } - if(VECTOR_SIZE(device->Hrtf.List) > 0) + if(VECTOR_SIZE(device->HrtfList) > 0) { device->FmtChans = DevFmtStereo; - if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf.List)) - device->Frequency = VECTOR_ELEM(device->Hrtf.List, hrtf_id).hrtf->sampleRate; + if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList)) + device->Frequency = VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf->sampleRate; else - device->Frequency = VECTOR_ELEM(device->Hrtf.List, 0).hrtf->sampleRate; + device->Frequency = VECTOR_ELEM(device->HrtfList, 0).hrtf->sampleRate; device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST; } else { hrtf_userreq = Hrtf_Default; hrtf_appreq = Hrtf_Disable; - device->Hrtf.Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT; + device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT; } } } else if(hrtf_appreq == Hrtf_Enable) { - size_t i = VECTOR_SIZE(device->Hrtf.List); + size_t i = VECTOR_SIZE(device->HrtfList); /* Loopback device. We don't need to match to a specific HRTF entry * here. If the requested ID matches, we'll pick that later, if not, * we'll try to auto-select one anyway. Just make sure one exists @@ -2119,24 +2119,24 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList) */ if(device->FmtChans == DevFmtStereo) { - if(VECTOR_SIZE(device->Hrtf.List) == 0) + if(VECTOR_SIZE(device->HrtfList) == 0) { - VECTOR_DEINIT(device->Hrtf.List); - device->Hrtf.List = EnumerateHrtf(device->DeviceName); + VECTOR_DEINIT(device->HrtfList); + device->HrtfList = EnumerateHrtf(device->DeviceName); } - for(i = 0;i < VECTOR_SIZE(device->Hrtf.List);i++) + for(i = 0;i < VECTOR_SIZE(device->HrtfList);i++) { - const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf.List, i).hrtf; + const struct Hrtf *hrtf = VECTOR_ELEM(device->HrtfList, i).hrtf; if(hrtf->sampleRate == device->Frequency) break; } } - if(i == VECTOR_SIZE(device->Hrtf.List)) + if(i == VECTOR_SIZE(device->HrtfList)) { ERR("Requested format not HRTF compatible: %s, %uhz\n", DevFmtChannelsString(device->FmtChans), device->Frequency); hrtf_appreq = Hrtf_Disable; - device->Hrtf.Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT; + device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT; } } @@ -2398,8 +2398,10 @@ static ALCvoid FreeDevice(ALCdevice *device) } ResetUIntMap(&device->FilterMap); - AL_STRING_DEINIT(device->Hrtf.Name); - FreeHrtfList(&device->Hrtf.List); + AL_STRING_DEINIT(device->HrtfName); + FreeHrtfList(&device->HrtfList); + al_free(device->Hrtf); + device->Hrtf = NULL; al_free(device->Bs2b); device->Bs2b = NULL; @@ -2964,7 +2966,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para else { almtx_lock(&Device->BackendLock); - value = (Device->Hrtf.Handle ? al_string_get_cstr(Device->Hrtf.Name) : ""); + value = (Device->HrtfHandle ? al_string_get_cstr(Device->HrtfName) : ""); almtx_unlock(&Device->BackendLock); ALCdevice_DecRef(Device); } @@ -3133,10 +3135,10 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC values[i++] = device->NumAuxSends; values[i++] = ALC_HRTF_SOFT; - values[i++] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE); + values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE); values[i++] = ALC_HRTF_STATUS_SOFT; - values[i++] = device->Hrtf.Status; + values[i++] = device->HrtfStatus; almtx_unlock(&device->BackendLock); values[i++] = 0; @@ -3234,18 +3236,18 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC return 1; case ALC_HRTF_SOFT: - values[0] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE); + values[0] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE); return 1; case ALC_HRTF_STATUS_SOFT: - values[0] = device->Hrtf.Status; + values[0] = device->HrtfStatus; return 1; case ALC_NUM_HRTF_SPECIFIERS_SOFT: almtx_lock(&device->BackendLock); - FreeHrtfList(&device->Hrtf.List); - device->Hrtf.List = EnumerateHrtf(device->DeviceName); - values[0] = (ALCint)VECTOR_SIZE(device->Hrtf.List); + FreeHrtfList(&device->HrtfList); + device->HrtfList = EnumerateHrtf(device->DeviceName); + values[0] = (ALCint)VECTOR_SIZE(device->HrtfList); almtx_unlock(&device->BackendLock); return 1; @@ -3336,10 +3338,10 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, values[i++] = device->NumAuxSends; values[i++] = ALC_HRTF_SOFT; - values[i++] = (device->Hrtf.Handle ? ALC_TRUE : ALC_FALSE); + values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE); values[i++] = ALC_HRTF_STATUS_SOFT; - values[i++] = device->Hrtf.Status; + values[i++] = device->HrtfStatus; clock = V0(device->Backend,getClockLatency)(); values[i++] = ALC_DEVICE_CLOCK_SOFT; @@ -3764,8 +3766,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName) device->Flags = 0; device->Bs2b = NULL; device->Uhj_Encoder = NULL; - VECTOR_INIT(device->Hrtf.List); - AL_STRING_INIT(device->Hrtf.Name); + device->Hrtf = NULL; + VECTOR_INIT(device->HrtfList); + AL_STRING_INIT(device->HrtfName); device->Render_Mode = NormalRender; AL_STRING_INIT(device->DeviceName); device->Dry.Buffer = NULL; @@ -4070,8 +4073,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, device->Connected = ALC_TRUE; device->Type = Capture; - VECTOR_INIT(device->Hrtf.List); - AL_STRING_INIT(device->Hrtf.Name); + device->Hrtf = NULL; + VECTOR_INIT(device->HrtfList); + AL_STRING_INIT(device->HrtfName); AL_STRING_INIT(device->DeviceName); device->Dry.Buffer = NULL; @@ -4279,8 +4283,9 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN ATOMIC_INIT(&device->LastError, ALC_NO_ERROR); device->Flags = 0; - VECTOR_INIT(device->Hrtf.List); - AL_STRING_INIT(device->Hrtf.Name); + device->Hrtf = NULL; + VECTOR_INIT(device->HrtfList); + AL_STRING_INIT(device->HrtfName); device->Bs2b = NULL; device->Uhj_Encoder = NULL; device->Render_Mode = NormalRender; @@ -4501,8 +4506,8 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum else switch(paramName) { case ALC_HRTF_SPECIFIER_SOFT: - if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf.List)) - str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf.List, index).name); + if(index >= 0 && (size_t)index < VECTOR_SIZE(device->HrtfList)) + str = al_string_get_cstr(VECTOR_ELEM(device->HrtfList, index).name); else alcSetError(device, ALC_INVALID_VALUE); break; @@ -633,7 +633,7 @@ static void CalcNonAttnSourceParams(ALvoice *voice, const struct ALsourceProps * } /* Get the static HRIR coefficients and delays for this channel. */ - GetHrtfCoeffs(Device->Hrtf.Handle, + GetHrtfCoeffs(Device->HrtfHandle, chans[c].elevation, chans[c].angle, 0.0f, DryGain, voice->Direct.Params[c].Hrtf.Target.Coeffs, voice->Direct.Params[c].Hrtf.Target.Delay @@ -1104,7 +1104,7 @@ static void CalcAttnSourceParams(ALvoice *voice, const struct ALsourceProps *pro spread = asinf(radius / Distance) * 2.0f; /* Get the HRIR coefficients and delays. */ - GetHrtfCoeffs(Device->Hrtf.Handle, ev, az, spread, DryGain, + GetHrtfCoeffs(Device->HrtfHandle, ev, az, spread, DryGain, voice->Direct.Params[0].Hrtf.Target.Coeffs, voice->Direct.Params[0].Hrtf.Target.Delay); @@ -1482,10 +1482,10 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) device->SamplesDone %= device->Frequency; IncrementRef(&device->MixCount); - if(device->Hrtf.Handle) + if(device->HrtfHandle) { HrtfDirectMixerFunc HrtfMix; - ALsizei irsize; + DirectHrtfState *state; int lidx, ridx; if(device->AmbiUp) @@ -1499,16 +1499,15 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) assert(lidx != -1 && ridx != -1); HrtfMix = SelectHrtfMixer(); - irsize = device->Hrtf.IrSize; + state = device->Hrtf; for(c = 0;c < device->Dry.NumChannels;c++) { HrtfMix(device->RealOut.Buffer[lidx], device->RealOut.Buffer[ridx], - device->Dry.Buffer[c], device->Hrtf.Offset, irsize, - device->Hrtf.Coeffs[c], device->Hrtf.Values[c], - SamplesToDo + device->Dry.Buffer[c], state->Offset, state->IrSize, + state->Coeffs[c], state->Values[c], SamplesToDo ); } - device->Hrtf.Offset += SamplesToDo; + state->Offset += SamplesToDo; } else if(device->AmbiDecoder) { diff --git a/Alc/mixer.c b/Alc/mixer.c index 961c8f31..a189e5e3 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -393,7 +393,7 @@ ALboolean MixSource(ALvoice *voice, ALsource *Source, ALCdevice *Device, ALsizei SampleSize = voice->SampleSize; increment = voice->Step; - IrSize = (Device->Hrtf.Handle ? Device->Hrtf.Handle->irSize : 0); + IrSize = (Device->HrtfHandle ? Device->HrtfHandle->irSize : 0); Resample = ((increment == FRACTIONONE && DataPosFrac == 0) ? Resample_copy32_C : ResampleSamples); diff --git a/Alc/panning.c b/Alc/panning.c index 6315328a..728001c2 100644 --- a/Alc/panning.c +++ b/Alc/panning.c @@ -929,7 +929,7 @@ static void InitHrtfPanning(ALCdevice *device, bool hoa_mode) ALsizei count = hoa_mode ? 9 : 4; ALsizei i; - static_assert(9 <= COUNTOF(device->Hrtf.Coeffs), "ALCdevice::Hrtf.Values/Coeffs size is too small"); + static_assert(9 <= COUNTOF(device->Hrtf->Coeffs), "ALCdevice::Hrtf.Values/Coeffs size is too small"); static_assert(COUNTOF(AmbiPoints) <= HRTF_AMBI_MAX_CHANNELS, "HRTF_AMBI_MAX_CHANNELS is too small"); for(i = 0;i < count;i++) @@ -962,14 +962,14 @@ static void InitHrtfPanning(ALCdevice *device, bool hoa_mode) device->RealOut.NumChannels = ChannelsFromDevFmt(device->FmtChans); - memset(device->Hrtf.Coeffs, 0, sizeof(device->Hrtf.Coeffs)); - device->Hrtf.IrSize = BuildBFormatHrtf(device->Hrtf.Handle, - device->Hrtf.Coeffs, device->Dry.NumChannels, + memset(device->Hrtf->Coeffs, 0, sizeof(device->Hrtf->Coeffs)); + device->Hrtf->IrSize = BuildBFormatHrtf(device->HrtfHandle, + device->Hrtf->Coeffs, device->Dry.NumChannels, AmbiPoints, AmbiMatrix, COUNTOF(AmbiPoints) ); /* Round up to the nearest multiple of 8 */ - device->Hrtf.IrSize = (device->Hrtf.IrSize+7)&~7; + device->Hrtf->IrSize = (device->Hrtf->IrSize+7)&~7; } static void InitUhjPanning(ALCdevice *device) @@ -1000,8 +1000,10 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf int bs2blevel; size_t i; - device->Hrtf.Handle = NULL; - al_string_clear(&device->Hrtf.Name); + al_free(device->Hrtf); + device->Hrtf = NULL; + device->HrtfHandle = NULL; + al_string_clear(&device->HrtfName); device->Render_Mode = NormalRender; memset(&device->Dry.Ambi, 0, sizeof(device->Dry.Ambi)); @@ -1025,7 +1027,7 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf AmbDecConf conf, *pconf = NULL; if(hrtf_appreq == Hrtf_Enable) - device->Hrtf.Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT; + device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT; ambdec_init(&conf); @@ -1123,48 +1125,48 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf (hrtf_appreq == Hrtf_Enable); if(!usehrtf) goto no_hrtf; - device->Hrtf.Status = ALC_HRTF_ENABLED_SOFT; + device->HrtfStatus = ALC_HRTF_ENABLED_SOFT; if(headphones && hrtf_appreq != Hrtf_Disable) - device->Hrtf.Status = ALC_HRTF_HEADPHONES_DETECTED_SOFT; + device->HrtfStatus = ALC_HRTF_HEADPHONES_DETECTED_SOFT; } else { if(hrtf_userreq != Hrtf_Enable) { if(hrtf_appreq == Hrtf_Enable) - device->Hrtf.Status = ALC_HRTF_DENIED_SOFT; + device->HrtfStatus = ALC_HRTF_DENIED_SOFT; goto no_hrtf; } - device->Hrtf.Status = ALC_HRTF_REQUIRED_SOFT; + device->HrtfStatus = ALC_HRTF_REQUIRED_SOFT; } - if(VECTOR_SIZE(device->Hrtf.List) == 0) + if(VECTOR_SIZE(device->HrtfList) == 0) { - VECTOR_DEINIT(device->Hrtf.List); - device->Hrtf.List = EnumerateHrtf(device->DeviceName); + VECTOR_DEINIT(device->HrtfList); + device->HrtfList = EnumerateHrtf(device->DeviceName); } - if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->Hrtf.List)) + if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList)) { - const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf.List, hrtf_id); + const HrtfEntry *entry = &VECTOR_ELEM(device->HrtfList, hrtf_id); if(entry->hrtf->sampleRate == device->Frequency) { - device->Hrtf.Handle = entry->hrtf; - al_string_copy(&device->Hrtf.Name, entry->name); + device->HrtfHandle = entry->hrtf; + al_string_copy(&device->HrtfName, entry->name); } } - for(i = 0;!device->Hrtf.Handle && i < VECTOR_SIZE(device->Hrtf.List);i++) + for(i = 0;!device->HrtfHandle && i < VECTOR_SIZE(device->HrtfList);i++) { - const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf.List, i); + const HrtfEntry *entry = &VECTOR_ELEM(device->HrtfList, i); if(entry->hrtf->sampleRate == device->Frequency) { - device->Hrtf.Handle = entry->hrtf; - al_string_copy(&device->Hrtf.Name, entry->name); + device->HrtfHandle = entry->hrtf; + al_string_copy(&device->HrtfName, entry->name); } } - if(device->Hrtf.Handle) + if(device->HrtfHandle) { bool hoa_mode; @@ -1194,15 +1196,16 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf device->AmbiUp = ambiup_alloc(); hoa_mode = true; } + device->Hrtf = al_calloc(16, sizeof(device->Hrtf[0])); TRACE("%s HRTF rendering enabled, using \"%s\"\n", ((device->Render_Mode == HrtfRender) ? "Full" : "Basic"), - al_string_get_cstr(device->Hrtf.Name) + al_string_get_cstr(device->HrtfName) ); InitHrtfPanning(device, hoa_mode); return; } - device->Hrtf.Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT; + device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT; no_hrtf: TRACE("HRTF disabled\n"); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index e4c5b94a..b2e1bfcf 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -622,6 +622,14 @@ typedef struct HrtfParams { ALsizei Delay[2]; } HrtfParams; +typedef struct DirectHrtfState { + /* HRTF filter state for dry buffer content */ + alignas(16) ALfloat Values[9][HRIR_LENGTH][2]; + alignas(16) ALfloat Coeffs[9][HRIR_LENGTH][2]; + ALsizei Offset; + ALsizei IrSize; +} DirectHrtfState; + typedef struct HrtfEntry { al_string name; @@ -687,19 +695,12 @@ struct ALCdevice_struct // Map of Filters for this device UIntMap FilterMap; - /* HRTF filter tables */ - struct { - vector_HrtfEntry List; - al_string Name; - ALCenum Status; - const struct Hrtf *Handle; - - /* HRTF filter state for dry buffer content */ - alignas(16) ALfloat Values[9][HRIR_LENGTH][2]; - alignas(16) ALfloat Coeffs[9][HRIR_LENGTH][2]; - ALsizei Offset; - ALsizei IrSize; - } Hrtf; + /* HRTF state and info */ + DirectHrtfState *Hrtf; + al_string HrtfName; + const struct Hrtf *HrtfHandle; + vector_HrtfEntry HrtfList; + ALCenum HrtfStatus; /* UHJ encoder state */ struct Uhj2Encoder *Uhj_Encoder; |