File: sofa_hrtf.cpp

package info (click to toggle)
libspatialaudio 0.3.0%2Bgit20180730%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 484 kB
  • sloc: cpp: 2,293; ansic: 1,247; makefile: 4
file content (69 lines) | stat: -rw-r--r-- 1,883 bytes parent folder | download | duplicates (3)
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