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
32 /* Current data set limits defined by the makehrtf utility. */
33 #define MIN_IR_SIZE (8)
34 #define MAX_IR_SIZE (128)
35 #define MOD_IR_SIZE (8)
37 #define MIN_EV_COUNT (5)
38 #define MAX_EV_COUNT (128)
40 #define MIN_AZ_COUNT (1)
41 #define MAX_AZ_COUNT (128)
48 const ALubyte
*azCount
;
49 const ALushort
*evOffset
;
50 const ALshort
*coeffs
;
51 const ALubyte
*delays
;
56 static const ALchar magicMarker
[8] = "MinPHR01";
58 /* Define the default HRTF:
59 * ALubyte defaultAzCount [DefaultHrtf.evCount]
60 * ALushort defaultEvOffset [DefaultHrtf.evCount]
61 * ALshort defaultCoeffs [DefaultHrtf.irCount * defaultHrtf.irSize]
62 * ALubyte defaultDelays [DefaultHrtf.irCount]
64 * struct Hrtf DefaultHrtf
66 #include "hrtf_tables.inc"
68 static struct Hrtf
*LoadedHrtfs
= NULL
;
70 /* Calculate the elevation indices given the polar elevation in radians.
71 * This will return two indices between 0 and (Hrtf->evCount - 1) and an
72 * interpolation factor between 0.0 and 1.0.
74 static void CalcEvIndices(const struct Hrtf
*Hrtf
, ALfloat ev
, ALuint
*evidx
, ALfloat
*evmu
)
76 ev
= (F_PI_2
+ ev
) * (Hrtf
->evCount
-1) / F_PI
;
77 evidx
[0] = fastf2u(ev
);
78 evidx
[1] = minu(evidx
[0] + 1, Hrtf
->evCount
-1);
79 *evmu
= ev
- evidx
[0];
82 /* Calculate the azimuth indices given the polar azimuth in radians. This
83 * will return two indices between 0 and (Hrtf->azCount[ei] - 1) and an
84 * interpolation factor between 0.0 and 1.0.
86 static void CalcAzIndices(const struct Hrtf
*Hrtf
, ALuint evidx
, ALfloat az
, ALuint
*azidx
, ALfloat
*azmu
)
88 az
= (F_PI
*2.0f
+ az
) * Hrtf
->azCount
[evidx
] / (F_PI
*2.0f
);
89 azidx
[0] = fastf2u(az
) % Hrtf
->azCount
[evidx
];
90 azidx
[1] = (azidx
[0] + 1) % Hrtf
->azCount
[evidx
];
91 *azmu
= az
- floorf(az
);
94 /* Calculates the normalized HRTF transition factor (delta) from the changes
95 * in gain and listener to source angle between updates. The result is a
96 * normalized delta factor that can be used to calculate moving HRIR stepping
99 ALfloat
CalcHrtfDelta(ALfloat oldGain
, ALfloat newGain
, const ALfloat olddir
[3], const ALfloat newdir
[3])
101 ALfloat gainChange
, angleChange
, change
;
103 // Calculate the normalized dB gain change.
104 newGain
= maxf(newGain
, 0.0001f
);
105 oldGain
= maxf(oldGain
, 0.0001f
);
106 gainChange
= fabsf(log10f(newGain
/ oldGain
) / log10f(0.0001f
));
108 // Calculate the normalized listener to source angle change when there is
109 // enough gain to notice it.
111 if(gainChange
> 0.0001f
|| newGain
> 0.0001f
)
113 // No angle change when the directions are equal or degenerate (when
114 // both have zero length).
115 if(newdir
[0]-olddir
[0] || newdir
[1]-olddir
[1] || newdir
[2]-olddir
[2])
116 angleChange
= acosf(olddir
[0]*newdir
[0] +
117 olddir
[1]*newdir
[1] +
118 olddir
[2]*newdir
[2]) / F_PI
;
122 // Use the largest of the two changes for the delta factor, and apply a
123 // significance shaping function to it.
124 change
= maxf(angleChange
* 25.0f
, gainChange
) * 2.0f
;
125 return minf(change
, 1.0f
);
128 /* Calculates static HRIR coefficients and delays for the given polar
129 * elevation and azimuth in radians. Linear interpolation is used to
130 * increase the apparent resolution of the HRIR data set. The coefficients
131 * are also normalized and attenuated by the specified gain.
133 void GetLerpedHrtfCoeffs(const struct Hrtf
*Hrtf
, ALfloat elevation
, ALfloat azimuth
, ALfloat gain
, ALfloat (*coeffs
)[2], ALuint
*delays
)
135 ALuint evidx
[2], azidx
[2];
136 ALuint lidx
[4], ridx
[4];
137 ALfloat mu
[3], blend
[4];
140 // Claculate elevation indices and interpolation factor.
141 CalcEvIndices(Hrtf
, elevation
, evidx
, &mu
[2]);
143 // Calculate azimuth indices and interpolation factor for the first
145 CalcAzIndices(Hrtf
, evidx
[0], azimuth
, azidx
, &mu
[0]);
147 // Calculate the first set of linear HRIR indices for left and right
149 lidx
[0] = Hrtf
->evOffset
[evidx
[0]] + azidx
[0];
150 lidx
[1] = Hrtf
->evOffset
[evidx
[0]] + azidx
[1];
151 ridx
[0] = Hrtf
->evOffset
[evidx
[0]] + ((Hrtf
->azCount
[evidx
[0]]-azidx
[0]) % Hrtf
->azCount
[evidx
[0]]);
152 ridx
[1] = Hrtf
->evOffset
[evidx
[0]] + ((Hrtf
->azCount
[evidx
[0]]-azidx
[1]) % Hrtf
->azCount
[evidx
[0]]);
154 // Calculate azimuth indices and interpolation factor for the second
156 CalcAzIndices(Hrtf
, evidx
[1], azimuth
, azidx
, &mu
[1]);
158 // Calculate the second set of linear HRIR indices for left and right
160 lidx
[2] = Hrtf
->evOffset
[evidx
[1]] + azidx
[0];
161 lidx
[3] = Hrtf
->evOffset
[evidx
[1]] + azidx
[1];
162 ridx
[2] = Hrtf
->evOffset
[evidx
[1]] + ((Hrtf
->azCount
[evidx
[1]]-azidx
[0]) % Hrtf
->azCount
[evidx
[1]]);
163 ridx
[3] = Hrtf
->evOffset
[evidx
[1]] + ((Hrtf
->azCount
[evidx
[1]]-azidx
[1]) % Hrtf
->azCount
[evidx
[1]]);
165 /* Calculate 4 blending weights for 2D bilinear interpolation. */
166 blend
[0] = (1.0f
-mu
[0]) * (1.0f
-mu
[2]);
167 blend
[1] = ( mu
[0]) * (1.0f
-mu
[2]);
168 blend
[2] = (1.0f
-mu
[1]) * ( mu
[2]);
169 blend
[3] = ( mu
[1]) * ( mu
[2]);
171 /* Calculate the HRIR delays using linear interpolation. */
172 delays
[0] = fastf2u(Hrtf
->delays
[lidx
[0]]*blend
[0] + Hrtf
->delays
[lidx
[1]]*blend
[1] +
173 Hrtf
->delays
[lidx
[2]]*blend
[2] + Hrtf
->delays
[lidx
[3]]*blend
[3] +
174 0.5f
) << HRTFDELAY_BITS
;
175 delays
[1] = fastf2u(Hrtf
->delays
[ridx
[0]]*blend
[0] + Hrtf
->delays
[ridx
[1]]*blend
[1] +
176 Hrtf
->delays
[ridx
[2]]*blend
[2] + Hrtf
->delays
[ridx
[3]]*blend
[3] +
177 0.5f
) << HRTFDELAY_BITS
;
179 /* Calculate the sample offsets for the HRIR indices. */
180 lidx
[0] *= Hrtf
->irSize
;
181 lidx
[1] *= Hrtf
->irSize
;
182 lidx
[2] *= Hrtf
->irSize
;
183 lidx
[3] *= Hrtf
->irSize
;
184 ridx
[0] *= Hrtf
->irSize
;
185 ridx
[1] *= Hrtf
->irSize
;
186 ridx
[2] *= Hrtf
->irSize
;
187 ridx
[3] *= Hrtf
->irSize
;
189 /* Calculate the normalized and attenuated HRIR coefficients using linear
190 * interpolation when there is enough gain to warrant it. Zero the
191 * coefficients if gain is too low.
195 gain
*= 1.0f
/32767.0f
;
196 for(i
= 0;i
< Hrtf
->irSize
;i
++)
198 coeffs
[i
][0] = (Hrtf
->coeffs
[lidx
[0]+i
]*blend
[0] +
199 Hrtf
->coeffs
[lidx
[1]+i
]*blend
[1] +
200 Hrtf
->coeffs
[lidx
[2]+i
]*blend
[2] +
201 Hrtf
->coeffs
[lidx
[3]+i
]*blend
[3]) * gain
;
202 coeffs
[i
][1] = (Hrtf
->coeffs
[ridx
[0]+i
]*blend
[0] +
203 Hrtf
->coeffs
[ridx
[1]+i
]*blend
[1] +
204 Hrtf
->coeffs
[ridx
[2]+i
]*blend
[2] +
205 Hrtf
->coeffs
[ridx
[3]+i
]*blend
[3]) * gain
;
210 for(i
= 0;i
< Hrtf
->irSize
;i
++)
218 /* Calculates the moving HRIR target coefficients, target delays, and
219 * stepping values for the given polar elevation and azimuth in radians.
220 * Linear interpolation is used to increase the apparent resolution of the
221 * HRIR data set. The coefficients are also normalized and attenuated by the
222 * specified gain. Stepping resolution and count is determined using the
223 * given delta factor between 0.0 and 1.0.
225 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
)
227 ALuint evidx
[2], azidx
[2];
228 ALuint lidx
[4], ridx
[4];
229 ALfloat mu
[3], blend
[4];
234 // Claculate elevation indices and interpolation factor.
235 CalcEvIndices(Hrtf
, elevation
, evidx
, &mu
[2]);
237 // Calculate azimuth indices and interpolation factor for the first
239 CalcAzIndices(Hrtf
, evidx
[0], azimuth
, azidx
, &mu
[0]);
241 // Calculate the first set of linear HRIR indices for left and right
243 lidx
[0] = Hrtf
->evOffset
[evidx
[0]] + azidx
[0];
244 lidx
[1] = Hrtf
->evOffset
[evidx
[0]] + azidx
[1];
245 ridx
[0] = Hrtf
->evOffset
[evidx
[0]] + ((Hrtf
->azCount
[evidx
[0]]-azidx
[0]) % Hrtf
->azCount
[evidx
[0]]);
246 ridx
[1] = Hrtf
->evOffset
[evidx
[0]] + ((Hrtf
->azCount
[evidx
[0]]-azidx
[1]) % Hrtf
->azCount
[evidx
[0]]);
248 // Calculate azimuth indices and interpolation factor for the second
250 CalcAzIndices(Hrtf
, evidx
[1], azimuth
, azidx
, &mu
[1]);
252 // Calculate the second set of linear HRIR indices for left and right
254 lidx
[2] = Hrtf
->evOffset
[evidx
[1]] + azidx
[0];
255 lidx
[3] = Hrtf
->evOffset
[evidx
[1]] + azidx
[1];
256 ridx
[2] = Hrtf
->evOffset
[evidx
[1]] + ((Hrtf
->azCount
[evidx
[1]]-azidx
[0]) % Hrtf
->azCount
[evidx
[1]]);
257 ridx
[3] = Hrtf
->evOffset
[evidx
[1]] + ((Hrtf
->azCount
[evidx
[1]]-azidx
[1]) % Hrtf
->azCount
[evidx
[1]]);
259 // Calculate the stepping parameters.
260 delta
= maxf(floorf(delta
*(Hrtf
->sampleRate
*0.015f
) + 0.5f
), 1.0f
);
263 /* Calculate 4 blending weights for 2D bilinear interpolation. */
264 blend
[0] = (1.0f
-mu
[0]) * (1.0f
-mu
[2]);
265 blend
[1] = ( mu
[0]) * (1.0f
-mu
[2]);
266 blend
[2] = (1.0f
-mu
[1]) * ( mu
[2]);
267 blend
[3] = ( mu
[1]) * ( mu
[2]);
269 /* Calculate the HRIR delays using linear interpolation. Then calculate
270 * the delay stepping values using the target and previous running
273 left
= (ALfloat
)(delays
[0] - (delayStep
[0] * counter
));
274 right
= (ALfloat
)(delays
[1] - (delayStep
[1] * counter
));
276 delays
[0] = fastf2u(Hrtf
->delays
[lidx
[0]]*blend
[0] + Hrtf
->delays
[lidx
[1]]*blend
[1] +
277 Hrtf
->delays
[lidx
[2]]*blend
[2] + Hrtf
->delays
[lidx
[3]]*blend
[3] +
278 0.5f
) << HRTFDELAY_BITS
;
279 delays
[1] = fastf2u(Hrtf
->delays
[ridx
[0]]*blend
[0] + Hrtf
->delays
[ridx
[1]]*blend
[1] +
280 Hrtf
->delays
[ridx
[2]]*blend
[2] + Hrtf
->delays
[ridx
[3]]*blend
[3] +
281 0.5f
) << HRTFDELAY_BITS
;
283 delayStep
[0] = fastf2i(step
* (delays
[0] - left
));
284 delayStep
[1] = fastf2i(step
* (delays
[1] - right
));
286 /* Calculate the sample offsets for the HRIR indices. */
287 lidx
[0] *= Hrtf
->irSize
;
288 lidx
[1] *= Hrtf
->irSize
;
289 lidx
[2] *= Hrtf
->irSize
;
290 lidx
[3] *= Hrtf
->irSize
;
291 ridx
[0] *= Hrtf
->irSize
;
292 ridx
[1] *= Hrtf
->irSize
;
293 ridx
[2] *= Hrtf
->irSize
;
294 ridx
[3] *= Hrtf
->irSize
;
296 /* Calculate the normalized and attenuated target HRIR coefficients using
297 * linear interpolation when there is enough gain to warrant it. Zero
298 * the target coefficients if gain is too low. Then calculate the
299 * coefficient stepping values using the target and previous running
304 gain
*= 1.0f
/32767.0f
;
305 for(i
= 0;i
< HRIR_LENGTH
;i
++)
307 left
= coeffs
[i
][0] - (coeffStep
[i
][0] * counter
);
308 right
= coeffs
[i
][1] - (coeffStep
[i
][1] * counter
);
310 coeffs
[i
][0] = (Hrtf
->coeffs
[lidx
[0]+i
]*blend
[0] +
311 Hrtf
->coeffs
[lidx
[1]+i
]*blend
[1] +
312 Hrtf
->coeffs
[lidx
[2]+i
]*blend
[2] +
313 Hrtf
->coeffs
[lidx
[3]+i
]*blend
[3]) * gain
;
314 coeffs
[i
][1] = (Hrtf
->coeffs
[ridx
[0]+i
]*blend
[0] +
315 Hrtf
->coeffs
[ridx
[1]+i
]*blend
[1] +
316 Hrtf
->coeffs
[ridx
[2]+i
]*blend
[2] +
317 Hrtf
->coeffs
[ridx
[3]+i
]*blend
[3]) * gain
;
319 coeffStep
[i
][0] = step
* (coeffs
[i
][0] - left
);
320 coeffStep
[i
][1] = step
* (coeffs
[i
][1] - right
);
325 for(i
= 0;i
< HRIR_LENGTH
;i
++)
327 left
= coeffs
[i
][0] - (coeffStep
[i
][0] * counter
);
328 right
= coeffs
[i
][1] - (coeffStep
[i
][1] * counter
);
333 coeffStep
[i
][0] = step
* -left
;
334 coeffStep
[i
][1] = step
* -right
;
338 /* The stepping count is the number of samples necessary for the HRIR to
339 * complete its transition. The mixer will only apply stepping for this
342 return fastf2u(delta
);
345 static struct Hrtf
*LoadHrtf(ALuint deviceRate
)
347 const char *fnamelist
= NULL
;
348 char rateStr
[16 + 1];
351 rateLen
= minu(snprintf(rateStr
, 16, "%u", deviceRate
), 16);
352 ConfigValueStr(NULL
, "hrtf_tables", &fnamelist
);
353 while(*fnamelist
!= '\0')
355 const ALubyte maxDelay
= SRC_HISTORY_LENGTH
-1;
356 struct Hrtf
*Hrtf
= NULL
;
360 ALuint rate
= 0, irCount
;
361 ALubyte irSize
= 0, evCount
= 0, *azCount
, *delays
;
367 while(isspace(*fnamelist
) || *fnamelist
== ',')
370 while(*fnamelist
!= '\0' && *fnamelist
!= ',')
374 if(*fnamelist
== '%' && *(fnamelist
+1) == 'r')
376 strncpy(&fname
[i
], rateStr
, minu(rateLen
, 256-i
));
377 i
+= minu(rateLen
, 256-i
);
382 fname
[i
] = *fnamelist
;
388 while(isspace(fname
[i
-1]))
395 TRACE("Loading %s\n", fname
);
396 f
= fopen(fname
, "rb");
399 ERR("Could not open %s\n", fname
);
408 if(fread(magic
, 1, sizeof(magicMarker
), f
) != sizeof(magicMarker
))
410 ERR("Failed to read magic marker\n");
413 else if(memcmp(magic
, magicMarker
, sizeof(magicMarker
)) != 0)
416 ERR("Invalid magic marker: \"%s\"\n", magic
);
424 rate
|= fgetc(f
)<<16;
425 rate
|= fgetc(f
)<<24;
431 if(rate
!= deviceRate
)
433 ERR("HRIR rate does not match device rate: rate=%d (%d)\n",
437 if(irSize
< MIN_IR_SIZE
|| irSize
> MAX_IR_SIZE
|| (irSize
%MOD_IR_SIZE
))
439 ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
440 irSize
, MIN_IR_SIZE
, MAX_IR_SIZE
, MOD_IR_SIZE
);
443 if(evCount
< MIN_EV_COUNT
|| evCount
> MAX_EV_COUNT
)
445 ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
446 evCount
, MIN_EV_COUNT
, MAX_EV_COUNT
);
453 azCount
= malloc(sizeof(azCount
[0])*evCount
);
454 evOffset
= malloc(sizeof(evOffset
[0])*evCount
);
455 if(azCount
== NULL
|| evOffset
== NULL
)
457 ERR("Out of memory.\n");
464 for(i
= 0;i
< evCount
;i
++)
466 azCount
[i
] = fgetc(f
);
467 if(azCount
[i
] < MIN_AZ_COUNT
|| azCount
[i
] > MAX_AZ_COUNT
)
469 ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
470 i
, azCount
[i
], MIN_AZ_COUNT
, MAX_AZ_COUNT
);
479 irCount
= azCount
[0];
480 for(i
= 1;i
< evCount
;i
++)
482 evOffset
[i
] = evOffset
[i
-1] + azCount
[i
-1];
483 irCount
+= azCount
[i
];
486 coeffs
= malloc(sizeof(coeffs
[0])*irSize
*irCount
);
487 delays
= malloc(sizeof(delays
[0])*irCount
);
488 if(coeffs
== NULL
|| delays
== NULL
)
490 ERR("Out of memory.\n");
497 for(i
= 0;i
< (ALsizei
)(irCount
*irSize
);i
+=irSize
)
499 for(j
= 0;j
< (ALsizei
)irSize
;j
++)
503 coeff
|= fgetc(f
)<<8;
507 for(i
= 0;i
< (ALsizei
)irCount
;i
++)
509 delays
[i
] = fgetc(f
);
510 if(delays
[i
] > maxDelay
)
512 ERR("Invalid delays[%d]: %d (%d)\n", i
, delays
[i
], maxDelay
);
519 ERR("Premature end of data\n");
529 Hrtf
= malloc(sizeof(struct Hrtf
));
532 ERR("Out of memory.\n");
539 Hrtf
->sampleRate
= rate
;
540 Hrtf
->irSize
= irSize
;
541 Hrtf
->evCount
= evCount
;
542 Hrtf
->azCount
= azCount
;
543 Hrtf
->evOffset
= evOffset
;
544 Hrtf
->coeffs
= coeffs
;
545 Hrtf
->delays
= delays
;
546 Hrtf
->next
= LoadedHrtfs
;
548 TRACE("Loaded HRTF support for format: %s %uhz\n",
549 DevFmtChannelsString(DevFmtStereo
), Hrtf
->sampleRate
);
558 ERR("Failed to load %s\n", fname
);
564 const struct Hrtf
*GetHrtf(ALCdevice
*device
)
566 if(device
->FmtChans
== DevFmtStereo
)
568 struct Hrtf
*Hrtf
= LoadedHrtfs
;
571 if(device
->Frequency
== Hrtf
->sampleRate
)
576 Hrtf
= LoadHrtf(device
->Frequency
);
580 if(device
->Frequency
== DefaultHrtf
.sampleRate
)
583 ERR("Incompatible format: %s %uhz\n",
584 DevFmtChannelsString(device
->FmtChans
), device
->Frequency
);
590 struct Hrtf
*Hrtf
= NULL
;
592 while((Hrtf
=LoadedHrtfs
) != NULL
)
594 LoadedHrtfs
= Hrtf
->next
;
595 free((void*)Hrtf
->azCount
);
596 free((void*)Hrtf
->evOffset
);
597 free((void*)Hrtf
->coeffs
);
598 free((void*)Hrtf
->delays
);
603 ALuint
GetHrtfIrSize (const struct Hrtf
*Hrtf
)