From 1bb7f575f056f33d0957fe864cd62072982fc66e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 11 Dec 2020 15:08:50 -0800 Subject: [PATCH] Don't modify the IR size of loaded HRTFs --- alc/alcmain.h | 3 +++ alc/hrtf.cpp | 14 ++++---------- alc/hrtf.h | 6 +++--- alc/panning.cpp | 20 ++++++++++++++------ alc/voice.cpp | 2 +- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/alc/alcmain.h b/alc/alcmain.h index 68d0e31d..d809f8ee 100644 --- a/alc/alcmain.h +++ b/alc/alcmain.h @@ -42,6 +42,8 @@ struct EffectState; struct Uhj2Encoder; struct bs2b; +using uint = unsigned int; + #define MIN_OUTPUT_RATE 8000 #define MAX_OUTPUT_RATE 192000 @@ -277,6 +279,7 @@ struct ALCdevice : public al::intrusive_ref { /* HRTF state and info */ std::unique_ptr mHrtfState; al::intrusive_ptr mHrtf; + uint mIrSize{0}; /* Ambisonic-to-UHJ encoder */ std::unique_ptr Uhj_Encoder; diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp index 5f812318..e01cdf97 100644 --- a/alc/hrtf.cpp +++ b/alc/hrtf.cpp @@ -277,8 +277,8 @@ void GetHrtfCoeffs(const HrtfStore *Hrtf, float elevation, float azimuth, float std::unique_ptr DirectHrtfState::Create(size_t num_chans) { return std::unique_ptr{new(FamCount(num_chans)) DirectHrtfState{num_chans}}; } -void DirectHrtfState::build(const HrtfStore *Hrtf, const al::span AmbiPoints, - const float (*AmbiMatrix)[MaxAmbiChannels], +void DirectHrtfState::build(const HrtfStore *Hrtf, const uint irSize, + const al::span AmbiPoints, const float (*AmbiMatrix)[MaxAmbiChannels], const al::span AmbiOrderHFGain) { using double2 = std::array; @@ -367,7 +367,7 @@ void DirectHrtfState::build(const HrtfStore *Hrtf, const al::spanirSize, HRIR_LENGTH)}; + const uint max_length{minu(max_delay + irSize, HRIR_LENGTH)}; TRACE("Skipped delay: %.2f, new max delay: %.2f, FIR length: %u\n", min_delay/double{HRIR_DELAY_FRACONE}, max_delay/double{HRIR_DELAY_FRACONE}, @@ -1277,7 +1277,7 @@ al::vector EnumerateHrtf(const char *devname) return list; } -HrtfStorePtr GetLoadedHrtf(const std::string &name, const char *devname, const uint devrate) +HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate) { std::lock_guard _{EnumeratedHrtfLock}; auto entry_iter = std::find_if(EnumeratedHrtfs.cbegin(), EnumeratedHrtfs.cend(), @@ -1432,12 +1432,6 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const char *devname, const u hrtf->sampleRate = devrate; } - if(auto hrtfsizeopt = ConfigValueUInt(devname, nullptr, "hrtf-size")) - { - if(*hrtfsizeopt > 0 && *hrtfsizeopt < hrtf->irSize) - hrtf->irSize = maxu(*hrtfsizeopt, MIN_IR_LENGTH); - } - TRACE("Loaded HRTF %s for sample rate %uhz, %u-sample filter\n", name.c_str(), hrtf->sampleRate, hrtf->irSize); handle = LoadedHrtfs.emplace(handle, LoadedHrtf{fname, std::move(hrtf)}); diff --git a/alc/hrtf.h b/alc/hrtf.h index 33a6021f..9bb7f65f 100644 --- a/alc/hrtf.h +++ b/alc/hrtf.h @@ -101,8 +101,8 @@ struct DirectHrtfState { * high-frequency gains for the decoder. The calculated impulse responses * are ordered and scaled according to the matrix input. */ - void build(const HrtfStore *Hrtf, const al::span AmbiPoints, - const float (*AmbiMatrix)[MaxAmbiChannels], + void build(const HrtfStore *Hrtf, const uint irSize, + const al::span AmbiPoints, const float (*AmbiMatrix)[MaxAmbiChannels], const al::span AmbiOrderHFGain); static std::unique_ptr Create(size_t num_chans); @@ -112,7 +112,7 @@ struct DirectHrtfState { al::vector EnumerateHrtf(const char *devname); -HrtfStorePtr GetLoadedHrtf(const std::string &name, const char *devname, const uint devrate); +HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate); void GetHrtfCoeffs(const HrtfStore *Hrtf, float elevation, float azimuth, float distance, float spread, HrirArray &coeffs, const al::span delays); diff --git a/alc/panning.cpp b/alc/panning.cpp index 24a303e5..c8db28c2 100644 --- a/alc/panning.cpp +++ b/alc/panning.cpp @@ -823,7 +823,7 @@ void InitHrtfPanning(ALCdevice *device) HrtfStore *Hrtf{device->mHrtf.get()}; auto hrtfstate = DirectHrtfState::Create(count); - hrtfstate->build(Hrtf, AmbiPoints, AmbiMatrix, AmbiOrderHFGain); + hrtfstate->build(Hrtf, device->mIrSize, AmbiPoints, AmbiMatrix, AmbiOrderHFGain); device->mHrtfState = std::move(hrtfstate); InitNearFieldCtrl(device, Hrtf->field[0].distance, ambi_order, true); @@ -849,11 +849,14 @@ void InitUhjPanning(ALCdevice *device) void aluInitRenderer(ALCdevice *device, int hrtf_id, HrtfRequestMode hrtf_appreq, HrtfRequestMode hrtf_userreq) { + const char *devname{device->DeviceName.c_str()}; + /* Hold the HRTF the device last used, in case it's used again. */ HrtfStorePtr old_hrtf{std::move(device->mHrtf)}; device->mHrtfState = nullptr; device->mHrtf = nullptr; + device->mIrSize = 0; device->HrtfName.clear(); device->mRenderMode = RenderMode::Normal; @@ -878,7 +881,6 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, HrtfRequestMode hrtf_appreq break; } - const char *devname{device->DeviceName.c_str()}; ALuint speakermap[MAX_OUTPUT_CHANNELS]; AmbDecConf *pconf{nullptr}; AmbDecConf conf{}; @@ -960,9 +962,8 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, HrtfRequestMode hrtf_appreq if(hrtf_id >= 0 && static_cast(hrtf_id) < device->HrtfList.size()) { - const char *devname{device->DeviceName.c_str()}; const std::string &hrtfname = device->HrtfList[static_cast(hrtf_id)]; - if(HrtfStorePtr hrtf{GetLoadedHrtf(hrtfname, devname, device->Frequency)}) + if(HrtfStorePtr hrtf{GetLoadedHrtf(hrtfname, device->Frequency)}) { device->mHrtf = std::move(hrtf); device->HrtfName = hrtfname; @@ -971,10 +972,9 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, HrtfRequestMode hrtf_appreq if(!device->mHrtf) { - const char *devname{device->DeviceName.c_str()}; for(const auto &hrtfname : device->HrtfList) { - if(HrtfStorePtr hrtf{GetLoadedHrtf(hrtfname, devname, device->Frequency)}) + if(HrtfStorePtr hrtf{GetLoadedHrtf(hrtfname, device->Frequency)}) { device->mHrtf = std::move(hrtf); device->HrtfName = hrtfname; @@ -987,6 +987,14 @@ void aluInitRenderer(ALCdevice *device, int hrtf_id, HrtfRequestMode hrtf_appreq { old_hrtf = nullptr; + HrtfStore *hrtf{device->mHrtf.get()}; + device->mIrSize = hrtf->irSize; + if(auto hrtfsizeopt = ConfigValueUInt(devname, nullptr, "hrtf-size")) + { + if(*hrtfsizeopt > 0 && *hrtfsizeopt < device->mIrSize) + device->mIrSize = maxu(*hrtfsizeopt, MIN_IR_LENGTH); + } + InitHrtfPanning(device); device->PostProcess = &ALCdevice::ProcessHrtf; return; diff --git a/alc/voice.cpp b/alc/voice.cpp index 600fe80e..eec34246 100644 --- a/alc/voice.cpp +++ b/alc/voice.cpp @@ -467,7 +467,7 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) ALCdevice *Device{Context->mDevice.get()}; const uint NumSends{Device->NumAuxSends}; - const uint IrSize{Device->mHrtf ? Device->mHrtf->irSize : 0}; + const uint IrSize{Device->mIrSize}; ResamplerFunc Resample{(increment == MixerFracOne && DataPosFrac == 0) ? Resample_ : mResampler};