1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#include <iostream>
#include <sofa_hrtf.h>
#ifdef HAVE_MYSOFA
#include <cmath>
#include <AmbisonicCommons.h>
#include <vector>
SOFA_HRTF::SOFA_HRTF(std::string path, unsigned i_sampleRate)
: HRTF(i_sampleRate), hrtf(nullptr)
{
int err;
hrtf = mysofa_open(path.c_str(), i_sampleRate, &i_internalLength, &err);
if (hrtf == nullptr)
{
std::cout << "Could not load the SOFA HRTF." << std::endl;
return;
}
i_filterExtraLength = i_internalLength / 2;
i_len = i_internalLength + i_filterExtraLength;
}
SOFA_HRTF::~SOFA_HRTF()
{
if (hrtf != nullptr)
mysofa_close(hrtf);
}
bool SOFA_HRTF::get(float f_azimuth, float f_elevation, float** pfHRTF)
{
float delaysSec[2]; // unit is second.
unsigned delaysSamples[2]; // unit is samples.
std::vector<float> pfHRTFNotDelayed[2];
pfHRTFNotDelayed[0].resize( i_internalLength, 0.f );
pfHRTFNotDelayed[1].resize( i_internalLength, 0.f );
float p[3] = {RadiansToDegrees(f_azimuth), RadiansToDegrees(f_elevation), 1.f};
mysofa_s2c(p);
mysofa_getfilter_float(hrtf, p[0], p[1], p[2],
pfHRTFNotDelayed[0].data(), pfHRTFNotDelayed[1].data(), &delaysSec[0], &delaysSec[1]);
delaysSamples[0] = std::roundf(delaysSec[0] * i_sampleRate);
delaysSamples[1] = std::roundf(delaysSec[1] * i_sampleRate);
if (delaysSamples[0] > i_filterExtraLength
|| delaysSamples[1] > i_filterExtraLength)
{
std::cout << "Too big HRTF delay for the buffer length." << std::endl;
return false;
}
std::fill(pfHRTF[0], pfHRTF[0] + i_len, 0);
std::fill(pfHRTF[1], pfHRTF[1] + i_len, 0);
std::copy(pfHRTFNotDelayed[0].begin(), pfHRTFNotDelayed[0].end(), pfHRTF[0] + delaysSamples[0]);
std::copy(pfHRTFNotDelayed[1].begin(), pfHRTFNotDelayed[1].end(), pfHRTF[1] + delaysSamples[1]);
return true;
}
#endif
|