2 * OpenAL cross platform audio library
3 * Copyright (C) 2011 by Chris Robinson
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
28 #define HRIR_COUNT 828
30 static const ALuint sampleRate
= 44100;
31 static const ALubyte evCount
= 19;
32 static const ALushort evOffset
[19] = { 0, 1, 13, 37, 73, 118, 174, 234, 306, 378, 450, 522, 594, 654, 710, 755, 791, 815, 827 };
33 static const ALubyte azCount
[19] = { 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1 };
36 ALshort coeffs
[HRIR_COUNT
][HRIR_LENGTH
];
37 ALubyte delays
[HRIR_COUNT
];
39 #include "hrtf_tables.inc"
42 // Calculate the elevation indices given the polar elevation in radians.
43 // This will return two indices between 0 and (evCount - 1) and an
44 // interpolation factor between 0.0 and 1.0.
45 static void CalcEvIndices(ALfloat ev
, ALuint
*evidx
, ALfloat
*evmu
)
47 ev
= (M_PI
/2.0f
+ ev
) * (evCount
-1) / M_PI
;
48 evidx
[0] = (ALuint
)ev
;
49 evidx
[1] = __min(evidx
[0] + 1, evCount
- 1);
50 *evmu
= ev
- evidx
[0];
53 // Calculate the azimuth indices given the polar azimuth in radians. This
54 // will return two indices between 0 and (azCount [ei] - 1) and an
55 // interpolation factor between 0.0 and 1.0.
56 static void CalcAzIndices(ALuint evidx
, ALfloat az
, ALuint
*azidx
, ALfloat
*azmu
)
58 az
= (M_PI
*2.0f
+ az
) * azCount
[evidx
] / (M_PI
*2.0f
);
59 azidx
[0] = (ALuint
)az
% azCount
[evidx
];
60 azidx
[1] = (azidx
[0] + 1) % azCount
[evidx
];
61 *azmu
= az
- (ALuint
)az
;
64 // Calculates static HRIR coefficients and delays for the given polar
65 // elevation and azimuth in radians. Linear interpolation is used to
66 // increase the apparent resolution of the HRIR dataset. The coefficients
67 // are also normalized and attenuated by the specified gain.
68 void GetLerpedHrtfCoeffs(ALfloat elevation
, ALfloat azimuth
, ALfloat gain
, ALfloat (*coeffs
)[2], ALuint
*delays
)
70 ALuint evidx
[2], azidx
[2];
72 ALuint lidx
[4], ridx
[4];
75 // Claculate elevation indices and interpolation factor.
76 CalcEvIndices(elevation
, evidx
, &mu
[2]);
78 // Calculate azimuth indices and interpolation factor for the first
80 CalcAzIndices(evidx
[0], azimuth
, azidx
, &mu
[0]);
82 // Calculate the first set of linear HRIR indices for left and right
84 lidx
[0] = evOffset
[evidx
[0]] + azidx
[0];
85 lidx
[1] = evOffset
[evidx
[0]] + azidx
[1];
86 ridx
[0] = evOffset
[evidx
[0]] + ((azCount
[evidx
[0]]-azidx
[0]) % azCount
[evidx
[0]]);
87 ridx
[1] = evOffset
[evidx
[0]] + ((azCount
[evidx
[0]]-azidx
[1]) % azCount
[evidx
[0]]);
89 // Calculate azimuth indices and interpolation factor for the second
91 CalcAzIndices (evidx
[1], azimuth
, azidx
, &mu
[1]);
93 // Calculate the second set of linear HRIR indices for left and right
95 lidx
[2] = evOffset
[evidx
[1]] + azidx
[0];
96 lidx
[3] = evOffset
[evidx
[1]] + azidx
[1];
97 ridx
[2] = evOffset
[evidx
[1]] + ((azCount
[evidx
[1]]-azidx
[0]) % azCount
[evidx
[1]]);
98 ridx
[3] = evOffset
[evidx
[1]] + ((azCount
[evidx
[1]]-azidx
[1]) % azCount
[evidx
[1]]);
100 // Calculate the normalized and attenuated HRIR coefficients using linear
101 // interpolation when there is enough gain to warrant it. Zero the
102 // coefficients if gain is too low.
105 ALdouble scale
= gain
* (1.0/32767.0);
106 for(i
= 0;i
< HRIR_LENGTH
;i
++)
108 coeffs
[i
][0] = lerp(lerp(Hrtf
.coeffs
[lidx
[0]][i
], Hrtf
.coeffs
[lidx
[1]][i
], mu
[0]),
109 lerp(Hrtf
.coeffs
[lidx
[2]][i
], Hrtf
.coeffs
[lidx
[3]][i
], mu
[1]),
111 coeffs
[i
][1] = lerp(lerp(Hrtf
.coeffs
[ridx
[0]][i
], Hrtf
.coeffs
[ridx
[1]][i
], mu
[0]),
112 lerp(Hrtf
.coeffs
[ridx
[2]][i
], Hrtf
.coeffs
[ridx
[3]][i
], mu
[1]),
118 for(i
= 0;i
< HRIR_LENGTH
;i
++)
125 // Calculate the HRIR delays using linear interpolation.
126 delays
[0] = (ALuint
)(lerp(lerp(Hrtf
.delays
[lidx
[0]], Hrtf
.delays
[lidx
[1]], mu
[0]),
127 lerp(Hrtf
.delays
[lidx
[2]], Hrtf
.delays
[lidx
[3]], mu
[1]),
129 delays
[1] = (ALuint
)(lerp(lerp(Hrtf
.delays
[ridx
[0]], Hrtf
.delays
[ridx
[1]], mu
[0]),
130 lerp(Hrtf
.delays
[ridx
[2]], Hrtf
.delays
[ridx
[3]], mu
[1]),
134 ALCboolean
IsHrtfCompatible(ALCdevice
*device
)
136 if(device
->FmtChans
== DevFmtStereo
&& device
->Frequency
== sampleRate
)
146 str
= GetConfigValue(NULL
, "hrtf_tables", "");
149 f
= fopen(str
, "rb");
151 AL_PRINT("Could not open %s\n", str
);
155 const ALubyte maxDelay
= SRC_HISTORY_LENGTH
;
156 ALboolean failed
= AL_FALSE
;
160 for(i
= 0;i
< HRIR_COUNT
;i
++)
162 for(j
= 0;j
< HRIR_LENGTH
;j
++)
167 newdata
.coeffs
[i
][j
] = val
;
170 for(i
= 0;i
< HRIR_COUNT
;i
++)
174 newdata
.delays
[i
] = val
;
177 AL_PRINT("Invalid delay at idx %zu: %u (max: %u), in %s\n", i
, val
, maxDelay
, str
);
183 AL_PRINT("Premature end of data while reading %s\n", str
);