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
38 /* Current data set limits defined by the makehrtf utility. */
39 #define MIN_IR_SIZE (8)
40 #define MAX_IR_SIZE (128)
41 #define MOD_IR_SIZE (8)
43 #define MIN_EV_COUNT (5)
44 #define MAX_EV_COUNT (128)
46 #define MIN_AZ_COUNT (1)
47 #define MAX_AZ_COUNT (128)
54 const ALubyte
*azCount
;
55 const ALushort
*evOffset
;
56 const ALshort
*coeffs
;
57 const ALubyte
*delays
;
62 static const ALchar magicMarker
[8] = "MinPHR01";
64 /* Define the default HRTF:
65 * ALubyte defaultAzCount [DefaultHrtf.evCount]
66 * ALushort defaultEvOffset [DefaultHrtf.evCount]
67 * ALshort defaultCoeffs [DefaultHrtf.irCount * defaultHrtf.irSize]
68 * ALubyte defaultDelays [DefaultHrtf.irCount]
70 * struct Hrtf DefaultHrtf
72 #include "hrtf_tables.inc"
74 static struct Hrtf
*LoadedHrtfs
= NULL
;
76 /* Calculate the elevation indices given the polar elevation in radians.
77 * This will return two indices between 0 and (Hrtf->evCount - 1) and an
78 * interpolation factor between 0.0 and 1.0.
80 static void CalcEvIndices(const struct Hrtf
*Hrtf
, ALfloat ev
, ALuint
*evidx
, ALfloat
*evmu
)
82 ev
= (F_PI_2
+ ev
) * (Hrtf
->evCount
-1) / F_PI
;
83 evidx
[0] = fastf2u(ev
);
84 evidx
[1] = minu(evidx
[0] + 1, Hrtf
->evCount
-1);
85 *evmu
= ev
- evidx
[0];
88 /* Calculate the azimuth indices given the polar azimuth in radians. This
89 * will return two indices between 0 and (Hrtf->azCount[ei] - 1) and an
90 * interpolation factor between 0.0 and 1.0.
92 static void CalcAzIndices(const struct Hrtf
*Hrtf
, ALuint evidx
, ALfloat az
, ALuint
*azidx
, ALfloat
*azmu
)
94 az
= (F_PI
*2.0f
+ az
) * Hrtf
->azCount
[evidx
] / (F_PI
*2.0f
);
95 azidx
[0] = fastf2u(az
) % Hrtf
->azCount
[evidx
];
96 azidx
[1] = (azidx
[0] + 1) % Hrtf
->azCount
[evidx
];
97 *azmu
= az
- floorf(az
);
100 /* Calculates the normalized HRTF transition factor (delta) from the changes
101 * in gain and listener to source angle between updates. The result is a
102 * normalized delta factor that can be used to calculate moving HRIR stepping
105 ALfloat
CalcHrtfDelta(ALfloat oldGain
, ALfloat newGain
, const ALfloat olddir
[3], const ALfloat newdir
[3])
107 ALfloat gainChange
, angleChange
, change
;
109 // Calculate the normalized dB gain change.
110 newGain
= maxf(newGain
, 0.0001f
);
111 oldGain
= maxf(oldGain
, 0.0001f
);
112 gainChange
= fabsf(log10f(newGain
/ oldGain
) / log10f(0.0001f
));
114 // Calculate the normalized listener to source angle change when there is
115 // enough gain to notice it.
117 if(gainChange
> 0.0001f
|| newGain
> 0.0001f
)
119 // No angle change when the directions are equal or degenerate (when
120 // both have zero length).
121 if(newdir
[0]-olddir
[0] || newdir
[1]-olddir
[1] || newdir
[2]-olddir
[2])
122 angleChange
= acosf(olddir
[0]*newdir
[0] +
123 olddir
[1]*newdir
[1] +
124 olddir
[2]*newdir
[2]) / F_PI
;
128 // Use the largest of the two changes for the delta factor, and apply a
129 // significance shaping function to it.
130 change
= maxf(angleChange
* 25.0f
, gainChange
) * 2.0f
;
131 return minf(change
, 1.0f
);
134 /* Calculates static HRIR coefficients and delays for the given polar
135 * elevation and azimuth in radians. Linear interpolation is used to
136 * increase the apparent resolution of the HRIR data set. The coefficients
137 * are also normalized and attenuated by the specified gain.
139 void GetLerpedHrtfCoeffs(const struct Hrtf
*Hrtf
, ALfloat elevation
, ALfloat azimuth
, ALfloat gain
, ALfloat (*coeffs
)[2], ALuint
*delays
)
141 ALuint evidx
[2], azidx
[2];
142 ALuint lidx
[4], ridx
[4];
143 ALfloat mu
[3], blend
[4];
146 // Claculate elevation indices and interpolation factor.
147 CalcEvIndices(Hrtf
, elevation
, evidx
, &mu
[2]);
149 // Calculate azimuth indices and interpolation factor for the first
151 CalcAzIndices(Hrtf
, evidx
[0], azimuth
, azidx
, &mu
[0]);
153 // Calculate the first set of linear HRIR indices for left and right
155 lidx
[0] = Hrtf
->evOffset
[evidx
[0]] + azidx
[0];
156 lidx
[1] = Hrtf
->evOffset
[evidx
[0]] + azidx
[1];
157 ridx
[0] = Hrtf
->evOffset
[evidx
[0]] + ((Hrtf
->azCount
[evidx
[0]]-azidx
[0]) % Hrtf
->azCount
[evidx
[0]]);
158 ridx
[1] = Hrtf
->evOffset
[evidx
[0]] + ((Hrtf
->azCount
[evidx
[0]]-azidx
[1]) % Hrtf
->azCount
[evidx
[0]]);
160 // Calculate azimuth indices and interpolation factor for the second
162 CalcAzIndices(Hrtf
, evidx
[1], azimuth
, azidx
, &mu
[1]);
164 // Calculate the second set of linear HRIR indices for left and right
166 lidx
[2] = Hrtf
->evOffset
[evidx
[1]] + azidx
[0];
167 lidx
[3] = Hrtf
->evOffset
[evidx
[1]] + azidx
[1];
168 ridx
[2] = Hrtf
->evOffset
[evidx
[1]] + ((Hrtf
->azCount
[evidx
[1]]-azidx
[0]) % Hrtf
->azCount
[evidx
[1]]);
169 ridx
[3] = Hrtf
->evOffset
[evidx
[1]] + ((Hrtf
->azCount
[evidx
[1]]-azidx
[1]) % Hrtf
->azCount
[evidx
[1]]);
171 /* Calculate 4 blending weights for 2D bilinear interpolation. */
172 blend
[0] = (1.0f
-mu
[0]) * (1.0f
-mu
[2]);
173 blend
[1] = ( mu
[0]) * (1.0f
-mu
[2]);
174 blend
[2] = (1.0f
-mu
[1]) * ( mu
[2]);
175 blend
[3] = ( mu
[1]) * ( mu
[2]);
177 /* Calculate the HRIR delays using linear interpolation. */
178 delays
[0] = fastf2u(Hrtf
->delays
[lidx
[0]]*blend
[0] + Hrtf
->delays
[lidx
[1]]*blend
[1] +
179 Hrtf
->delays
[lidx
[2]]*blend
[2] + Hrtf
->delays
[lidx
[3]]*blend
[3] +
180 0.5f
) << HRTFDELAY_BITS
;
181 delays
[1] = fastf2u(Hrtf
->delays
[ridx
[0]]*blend
[0] + Hrtf
->delays
[ridx
[1]]*blend
[1] +
182 Hrtf
->delays
[ridx
[2]]*blend
[2] + Hrtf
->delays
[ridx
[3]]*blend
[3] +
183 0.5f
) << HRTFDELAY_BITS
;
185 /* Calculate the sample offsets for the HRIR indices. */
186 lidx
[0] *= Hrtf
->irSize
;
187 lidx
[1] *= Hrtf
->irSize
;
188 lidx
[2] *= Hrtf
->irSize
;
189 lidx
[3] *= Hrtf
->irSize
;
190 ridx
[0] *= Hrtf
->irSize
;
191 ridx
[1] *= Hrtf
->irSize
;
192 ridx
[2] *= Hrtf
->irSize
;
193 ridx
[3] *= Hrtf
->irSize
;
195 /* Calculate the normalized and attenuated HRIR coefficients using linear
196 * interpolation when there is enough gain to warrant it. Zero the
197 * coefficients if gain is too low.
201 gain
*= 1.0f
/32767.0f
;
202 for(i
= 0;i
< Hrtf
->irSize
;i
++)
204 coeffs
[i
][0] = (Hrtf
->coeffs
[lidx
[0]+i
]*blend
[0] +
205 Hrtf
->coeffs
[lidx
[1]+i
]*blend
[1] +
206 Hrtf
->coeffs
[lidx
[2]+i
]*blend
[2] +
207 Hrtf
->coeffs
[lidx
[3]+i
]*blend
[3]) * gain
;
208 coeffs
[i
][1] = (Hrtf
->coeffs
[ridx
[0]+i
]*blend
[0] +
209 Hrtf
->coeffs
[ridx
[1]+i
]*blend
[1] +
210 Hrtf
->coeffs
[ridx
[2]+i
]*blend
[2] +
211 Hrtf
->coeffs
[ridx
[3]+i
]*blend
[3]) * gain
;
216 for(i
= 0;i
< Hrtf
->irSize
;i
++)
224 /* Calculates the moving HRIR target coefficients, target delays, and
225 * stepping values for the given polar elevation and azimuth in radians.
226 * Linear interpolation is used to increase the apparent resolution of the
227 * HRIR data set. The coefficients are also normalized and attenuated by the
228 * specified gain. Stepping resolution and count is determined using the
229 * given delta factor between 0.0 and 1.0.
231 ALuint
GetMovingHrtfCoeffs(const struct Hrtf
*Hrtf
, ALfloat elevation
, ALfloat azimuth
, ALfloat gain
, ALfloat delta
, ALint counter
, ALfloat (*coeffs
)[2], ALuint
*delays
, ALfloat (*coeffStep
)[2], ALint
*delayStep
)
233 ALuint evidx
[2], azidx
[2];
234 ALuint lidx
[4], ridx
[4];
235 ALfloat mu
[3], blend
[4];
240 // Claculate elevation indices and interpolation factor.
241 CalcEvIndices(Hrtf
, elevation
, evidx
, &mu
[2]);
243 // Calculate azimuth indices and interpolation factor for the first
245 CalcAzIndices(Hrtf
, evidx
[0], azimuth
, azidx
, &mu
[0]);
247 // Calculate the first set of linear HRIR indices for left and right
249 lidx
[0] = Hrtf
->evOffset
[evidx
[0]] + azidx
[0];
250 lidx
[1] = Hrtf
->evOffset
[evidx
[0]] + azidx
[1];
251 ridx
[0] = Hrtf
->evOffset
[evidx
[0]] + ((Hrtf
->azCount
[evidx
[0]]-azidx
[0]) % Hrtf
->azCount
[evidx
[0]]);
252 ridx
[1] = Hrtf
->evOffset
[evidx
[0]] + ((Hrtf
->azCount
[evidx
[0]]-azidx
[1]) % Hrtf
->azCount
[evidx
[0]]);
254 // Calculate azimuth indices and interpolation factor for the second
256 CalcAzIndices(Hrtf
, evidx
[1], azimuth
, azidx
, &mu
[1]);
258 // Calculate the second set of linear HRIR indices for left and right
260 lidx
[2] = Hrtf
->evOffset
[evidx
[1]] + azidx
[0];
261 lidx
[3] = Hrtf
->evOffset
[evidx
[1]] + azidx
[1];
262 ridx
[2] = Hrtf
->evOffset
[evidx
[1]] + ((Hrtf
->azCount
[evidx
[1]]-azidx
[0]) % Hrtf
->azCount
[evidx
[1]]);
263 ridx
[3] = Hrtf
->evOffset
[evidx
[1]] + ((Hrtf
->azCount
[evidx
[1]]-azidx
[1]) % Hrtf
->azCount
[evidx
[1]]);
265 // Calculate the stepping parameters.
266 delta
= maxf(floorf(delta
*(Hrtf
->sampleRate
*0.015f
) + 0.5f
), 1.0f
);
269 /* Calculate 4 blending weights for 2D bilinear interpolation. */
270 blend
[0] = (1.0f
-mu
[0]) * (1.0f
-mu
[2]);
271 blend
[1] = ( mu
[0]) * (1.0f
-mu
[2]);
272 blend
[2] = (1.0f
-mu
[1]) * ( mu
[2]);
273 blend
[3] = ( mu
[1]) * ( mu
[2]);
275 /* Calculate the HRIR delays using linear interpolation. Then calculate
276 * the delay stepping values using the target and previous running
279 left
= (ALfloat
)(delays
[0] - (delayStep
[0] * counter
));
280 right
= (ALfloat
)(delays
[1] - (delayStep
[1] * counter
));
282 delays
[0] = fastf2u(Hrtf
->delays
[lidx
[0]]*blend
[0] + Hrtf
->delays
[lidx
[1]]*blend
[1] +
283 Hrtf
->delays
[lidx
[2]]*blend
[2] + Hrtf
->delays
[lidx
[3]]*blend
[3] +
284 0.5f
) << HRTFDELAY_BITS
;
285 delays
[1] = fastf2u(Hrtf
->delays
[ridx
[0]]*blend
[0] + Hrtf
->delays
[ridx
[1]]*blend
[1] +
286 Hrtf
->delays
[ridx
[2]]*blend
[2] + Hrtf
->delays
[ridx
[3]]*blend
[3] +
287 0.5f
) << HRTFDELAY_BITS
;
289 delayStep
[0] = fastf2i(step
* (delays
[0] - left
));
290 delayStep
[1] = fastf2i(step
* (delays
[1] - right
));
292 /* Calculate the sample offsets for the HRIR indices. */
293 lidx
[0] *= Hrtf
->irSize
;
294 lidx
[1] *= Hrtf
->irSize
;
295 lidx
[2] *= Hrtf
->irSize
;
296 lidx
[3] *= Hrtf
->irSize
;
297 ridx
[0] *= Hrtf
->irSize
;
298 ridx
[1] *= Hrtf
->irSize
;
299 ridx
[2] *= Hrtf
->irSize
;
300 ridx
[3] *= Hrtf
->irSize
;
302 /* Calculate the normalized and attenuated target HRIR coefficients using
303 * linear interpolation when there is enough gain to warrant it. Zero
304 * the target coefficients if gain is too low. Then calculate the
305 * coefficient stepping values using the target and previous running
310 gain
*= 1.0f
/32767.0f
;
311 for(i
= 0;i
< HRIR_LENGTH
;i
++)
313 left
= coeffs
[i
][0] - (coeffStep
[i
][0] * counter
);
314 right
= coeffs
[i
][1] - (coeffStep
[i
][1] * counter
);
316 coeffs
[i
][0] = (Hrtf
->coeffs
[lidx
[0]+i
]*blend
[0] +
317 Hrtf
->coeffs
[lidx
[1]+i
]*blend
[1] +
318 Hrtf
->coeffs
[lidx
[2]+i
]*blend
[2] +
319 Hrtf
->coeffs
[lidx
[3]+i
]*blend
[3]) * gain
;
320 coeffs
[i
][1] = (Hrtf
->coeffs
[ridx
[0]+i
]*blend
[0] +
321 Hrtf
->coeffs
[ridx
[1]+i
]*blend
[1] +
322 Hrtf
->coeffs
[ridx
[2]+i
]*blend
[2] +
323 Hrtf
->coeffs
[ridx
[3]+i
]*blend
[3]) * gain
;
325 coeffStep
[i
][0] = step
* (coeffs
[i
][0] - left
);
326 coeffStep
[i
][1] = step
* (coeffs
[i
][1] - right
);
331 for(i
= 0;i
< HRIR_LENGTH
;i
++)
333 left
= coeffs
[i
][0] - (coeffStep
[i
][0] * counter
);
334 right
= coeffs
[i
][1] - (coeffStep
[i
][1] * counter
);
339 coeffStep
[i
][0] = step
* -left
;
340 coeffStep
[i
][1] = step
* -right
;
344 /* The stepping count is the number of samples necessary for the HRIR to
345 * complete its transition. The mixer will only apply stepping for this
348 return fastf2u(delta
);
351 static struct Hrtf
*LoadHrtf(ALuint deviceRate
)
353 const char *fnamelist
= NULL
;
355 if(!ConfigValueStr(NULL
, "hrtf_tables", &fnamelist
))
357 while(*fnamelist
!= '\0')
359 const ALubyte maxDelay
= SRC_HISTORY_LENGTH
-1;
360 struct Hrtf
*Hrtf
= NULL
;
362 ALuint rate
= 0, irCount
= 0;
363 ALubyte irSize
= 0, evCount
= 0;
364 ALubyte
*azCount
= NULL
;
365 ALushort
*evOffset
= NULL
;
366 ALshort
*coeffs
= NULL
;
367 ALubyte
*delays
= NULL
;
368 char fname
[PATH_MAX
];
373 while(isspace(*fnamelist
) || *fnamelist
== ',')
376 while(*fnamelist
!= '\0' && *fnamelist
!= ',')
378 const char *next
= strpbrk(fnamelist
, "%,");
379 while(fnamelist
!= next
&& *fnamelist
&& i
< sizeof(fname
))
380 fname
[i
++] = *(fnamelist
++);
382 if(!next
|| *next
== ',')
389 int wrote
= snprintf(&fname
[i
], sizeof(fname
)-i
, "%u", deviceRate
);
390 i
+= minu(wrote
, sizeof(fname
)-i
);
393 else if(*next
== '%')
395 if(i
< sizeof(fname
))
400 ERR("Invalid marker '%%%c'\n", *next
);
403 i
= minu(i
, sizeof(fname
)-1);
405 while(i
> 0 && isspace(fname
[i
-1]))
412 TRACE("Loading %s...\n", fname
);
413 f
= fopen(fname
, "rb");
416 ERR("Could not open %s\n", fname
);
421 if(fread(magic
, 1, sizeof(magicMarker
), f
) != sizeof(magicMarker
))
423 ERR("Failed to read magic marker\n");
426 else if(memcmp(magic
, magicMarker
, sizeof(magicMarker
)) != 0)
429 ERR("Invalid magic marker: \"%s\"\n", magic
);
437 rate
|= fgetc(f
)<<16;
438 rate
|= fgetc(f
)<<24;
444 if(rate
!= deviceRate
)
446 ERR("HRIR rate does not match device rate: rate=%d (%d)\n",
450 if(irSize
< MIN_IR_SIZE
|| irSize
> MAX_IR_SIZE
|| (irSize
%MOD_IR_SIZE
))
452 ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
453 irSize
, MIN_IR_SIZE
, MAX_IR_SIZE
, MOD_IR_SIZE
);
456 if(evCount
< MIN_EV_COUNT
|| evCount
> MAX_EV_COUNT
)
458 ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
459 evCount
, MIN_EV_COUNT
, MAX_EV_COUNT
);
466 azCount
= malloc(sizeof(azCount
[0])*evCount
);
467 evOffset
= malloc(sizeof(evOffset
[0])*evCount
);
468 if(azCount
== NULL
|| evOffset
== NULL
)
470 ERR("Out of memory.\n");
477 for(i
= 0;i
< evCount
;i
++)
479 azCount
[i
] = fgetc(f
);
480 if(azCount
[i
] < MIN_AZ_COUNT
|| azCount
[i
] > MAX_AZ_COUNT
)
482 ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
483 i
, azCount
[i
], MIN_AZ_COUNT
, MAX_AZ_COUNT
);
492 irCount
= azCount
[0];
493 for(i
= 1;i
< evCount
;i
++)
495 evOffset
[i
] = evOffset
[i
-1] + azCount
[i
-1];
496 irCount
+= azCount
[i
];
499 coeffs
= malloc(sizeof(coeffs
[0])*irSize
*irCount
);
500 delays
= malloc(sizeof(delays
[0])*irCount
);
501 if(coeffs
== NULL
|| delays
== NULL
)
503 ERR("Out of memory.\n");
510 for(i
= 0;i
< irCount
*irSize
;i
+=irSize
)
512 for(j
= 0;j
< irSize
;j
++)
516 coeff
|= fgetc(f
)<<8;
520 for(i
= 0;i
< irCount
;i
++)
522 delays
[i
] = fgetc(f
);
523 if(delays
[i
] > maxDelay
)
525 ERR("Invalid delays[%d]: %d (%d)\n", i
, delays
[i
], maxDelay
);
532 ERR("Premature end of data\n");
542 Hrtf
= malloc(sizeof(struct Hrtf
));
545 ERR("Out of memory.\n");
552 Hrtf
->sampleRate
= rate
;
553 Hrtf
->irSize
= irSize
;
554 Hrtf
->evCount
= evCount
;
555 Hrtf
->azCount
= azCount
;
556 Hrtf
->evOffset
= evOffset
;
557 Hrtf
->coeffs
= coeffs
;
558 Hrtf
->delays
= delays
;
559 Hrtf
->next
= LoadedHrtfs
;
561 TRACE("Loaded HRTF support for format: %s %uhz\n",
562 DevFmtChannelsString(DevFmtStereo
), Hrtf
->sampleRate
);
571 ERR("Failed to load %s\n", fname
);
577 const struct Hrtf
*GetHrtf(ALCdevice
*device
)
579 if(device
->FmtChans
== DevFmtStereo
)
581 struct Hrtf
*Hrtf
= LoadedHrtfs
;
584 if(device
->Frequency
== Hrtf
->sampleRate
)
589 Hrtf
= LoadHrtf(device
->Frequency
);
593 if(device
->Frequency
== DefaultHrtf
.sampleRate
)
596 ERR("Incompatible format: %s %uhz\n",
597 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
603 struct Hrtf
*Hrtf
= NULL
;
605 while((Hrtf
=LoadedHrtfs
) != NULL
)
607 LoadedHrtfs
= Hrtf
->next
;
608 free((void*)Hrtf
->azCount
);
609 free((void*)Hrtf
->evOffset
);
610 free((void*)Hrtf
->coeffs
);
611 free((void*)Hrtf
->delays
);
616 ALuint
GetHrtfIrSize (const struct Hrtf
*Hrtf
)