Use a different method for HRTF mixing
[openal-soft.git] / Alc / hrtf.c
blob2e4156a01e9e8fb2d32282eda0df4b20f25eb1b9
1 /**
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.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <stdlib.h>
24 #include <ctype.h>
26 #include "AL/al.h"
27 #include "AL/alc.h"
28 #include "alMain.h"
29 #include "alSource.h"
30 #include "alu.h"
31 #include "hrtf.h"
34 /* Current data set limits defined by the makehrtf utility. */
35 #define MIN_IR_SIZE (8)
36 #define MAX_IR_SIZE (128)
37 #define MOD_IR_SIZE (8)
39 #define MIN_EV_COUNT (5)
40 #define MAX_EV_COUNT (128)
42 #define MIN_AZ_COUNT (1)
43 #define MAX_AZ_COUNT (128)
45 struct Hrtf {
46 ALuint sampleRate;
47 ALuint irSize;
48 ALubyte evCount;
50 const ALubyte *azCount;
51 const ALushort *evOffset;
52 const ALshort *coeffs;
53 const ALubyte *delays;
55 struct Hrtf *next;
58 static const ALchar magicMarker00[8] = "MinPHR00";
59 static const ALchar magicMarker01[8] = "MinPHR01";
61 static struct Hrtf *LoadedHrtfs = NULL;
63 /* Calculate the elevation indices given the polar elevation in radians.
64 * This will return two indices between 0 and (evcount - 1) and an
65 * interpolation factor between 0.0 and 1.0.
67 static void CalcEvIndices(ALuint evcount, ALfloat ev, ALuint *evidx, ALfloat *evmu)
69 ev = (F_PI_2 + ev) * (evcount-1) / F_PI;
70 evidx[0] = fastf2u(ev);
71 evidx[1] = minu(evidx[0] + 1, evcount-1);
72 *evmu = ev - evidx[0];
75 /* Calculate the azimuth indices given the polar azimuth in radians. This
76 * will return two indices between 0 and (azcount - 1) and an interpolation
77 * factor between 0.0 and 1.0.
79 static void CalcAzIndices(ALuint azcount, ALfloat az, ALuint *azidx, ALfloat *azmu)
81 az = (F_2PI + az) * azcount / (F_2PI);
82 azidx[0] = fastf2u(az) % azcount;
83 azidx[1] = (azidx[0] + 1) % azcount;
84 *azmu = az - floorf(az);
87 /* Calculates static HRIR coefficients and delays for the given polar
88 * elevation and azimuth in radians. Linear interpolation is used to
89 * increase the apparent resolution of the HRIR data set. The coefficients
90 * are also normalized and attenuated by the specified gain.
92 void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat (*coeffs)[2], ALuint *delays)
94 ALuint evidx[2], lidx[4], ridx[4];
95 ALfloat mu[3], blend[4];
96 ALuint i;
98 /* Claculate elevation indices and interpolation factor. */
99 CalcEvIndices(Hrtf->evCount, elevation, evidx, &mu[2]);
101 for(i = 0;i < 2;i++)
103 ALuint azcount = Hrtf->azCount[evidx[i]];
104 ALuint evoffset = Hrtf->evOffset[evidx[i]];
105 ALuint azidx[2];
107 /* Calculate azimuth indices and interpolation factor for this elevation. */
108 CalcAzIndices(azcount, azimuth, azidx, &mu[i]);
110 /* Calculate a set of linear HRIR indices for left and right channels. */
111 lidx[i*2 + 0] = evoffset + azidx[0];
112 lidx[i*2 + 1] = evoffset + azidx[1];
113 ridx[i*2 + 0] = evoffset + ((azcount-azidx[0]) % azcount);
114 ridx[i*2 + 1] = evoffset + ((azcount-azidx[1]) % azcount);
117 /* Calculate 4 blending weights for 2D bilinear interpolation. */
118 blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]);
119 blend[1] = ( mu[0]) * (1.0f-mu[2]);
120 blend[2] = (1.0f-mu[1]) * ( mu[2]);
121 blend[3] = ( mu[1]) * ( mu[2]);
123 /* Calculate the HRIR delays using linear interpolation. */
124 delays[0] = fastf2u(Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] +
125 Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3] +
126 0.5f);
127 delays[1] = fastf2u(Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] +
128 Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3] +
129 0.5f);
131 /* Calculate the sample offsets for the HRIR indices. */
132 lidx[0] *= Hrtf->irSize;
133 lidx[1] *= Hrtf->irSize;
134 lidx[2] *= Hrtf->irSize;
135 lidx[3] *= Hrtf->irSize;
136 ridx[0] *= Hrtf->irSize;
137 ridx[1] *= Hrtf->irSize;
138 ridx[2] *= Hrtf->irSize;
139 ridx[3] *= Hrtf->irSize;
141 for(i = 0;i < Hrtf->irSize;i++)
143 ALfloat c;
144 c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] +
145 Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]);
146 coeffs[i][0] = c * (1.0f/32767.0f);
147 c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] +
148 Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]);
149 coeffs[i][1] = c * (1.0f/32767.0f);
154 static struct Hrtf *LoadHrtf00(FILE *f, ALuint deviceRate)
156 const ALubyte maxDelay = HRTF_HISTORY_LENGTH-1;
157 struct Hrtf *Hrtf = NULL;
158 ALboolean failed = AL_FALSE;
159 ALuint rate = 0, irCount = 0;
160 ALushort irSize = 0;
161 ALubyte evCount = 0;
162 ALubyte *azCount = NULL;
163 ALushort *evOffset = NULL;
164 ALshort *coeffs = NULL;
165 ALubyte *delays = NULL;
166 ALuint i, j;
168 rate = fgetc(f);
169 rate |= fgetc(f)<<8;
170 rate |= fgetc(f)<<16;
171 rate |= fgetc(f)<<24;
173 irCount = fgetc(f);
174 irCount |= fgetc(f)<<8;
176 irSize = fgetc(f);
177 irSize |= fgetc(f)<<8;
179 evCount = fgetc(f);
181 if(rate != deviceRate)
183 ERR("HRIR rate does not match device rate: rate=%d (%d)\n",
184 rate, deviceRate);
185 failed = AL_TRUE;
187 if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE))
189 ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
190 irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE);
191 failed = AL_TRUE;
193 if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT)
195 ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
196 evCount, MIN_EV_COUNT, MAX_EV_COUNT);
197 failed = AL_TRUE;
200 if(failed)
201 return NULL;
203 azCount = malloc(sizeof(azCount[0])*evCount);
204 evOffset = malloc(sizeof(evOffset[0])*evCount);
205 if(azCount == NULL || evOffset == NULL)
207 ERR("Out of memory.\n");
208 failed = AL_TRUE;
211 if(!failed)
213 evOffset[0] = fgetc(f);
214 evOffset[0] |= fgetc(f)<<8;
215 for(i = 1;i < evCount;i++)
217 evOffset[i] = fgetc(f);
218 evOffset[i] |= fgetc(f)<<8;
219 if(evOffset[i] <= evOffset[i-1])
221 ERR("Invalid evOffset: evOffset[%d]=%d (last=%d)\n",
222 i, evOffset[i], evOffset[i-1]);
223 failed = AL_TRUE;
226 azCount[i-1] = evOffset[i] - evOffset[i-1];
227 if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
229 ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
230 i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
231 failed = AL_TRUE;
234 if(irCount <= evOffset[i-1])
236 ERR("Invalid evOffset: evOffset[%d]=%d (irCount=%d)\n",
237 i-1, evOffset[i-1], irCount);
238 failed = AL_TRUE;
241 azCount[i-1] = irCount - evOffset[i-1];
242 if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
244 ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
245 i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
246 failed = AL_TRUE;
250 if(!failed)
252 coeffs = malloc(sizeof(coeffs[0])*irSize*irCount);
253 delays = malloc(sizeof(delays[0])*irCount);
254 if(coeffs == NULL || delays == NULL)
256 ERR("Out of memory.\n");
257 failed = AL_TRUE;
261 if(!failed)
263 for(i = 0;i < irCount*irSize;i+=irSize)
265 for(j = 0;j < irSize;j++)
267 ALshort coeff;
268 coeff = fgetc(f);
269 coeff |= fgetc(f)<<8;
270 coeffs[i+j] = coeff;
273 for(i = 0;i < irCount;i++)
275 delays[i] = fgetc(f);
276 if(delays[i] > maxDelay)
278 ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay);
279 failed = AL_TRUE;
283 if(feof(f))
285 ERR("Premature end of data\n");
286 failed = AL_TRUE;
290 if(!failed)
292 Hrtf = malloc(sizeof(struct Hrtf));
293 if(Hrtf == NULL)
295 ERR("Out of memory.\n");
296 failed = AL_TRUE;
300 if(!failed)
302 Hrtf->sampleRate = rate;
303 Hrtf->irSize = irSize;
304 Hrtf->evCount = evCount;
305 Hrtf->azCount = azCount;
306 Hrtf->evOffset = evOffset;
307 Hrtf->coeffs = coeffs;
308 Hrtf->delays = delays;
309 Hrtf->next = NULL;
310 return Hrtf;
313 free(azCount);
314 free(evOffset);
315 free(coeffs);
316 free(delays);
317 return NULL;
321 static struct Hrtf *LoadHrtf01(FILE *f, ALuint deviceRate)
323 const ALubyte maxDelay = HRTF_HISTORY_LENGTH-1;
324 struct Hrtf *Hrtf = NULL;
325 ALboolean failed = AL_FALSE;
326 ALuint rate = 0, irCount = 0;
327 ALubyte irSize = 0, evCount = 0;
328 ALubyte *azCount = NULL;
329 ALushort *evOffset = NULL;
330 ALshort *coeffs = NULL;
331 ALubyte *delays = NULL;
332 ALuint i, j;
334 rate = fgetc(f);
335 rate |= fgetc(f)<<8;
336 rate |= fgetc(f)<<16;
337 rate |= fgetc(f)<<24;
339 irSize = fgetc(f);
341 evCount = fgetc(f);
343 if(rate != deviceRate)
345 ERR("HRIR rate does not match device rate: rate=%d (%d)\n",
346 rate, deviceRate);
347 failed = AL_TRUE;
349 if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE))
351 ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
352 irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE);
353 failed = AL_TRUE;
355 if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT)
357 ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
358 evCount, MIN_EV_COUNT, MAX_EV_COUNT);
359 failed = AL_TRUE;
362 if(failed)
363 return NULL;
365 azCount = malloc(sizeof(azCount[0])*evCount);
366 evOffset = malloc(sizeof(evOffset[0])*evCount);
367 if(azCount == NULL || evOffset == NULL)
369 ERR("Out of memory.\n");
370 failed = AL_TRUE;
373 if(!failed)
375 for(i = 0;i < evCount;i++)
377 azCount[i] = fgetc(f);
378 if(azCount[i] < MIN_AZ_COUNT || azCount[i] > MAX_AZ_COUNT)
380 ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
381 i, azCount[i], MIN_AZ_COUNT, MAX_AZ_COUNT);
382 failed = AL_TRUE;
387 if(!failed)
389 evOffset[0] = 0;
390 irCount = azCount[0];
391 for(i = 1;i < evCount;i++)
393 evOffset[i] = evOffset[i-1] + azCount[i-1];
394 irCount += azCount[i];
397 coeffs = malloc(sizeof(coeffs[0])*irSize*irCount);
398 delays = malloc(sizeof(delays[0])*irCount);
399 if(coeffs == NULL || delays == NULL)
401 ERR("Out of memory.\n");
402 failed = AL_TRUE;
406 if(!failed)
408 for(i = 0;i < irCount*irSize;i+=irSize)
410 for(j = 0;j < irSize;j++)
412 ALshort coeff;
413 coeff = fgetc(f);
414 coeff |= fgetc(f)<<8;
415 coeffs[i+j] = coeff;
418 for(i = 0;i < irCount;i++)
420 delays[i] = fgetc(f);
421 if(delays[i] > maxDelay)
423 ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay);
424 failed = AL_TRUE;
428 if(feof(f))
430 ERR("Premature end of data\n");
431 failed = AL_TRUE;
435 if(!failed)
437 Hrtf = malloc(sizeof(struct Hrtf));
438 if(Hrtf == NULL)
440 ERR("Out of memory.\n");
441 failed = AL_TRUE;
445 if(!failed)
447 Hrtf->sampleRate = rate;
448 Hrtf->irSize = irSize;
449 Hrtf->evCount = evCount;
450 Hrtf->azCount = azCount;
451 Hrtf->evOffset = evOffset;
452 Hrtf->coeffs = coeffs;
453 Hrtf->delays = delays;
454 Hrtf->next = NULL;
455 return Hrtf;
458 free(azCount);
459 free(evOffset);
460 free(coeffs);
461 free(delays);
462 return NULL;
466 static struct Hrtf *LoadHrtf(ALuint deviceRate)
468 const char *fnamelist = "default-%r.mhr";
470 ConfigValueStr(NULL, "hrtf_tables", &fnamelist);
471 while(*fnamelist != '\0')
473 struct Hrtf *Hrtf = NULL;
474 char fname[PATH_MAX];
475 const char *next;
476 ALchar magic[8];
477 ALuint i;
478 FILE *f;
480 i = 0;
481 while(isspace(*fnamelist) || *fnamelist == ',')
482 fnamelist++;
483 next = fnamelist;
484 while(*(fnamelist=next) != '\0' && *fnamelist != ',')
486 next = strpbrk(fnamelist, "%,");
487 while(fnamelist != next && *fnamelist && i < sizeof(fname))
488 fname[i++] = *(fnamelist++);
490 if(!next || *next == ',')
491 break;
493 /* *next == '%' */
494 next++;
495 if(*next == 'r')
497 int wrote = snprintf(&fname[i], sizeof(fname)-i, "%u", deviceRate);
498 i += minu(wrote, sizeof(fname)-i);
499 next++;
501 else if(*next == '%')
503 if(i < sizeof(fname))
504 fname[i++] = '%';
505 next++;
507 else
508 ERR("Invalid marker '%%%c'\n", *next);
510 i = minu(i, sizeof(fname)-1);
511 fname[i] = '\0';
512 while(i > 0 && isspace(fname[i-1]))
513 i--;
514 fname[i] = '\0';
516 if(fname[0] == '\0')
517 continue;
519 TRACE("Loading %s...\n", fname);
520 f = OpenDataFile(fname, "openal/hrtf");
521 if(f == NULL)
523 ERR("Could not open %s\n", fname);
524 continue;
527 if(fread(magic, 1, sizeof(magic), f) != sizeof(magic))
528 ERR("Failed to read header from %s\n", fname);
529 else
531 if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0)
533 TRACE("Detected data set format v0\n");
534 Hrtf = LoadHrtf00(f, deviceRate);
536 else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0)
538 TRACE("Detected data set format v1\n");
539 Hrtf = LoadHrtf01(f, deviceRate);
541 else
542 ERR("Invalid header in %s: \"%.8s\"\n", fname, magic);
545 fclose(f);
546 f = NULL;
548 if(Hrtf)
550 Hrtf->next = LoadedHrtfs;
551 LoadedHrtfs = Hrtf;
552 TRACE("Loaded HRTF support for format: %s %uhz\n",
553 DevFmtChannelsString(DevFmtStereo), Hrtf->sampleRate);
554 return Hrtf;
557 ERR("Failed to load %s\n", fname);
560 return NULL;
563 const struct Hrtf *GetHrtf(enum DevFmtChannels chans, ALCuint srate)
565 if(chans == DevFmtStereo)
567 struct Hrtf *Hrtf = LoadedHrtfs;
568 while(Hrtf != NULL)
570 if(srate == Hrtf->sampleRate)
571 return Hrtf;
572 Hrtf = Hrtf->next;
575 Hrtf = LoadHrtf(srate);
576 if(Hrtf != NULL)
577 return Hrtf;
579 ERR("Incompatible format: %s %uhz\n", DevFmtChannelsString(chans), srate);
580 return NULL;
583 ALCboolean FindHrtfFormat(enum DevFmtChannels *chans, ALCuint *srate)
585 const struct Hrtf *hrtf = LoadedHrtfs;
586 while(hrtf != NULL)
588 if(*srate == hrtf->sampleRate)
589 break;
590 hrtf = hrtf->next;
593 if(hrtf == NULL)
595 hrtf = LoadHrtf(*srate);
596 if(hrtf == NULL) return ALC_FALSE;
599 *chans = DevFmtStereo;
600 *srate = hrtf->sampleRate;
601 return ALC_TRUE;
604 void FreeHrtfs(void)
606 struct Hrtf *Hrtf = NULL;
608 while((Hrtf=LoadedHrtfs) != NULL)
610 LoadedHrtfs = Hrtf->next;
611 free((void*)Hrtf->azCount);
612 free((void*)Hrtf->evOffset);
613 free((void*)Hrtf->coeffs);
614 free((void*)Hrtf->delays);
615 free(Hrtf);
619 ALuint GetHrtfIrSize (const struct Hrtf *Hrtf)
621 return Hrtf->irSize;