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 ALubyte evCount
= 19;
31 static const ALushort evOffset
[19] = { 0, 1, 13, 37, 73, 118, 174, 234, 306, 378, 450, 522, 594, 654, 710, 755, 791, 815, 827 };
32 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
];
40 #include "hrtf_tables.inc"
43 // Calculate the elevation indices given the polar elevation in radians.
44 // This will return two indices between 0 and (evCount - 1) and an
45 // interpolation factor between 0.0 and 1.0.
46 static void CalcEvIndices(ALfloat ev
, ALuint
*evidx
, ALfloat
*evmu
)
48 ev
= (M_PI
/2.0f
+ ev
) * (evCount
-1) / M_PI
;
49 evidx
[0] = (ALuint
)ev
;
50 evidx
[1] = __min(evidx
[0] + 1, evCount
- 1);
51 *evmu
= ev
- evidx
[0];
54 // Calculate the azimuth indices given the polar azimuth in radians. This
55 // will return two indices between 0 and (azCount [ei] - 1) and an
56 // interpolation factor between 0.0 and 1.0.
57 static void CalcAzIndices(ALuint evidx
, ALfloat az
, ALuint
*azidx
, ALfloat
*azmu
)
59 az
= (M_PI
*2.0f
+ az
) * azCount
[evidx
] / (M_PI
*2.0f
);
60 azidx
[0] = (ALuint
)az
% azCount
[evidx
];
61 azidx
[1] = (azidx
[0] + 1) % azCount
[evidx
];
62 *azmu
= az
- (ALuint
)az
;
65 // Calculates static HRIR coefficients and delays for the given polar
66 // elevation and azimuth in radians. Linear interpolation is used to
67 // increase the apparent resolution of the HRIR dataset. The coefficients
68 // are also normalized and attenuated by the specified gain.
69 void GetLerpedHrtfCoeffs(ALfloat elevation
, ALfloat azimuth
, ALfloat gain
, ALfloat (*coeffs
)[2], ALuint
*delays
)
71 ALuint evidx
[2], azidx
[2];
73 ALuint lidx
[4], ridx
[4];
76 // Claculate elevation indices and interpolation factor.
77 CalcEvIndices(elevation
, evidx
, &mu
[2]);
79 // Calculate azimuth indices and interpolation factor for the first
81 CalcAzIndices(evidx
[0], azimuth
, azidx
, &mu
[0]);
83 // Calculate the first set of linear HRIR indices for left and right
85 lidx
[0] = evOffset
[evidx
[0]] + azidx
[0];
86 lidx
[1] = evOffset
[evidx
[0]] + azidx
[1];
87 ridx
[0] = evOffset
[evidx
[0]] + ((azCount
[evidx
[0]]-azidx
[0]) % azCount
[evidx
[0]]);
88 ridx
[1] = evOffset
[evidx
[0]] + ((azCount
[evidx
[0]]-azidx
[1]) % azCount
[evidx
[0]]);
90 // Calculate azimuth indices and interpolation factor for the second
92 CalcAzIndices(evidx
[1], azimuth
, azidx
, &mu
[1]);
94 // Calculate the second set of linear HRIR indices for left and right
96 lidx
[2] = evOffset
[evidx
[1]] + azidx
[0];
97 lidx
[3] = evOffset
[evidx
[1]] + azidx
[1];
98 ridx
[2] = evOffset
[evidx
[1]] + ((azCount
[evidx
[1]]-azidx
[0]) % azCount
[evidx
[1]]);
99 ridx
[3] = evOffset
[evidx
[1]] + ((azCount
[evidx
[1]]-azidx
[1]) % azCount
[evidx
[1]]);
101 // Calculate the normalized and attenuated HRIR coefficients using linear
102 // interpolation when there is enough gain to warrant it. Zero the
103 // coefficients if gain is too low.
106 ALdouble scale
= gain
* (1.0/32767.0);
107 for(i
= 0;i
< HRIR_LENGTH
;i
++)
109 coeffs
[i
][0] = lerp(lerp(Hrtf
.coeffs
[lidx
[0]][i
], Hrtf
.coeffs
[lidx
[1]][i
], mu
[0]),
110 lerp(Hrtf
.coeffs
[lidx
[2]][i
], Hrtf
.coeffs
[lidx
[3]][i
], mu
[1]),
112 coeffs
[i
][1] = lerp(lerp(Hrtf
.coeffs
[ridx
[0]][i
], Hrtf
.coeffs
[ridx
[1]][i
], mu
[0]),
113 lerp(Hrtf
.coeffs
[ridx
[2]][i
], Hrtf
.coeffs
[ridx
[3]][i
], mu
[1]),
119 for(i
= 0;i
< HRIR_LENGTH
;i
++)
126 // Calculate the HRIR delays using linear interpolation.
127 delays
[0] = (ALuint
)(lerp(lerp(Hrtf
.delays
[lidx
[0]], Hrtf
.delays
[lidx
[1]], mu
[0]),
128 lerp(Hrtf
.delays
[lidx
[2]], Hrtf
.delays
[lidx
[3]], mu
[1]),
130 delays
[1] = (ALuint
)(lerp(lerp(Hrtf
.delays
[ridx
[0]], Hrtf
.delays
[ridx
[1]], mu
[0]),
131 lerp(Hrtf
.delays
[ridx
[2]], Hrtf
.delays
[ridx
[3]], mu
[1]),
135 ALCboolean
IsHrtfCompatible(ALCdevice
*device
)
137 if(device
->FmtChans
== DevFmtStereo
&& device
->Frequency
== Hrtf
.sampleRate
)
147 str
= GetConfigValue(NULL
, "hrtf_tables", "");
150 f
= fopen(str
, "rb");
152 ERR("Could not open %s\n", str
);
156 const ALubyte maxDelay
= SRC_HISTORY_LENGTH
;
157 ALboolean failed
= AL_FALSE
;
161 newdata
.sampleRate
= 44100;
162 for(i
= 0;i
< HRIR_COUNT
;i
++)
164 for(j
= 0;j
< HRIR_LENGTH
;j
++)
169 newdata
.coeffs
[i
][j
] = val
;
172 for(i
= 0;i
< HRIR_COUNT
;i
++)
176 newdata
.delays
[i
] = val
;
179 ERR("Invalid delay at idx %zu: %u (max: %u), in %s\n", i
, val
, maxDelay
, str
);
185 ERR("Premature end of data while reading %s\n", str
);