aboutsummaryrefslogtreecommitdiffstats
path: root/utils/makemhr
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-12-08 19:17:58 -0800
committerChris Robinson <[email protected]>2019-12-08 19:17:58 -0800
commit7ded42cb94d555b33891f59ec7fc86b710318ebb (patch)
tree3d371b3e17988edd4ad2d5e1037c14c6c50060e8 /utils/makemhr
parent5942974d471abb7ed0d5ea1975e2e96050093b37 (diff)
Load SOFA HRIRs in a background thread
Diffstat (limited to 'utils/makemhr')
-rw-r--r--utils/makemhr/loadsofa.cpp142
1 files changed, 79 insertions, 63 deletions
diff --git a/utils/makemhr/loadsofa.cpp b/utils/makemhr/loadsofa.cpp
index 00dbf8f9..e2f2e232 100644
--- a/utils/makemhr/loadsofa.cpp
+++ b/utils/makemhr/loadsofa.cpp
@@ -25,9 +25,11 @@
#include <algorithm>
#include <array>
+#include <atomic>
#include <cmath>
#include <cstdio>
#include <functional>
+#include <future>
#include <iterator>
#include <memory>
#include <numeric>
@@ -486,79 +488,93 @@ static void CalcHrirMagnitude(const uint points, const uint n, std::vector<compl
static bool LoadResponses(MYSOFA_HRTF *sofaHrtf, HrirDataT *hData)
{
- const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
- hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize);
- double *hrirs = hData->mHrirsBase.data();
-
- /* Temporary buffers used to calculate the IR's onset and frequency
- * magnitudes.
- */
- auto upsampled = std::vector<double>(10 * hData->mIrPoints);
- auto htemp = std::vector<complex_d>(hData->mFftSize);
- auto hrir = std::vector<double>(hData->mFftSize);
+ std::atomic<uint> loaded_count{0u};
- for(uint si{0u};si < sofaHrtf->M;si++)
+ auto load_proc = [sofaHrtf,hData,&loaded_count]() -> bool
{
- printf("\rLoading HRIRs... %d of %d", si+1, sofaHrtf->M);
- fflush(stdout);
+ const uint channels{(hData->mChannelType == CT_STEREO) ? 2u : 1u};
+ hData->mHrirsBase.resize(channels * hData->mIrCount * hData->mIrSize);
+ double *hrirs = hData->mHrirsBase.data();
- float aer[3]{
- sofaHrtf->SourcePosition.values[3*si],
- sofaHrtf->SourcePosition.values[3*si + 1],
- sofaHrtf->SourcePosition.values[3*si + 2]
- };
- mysofa_c2s(aer);
+ /* Temporary buffers used to calculate the IR's onset and frequency
+ * magnitudes.
+ */
+ auto upsampled = std::vector<double>(10 * hData->mIrPoints);
+ auto htemp = std::vector<complex_d>(hData->mFftSize);
+ auto hrir = std::vector<double>(hData->mFftSize);
- if(std::abs(aer[1]) >= 89.999f)
- aer[0] = 0.0f;
- else
- aer[0] = std::fmod(360.0f - aer[0], 360.0f);
+ for(uint si{0u};si < sofaHrtf->M;++si)
+ {
+ loaded_count.fetch_add(1u);
- auto field = std::find_if(hData->mFds.cbegin(), hData->mFds.cend(),
- [&aer](const HrirFdT &fld) -> bool
- {
- double delta = aer[2] - fld.mDistance;
- return (std::abs(delta) < 0.001);
- });
- if(field == hData->mFds.cend())
- continue;
+ float aer[3]{
+ sofaHrtf->SourcePosition.values[3*si],
+ sofaHrtf->SourcePosition.values[3*si + 1],
+ sofaHrtf->SourcePosition.values[3*si + 2]
+ };
+ mysofa_c2s(aer);
- double ef{(90.0+aer[1]) / 180.0 * (field->mEvCount-1)};
- auto ei = static_cast<int>(std::round(ef));
- ef = (ef-ei) * 180.0 / (field->mEvCount-1);
- if(std::abs(ef) >= 0.1) continue;
+ if(std::abs(aer[1]) >= 89.999f)
+ aer[0] = 0.0f;
+ else
+ aer[0] = std::fmod(360.0f - aer[0], 360.0f);
- double af{aer[0] / 360.0 * field->mEvs[ei].mAzCount};
- auto ai = static_cast<int>(std::round(af));
- af = (af-ai) * 360.0 / field->mEvs[ei].mAzCount;
- ai %= field->mEvs[ei].mAzCount;
- if(std::abs(af) >= 0.1) continue;
+ auto field = std::find_if(hData->mFds.cbegin(), hData->mFds.cend(),
+ [&aer](const HrirFdT &fld) -> bool
+ {
+ double delta = aer[2] - fld.mDistance;
+ return (std::abs(delta) < 0.001);
+ });
+ if(field == hData->mFds.cend())
+ continue;
+
+ double ef{(90.0+aer[1]) / 180.0 * (field->mEvCount-1)};
+ auto ei = static_cast<int>(std::round(ef));
+ ef = (ef-ei) * 180.0 / (field->mEvCount-1);
+ if(std::abs(ef) >= 0.1) continue;
+
+ double af{aer[0] / 360.0 * field->mEvs[ei].mAzCount};
+ auto ai = static_cast<int>(std::round(af));
+ af = (af-ai) * 360.0 / field->mEvs[ei].mAzCount;
+ ai %= field->mEvs[ei].mAzCount;
+ if(std::abs(af) >= 0.1) continue;
+
+ HrirAzT *azd = &field->mEvs[ei].mAzs[ai];
+ if(azd->mIrs[0] != nullptr)
+ {
+ fprintf(stderr, "\nMultiple measurements near [ a=%f, e=%f, r=%f ].\n",
+ aer[0], aer[1], aer[2]);
+ return false;
+ }
- HrirAzT *azd = &field->mEvs[ei].mAzs[ai];
- if(azd->mIrs[0] != nullptr)
- {
- fprintf(stderr, "Multiple measurements near [ a=%f, e=%f, r=%f ].\n",
- aer[0], aer[1], aer[2]);
- return false;
- }
+ for(uint ti{0u};ti < channels;++ti)
+ {
+ std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
+ hData->mIrPoints, hrir.begin());
+ azd->mIrs[ti] = &hrirs[hData->mIrSize * (hData->mIrCount*ti + azd->mIndex)];
+ azd->mDelays[ti] = CalcHrirOnset(hData->mIrRate, hData->mIrPoints, upsampled,
+ hrir.data());
+ CalcHrirMagnitude(hData->mIrPoints, hData->mFftSize, htemp, hrir.data(),
+ azd->mIrs[ti]);
+ }
- for(uint ti{0u};ti < channels;++ti)
- {
- std::copy_n(&sofaHrtf->DataIR.values[(si*sofaHrtf->R + ti)*sofaHrtf->N],
- hData->mIrPoints, hrir.begin());
- azd->mIrs[ti] = &hrirs[hData->mIrSize * (hData->mIrCount*ti + azd->mIndex)];
- azd->mDelays[ti] = CalcHrirOnset(hData->mIrRate, hData->mIrPoints, upsampled,
- hrir.data());
- CalcHrirMagnitude(hData->mIrPoints, hData->mFftSize, htemp, hrir.data(),
- azd->mIrs[ti]);
+ /* TODO: Since some SOFA files contain minimum phase HRIRs,
+ * it would be beneficial to check for per-measurement delays
+ * (when available) to reconstruct the HRTDs.
+ */
}
-
- // TODO: Since some SOFA files contain minimum phase HRIRs,
- // it would be beneficial to check for per-measurement delays
- // (when available) to reconstruct the HRTDs.
- }
- printf("\n");
- return true;
+ return true;
+ };
+
+ std::future_status load_status{};
+ auto load_future = std::async(std::launch::async, load_proc);
+ do {
+ load_status = load_future.wait_for(std::chrono::milliseconds{50});
+ printf("\rLoading HRIRs... %u of %u", loaded_count.load(), sofaHrtf->M);
+ fflush(stdout);
+ } while(load_status != std::future_status::ready);
+ fputc('\n', stdout);
+ return load_future.get();
}
struct MySofaHrtfDeleter {