Use a macro to specify the ambisonic periphonic channel mask
[openal-soft.git] / Alc / hrtf.c
blob1f972f87fb5e41adcc4a28d392f7dcfe8c2fde4f
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"
33 #include "compat.h"
36 /* Current data set limits defined by the makehrtf utility. */
37 #define MIN_IR_SIZE (8)
38 #define MAX_IR_SIZE (128)
39 #define MOD_IR_SIZE (8)
41 #define MIN_EV_COUNT (5)
42 #define MAX_EV_COUNT (128)
44 #define MIN_AZ_COUNT (1)
45 #define MAX_AZ_COUNT (128)
47 struct Hrtf {
48 ALuint sampleRate;
49 ALuint irSize;
50 ALubyte evCount;
52 const ALubyte *azCount;
53 const ALushort *evOffset;
54 const ALshort *coeffs;
55 const ALubyte *delays;
57 const char *filename;
58 struct Hrtf *next;
61 static const ALchar magicMarker00[8] = "MinPHR00";
62 static const ALchar magicMarker01[8] = "MinPHR01";
64 /* First value for pass-through coefficients (remaining are 0), used for omni-
65 * directional sounds. */
66 static const ALfloat PassthruCoeff = 32767.0f * 0.707106781187f/*sqrt(0.5)*/;
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 (evcount - 1) and an
72 * interpolation factor between 0.0 and 1.0.
74 static void CalcEvIndices(ALuint evcount, ALfloat ev, ALuint *evidx, ALfloat *evmu)
76 ev = (F_PI_2 + ev) * (evcount-1) / F_PI;
77 evidx[0] = fastf2u(ev);
78 evidx[1] = minu(evidx[0] + 1, 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 (azcount - 1) and an interpolation
84 * factor between 0.0 and 1.0.
86 static void CalcAzIndices(ALuint azcount, ALfloat az, ALuint *azidx, ALfloat *azmu)
88 az = (F_TAU + az) * azcount / F_TAU;
89 azidx[0] = fastf2u(az) % azcount;
90 azidx[1] = (azidx[0] + 1) % azcount;
91 *azmu = az - floorf(az);
94 /* Calculates static HRIR coefficients and delays for the given polar
95 * elevation and azimuth in radians. Linear interpolation is used to
96 * increase the apparent resolution of the HRIR data set. The coefficients
97 * are also normalized and attenuated by the specified gain.
99 void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat spread, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays)
101 ALuint evidx[2], lidx[4], ridx[4];
102 ALfloat mu[3], blend[4];
103 ALfloat dirfact;
104 ALuint i;
106 dirfact = 1.0f - (spread / F_TAU);
108 /* Claculate elevation indices and interpolation factor. */
109 CalcEvIndices(Hrtf->evCount, elevation, evidx, &mu[2]);
111 for(i = 0;i < 2;i++)
113 ALuint azcount = Hrtf->azCount[evidx[i]];
114 ALuint evoffset = Hrtf->evOffset[evidx[i]];
115 ALuint azidx[2];
117 /* Calculate azimuth indices and interpolation factor for this elevation. */
118 CalcAzIndices(azcount, azimuth, azidx, &mu[i]);
120 /* Calculate a set of linear HRIR indices for left and right channels. */
121 lidx[i*2 + 0] = evoffset + azidx[0];
122 lidx[i*2 + 1] = evoffset + azidx[1];
123 ridx[i*2 + 0] = evoffset + ((azcount-azidx[0]) % azcount);
124 ridx[i*2 + 1] = evoffset + ((azcount-azidx[1]) % azcount);
127 /* Calculate 4 blending weights for 2D bilinear interpolation. */
128 blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]);
129 blend[1] = ( mu[0]) * (1.0f-mu[2]);
130 blend[2] = (1.0f-mu[1]) * ( mu[2]);
131 blend[3] = ( mu[1]) * ( mu[2]);
133 /* Calculate the HRIR delays using linear interpolation. */
134 delays[0] = fastf2u((Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] +
135 Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3]) *
136 dirfact + 0.5f) << HRTFDELAY_BITS;
137 delays[1] = fastf2u((Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] +
138 Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3]) *
139 dirfact + 0.5f) << HRTFDELAY_BITS;
141 /* Calculate the sample offsets for the HRIR indices. */
142 lidx[0] *= Hrtf->irSize;
143 lidx[1] *= Hrtf->irSize;
144 lidx[2] *= Hrtf->irSize;
145 lidx[3] *= Hrtf->irSize;
146 ridx[0] *= Hrtf->irSize;
147 ridx[1] *= Hrtf->irSize;
148 ridx[2] *= Hrtf->irSize;
149 ridx[3] *= Hrtf->irSize;
151 /* Calculate the normalized and attenuated HRIR coefficients using linear
152 * interpolation when there is enough gain to warrant it. Zero the
153 * coefficients if gain is too low.
155 if(gain > 0.0001f)
157 ALfloat c;
159 i = 0;
160 c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] +
161 Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]);
162 coeffs[i][0] = lerp(PassthruCoeff, c, dirfact) * gain * (1.0f/32767.0f);
163 c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] +
164 Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]);
165 coeffs[i][1] = lerp(PassthruCoeff, c, dirfact) * gain * (1.0f/32767.0f);
167 for(i = 1;i < Hrtf->irSize;i++)
169 c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] +
170 Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]);
171 coeffs[i][0] = lerp(0.0f, c, dirfact) * gain * (1.0f/32767.0f);
172 c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] +
173 Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]);
174 coeffs[i][1] = lerp(0.0f, c, dirfact) * gain * (1.0f/32767.0f);
177 else
179 for(i = 0;i < Hrtf->irSize;i++)
181 coeffs[i][0] = 0.0f;
182 coeffs[i][1] = 0.0f;
188 static struct Hrtf *LoadHrtf00(FILE *f, const_al_string filename)
190 const ALubyte maxDelay = HRTF_HISTORY_LENGTH-1;
191 struct Hrtf *Hrtf = NULL;
192 ALboolean failed = AL_FALSE;
193 ALuint rate = 0, irCount = 0;
194 ALushort irSize = 0;
195 ALubyte evCount = 0;
196 ALubyte *azCount = NULL;
197 ALushort *evOffset = NULL;
198 ALshort *coeffs = NULL;
199 ALubyte *delays = NULL;
200 ALuint i, j;
202 rate = fgetc(f);
203 rate |= fgetc(f)<<8;
204 rate |= fgetc(f)<<16;
205 rate |= fgetc(f)<<24;
207 irCount = fgetc(f);
208 irCount |= fgetc(f)<<8;
210 irSize = fgetc(f);
211 irSize |= fgetc(f)<<8;
213 evCount = fgetc(f);
215 if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE))
217 ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
218 irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE);
219 failed = AL_TRUE;
221 if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT)
223 ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
224 evCount, MIN_EV_COUNT, MAX_EV_COUNT);
225 failed = AL_TRUE;
228 if(failed)
229 return NULL;
231 azCount = malloc(sizeof(azCount[0])*evCount);
232 evOffset = malloc(sizeof(evOffset[0])*evCount);
233 if(azCount == NULL || evOffset == NULL)
235 ERR("Out of memory.\n");
236 failed = AL_TRUE;
239 if(!failed)
241 evOffset[0] = fgetc(f);
242 evOffset[0] |= fgetc(f)<<8;
243 for(i = 1;i < evCount;i++)
245 evOffset[i] = fgetc(f);
246 evOffset[i] |= fgetc(f)<<8;
247 if(evOffset[i] <= evOffset[i-1])
249 ERR("Invalid evOffset: evOffset[%d]=%d (last=%d)\n",
250 i, evOffset[i], evOffset[i-1]);
251 failed = AL_TRUE;
254 azCount[i-1] = evOffset[i] - evOffset[i-1];
255 if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
257 ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
258 i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
259 failed = AL_TRUE;
262 if(irCount <= evOffset[i-1])
264 ERR("Invalid evOffset: evOffset[%d]=%d (irCount=%d)\n",
265 i-1, evOffset[i-1], irCount);
266 failed = AL_TRUE;
269 azCount[i-1] = irCount - evOffset[i-1];
270 if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
272 ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
273 i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
274 failed = AL_TRUE;
278 if(!failed)
280 coeffs = malloc(sizeof(coeffs[0])*irSize*irCount);
281 delays = malloc(sizeof(delays[0])*irCount);
282 if(coeffs == NULL || delays == NULL)
284 ERR("Out of memory.\n");
285 failed = AL_TRUE;
289 if(!failed)
291 for(i = 0;i < irCount*irSize;i+=irSize)
293 for(j = 0;j < irSize;j++)
295 ALshort coeff;
296 coeff = fgetc(f);
297 coeff |= fgetc(f)<<8;
298 coeffs[i+j] = coeff;
301 for(i = 0;i < irCount;i++)
303 delays[i] = fgetc(f);
304 if(delays[i] > maxDelay)
306 ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay);
307 failed = AL_TRUE;
311 if(feof(f))
313 ERR("Premature end of data\n");
314 failed = AL_TRUE;
318 if(!failed)
320 size_t total = sizeof(struct Hrtf);
321 total += sizeof(azCount[0])*evCount;
322 total += sizeof(evOffset[0])*evCount;
323 total += sizeof(coeffs[0])*irSize*irCount;
324 total += sizeof(delays[0])*irCount;
325 total += al_string_length(filename)+1;
327 Hrtf = malloc(total);
328 if(Hrtf == NULL)
330 ERR("Out of memory.\n");
331 failed = AL_TRUE;
335 if(!failed)
337 Hrtf->sampleRate = rate;
338 Hrtf->irSize = irSize;
339 Hrtf->evCount = evCount;
340 Hrtf->azCount = ((ALubyte*)(Hrtf+1));
341 Hrtf->evOffset = ((ALushort*)(Hrtf->azCount + evCount));
342 Hrtf->coeffs = ((ALshort*)(Hrtf->evOffset + evCount));
343 Hrtf->delays = ((ALubyte*)(Hrtf->coeffs + irSize*irCount));
344 Hrtf->filename = ((char*)(Hrtf->delays + irCount));
345 Hrtf->next = NULL;
347 memcpy((void*)Hrtf->azCount, azCount, sizeof(azCount[0])*evCount);
348 memcpy((void*)Hrtf->evOffset, evOffset, sizeof(evOffset[0])*evCount);
349 memcpy((void*)Hrtf->coeffs, coeffs, sizeof(coeffs[0])*irSize*irCount);
350 memcpy((void*)Hrtf->delays, delays, sizeof(delays[0])*irCount);
351 memcpy((void*)Hrtf->filename, al_string_get_cstr(filename), al_string_length(filename)+1);
354 free(azCount);
355 free(evOffset);
356 free(coeffs);
357 free(delays);
358 return Hrtf;
362 static struct Hrtf *LoadHrtf01(FILE *f, const_al_string filename)
364 const ALubyte maxDelay = HRTF_HISTORY_LENGTH-1;
365 struct Hrtf *Hrtf = NULL;
366 ALboolean failed = AL_FALSE;
367 ALuint rate = 0, irCount = 0;
368 ALubyte irSize = 0, evCount = 0;
369 ALubyte *azCount = NULL;
370 ALushort *evOffset = NULL;
371 ALshort *coeffs = NULL;
372 ALubyte *delays = NULL;
373 ALuint i, j;
375 rate = fgetc(f);
376 rate |= fgetc(f)<<8;
377 rate |= fgetc(f)<<16;
378 rate |= fgetc(f)<<24;
380 irSize = fgetc(f);
382 evCount = fgetc(f);
384 if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE))
386 ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
387 irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE);
388 failed = AL_TRUE;
390 if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT)
392 ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
393 evCount, MIN_EV_COUNT, MAX_EV_COUNT);
394 failed = AL_TRUE;
397 if(failed)
398 return NULL;
400 azCount = malloc(sizeof(azCount[0])*evCount);
401 evOffset = malloc(sizeof(evOffset[0])*evCount);
402 if(azCount == NULL || evOffset == NULL)
404 ERR("Out of memory.\n");
405 failed = AL_TRUE;
408 if(!failed)
410 for(i = 0;i < evCount;i++)
412 azCount[i] = fgetc(f);
413 if(azCount[i] < MIN_AZ_COUNT || azCount[i] > MAX_AZ_COUNT)
415 ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
416 i, azCount[i], MIN_AZ_COUNT, MAX_AZ_COUNT);
417 failed = AL_TRUE;
422 if(!failed)
424 evOffset[0] = 0;
425 irCount = azCount[0];
426 for(i = 1;i < evCount;i++)
428 evOffset[i] = evOffset[i-1] + azCount[i-1];
429 irCount += azCount[i];
432 coeffs = malloc(sizeof(coeffs[0])*irSize*irCount);
433 delays = malloc(sizeof(delays[0])*irCount);
434 if(coeffs == NULL || delays == NULL)
436 ERR("Out of memory.\n");
437 failed = AL_TRUE;
441 if(!failed)
443 for(i = 0;i < irCount*irSize;i+=irSize)
445 for(j = 0;j < irSize;j++)
447 ALshort coeff;
448 coeff = fgetc(f);
449 coeff |= fgetc(f)<<8;
450 coeffs[i+j] = coeff;
453 for(i = 0;i < irCount;i++)
455 delays[i] = fgetc(f);
456 if(delays[i] > maxDelay)
458 ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay);
459 failed = AL_TRUE;
463 if(feof(f))
465 ERR("Premature end of data\n");
466 failed = AL_TRUE;
470 if(!failed)
472 size_t total = sizeof(struct Hrtf);
473 total += sizeof(azCount[0])*evCount;
474 total += sizeof(evOffset[0])*evCount;
475 total += sizeof(coeffs[0])*irSize*irCount;
476 total += sizeof(delays[0])*irCount;
477 total += al_string_length(filename)+1;
479 Hrtf = malloc(total);
480 if(Hrtf == NULL)
482 ERR("Out of memory.\n");
483 failed = AL_TRUE;
487 if(!failed)
489 Hrtf->sampleRate = rate;
490 Hrtf->irSize = irSize;
491 Hrtf->evCount = evCount;
492 Hrtf->azCount = ((ALubyte*)(Hrtf+1));
493 Hrtf->evOffset = ((ALushort*)(Hrtf->azCount + evCount));
494 Hrtf->coeffs = ((ALshort*)(Hrtf->evOffset + evCount));
495 Hrtf->delays = ((ALubyte*)(Hrtf->coeffs + irSize*irCount));
496 Hrtf->filename = ((char*)(Hrtf->delays + irCount));
497 Hrtf->next = NULL;
499 memcpy((void*)Hrtf->azCount, azCount, sizeof(azCount[0])*evCount);
500 memcpy((void*)Hrtf->evOffset, evOffset, sizeof(evOffset[0])*evCount);
501 memcpy((void*)Hrtf->coeffs, coeffs, sizeof(coeffs[0])*irSize*irCount);
502 memcpy((void*)Hrtf->delays, delays, sizeof(delays[0])*irCount);
503 memcpy((void*)Hrtf->filename, al_string_get_cstr(filename), al_string_length(filename)+1);
506 free(azCount);
507 free(evOffset);
508 free(coeffs);
509 free(delays);
510 return Hrtf;
514 static void AddFileEntry(vector_HrtfEntry *list, al_string *filename)
516 HrtfEntry entry = { AL_STRING_INIT_STATIC(), NULL };
517 struct Hrtf *hrtf = NULL;
518 const HrtfEntry *iter;
519 const char *name;
520 const char *ext;
521 ALchar magic[8];
522 FILE *f;
523 int i;
525 name = strrchr(al_string_get_cstr(*filename), '/');
526 if(!name) name = strrchr(al_string_get_cstr(*filename), '\\');
527 if(!name) name = al_string_get_cstr(*filename);
528 else ++name;
530 entry.hrtf = LoadedHrtfs;
531 while(entry.hrtf)
533 if(al_string_cmp_cstr(*filename, entry.hrtf->filename) == 0)
535 TRACE("Skipping duplicate file entry %s\n", al_string_get_cstr(*filename));
536 goto done;
538 entry.hrtf = entry.hrtf->next;
541 TRACE("Loading %s...\n", al_string_get_cstr(*filename));
542 f = al_fopen(al_string_get_cstr(*filename), "rb");
543 if(f == NULL)
545 ERR("Could not open %s\n", al_string_get_cstr(*filename));
546 goto done;
549 if(fread(magic, 1, sizeof(magic), f) != sizeof(magic))
550 ERR("Failed to read header from %s\n", al_string_get_cstr(*filename));
551 else
553 if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0)
555 TRACE("Detected data set format v0\n");
556 hrtf = LoadHrtf00(f, *filename);
558 else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0)
560 TRACE("Detected data set format v1\n");
561 hrtf = LoadHrtf01(f, *filename);
563 else
564 ERR("Invalid header in %s: \"%.8s\"\n", al_string_get_cstr(*filename), magic);
566 fclose(f);
568 if(!hrtf)
570 ERR("Failed to load %s\n", al_string_get_cstr(*filename));
571 goto done;
574 hrtf->next = LoadedHrtfs;
575 LoadedHrtfs = hrtf;
576 TRACE("Loaded HRTF support for format: %s %uhz\n",
577 DevFmtChannelsString(DevFmtStereo), hrtf->sampleRate);
578 entry.hrtf = hrtf;
580 /* TODO: Get a human-readable name from the HRTF data (possibly coming in a
581 * format update). */
582 ext = strrchr(name, '.');
584 i = 0;
585 do {
586 if(!ext)
587 al_string_copy_cstr(&entry.name, name);
588 else
589 al_string_copy_range(&entry.name, name, ext);
590 if(i != 0)
592 char str[64];
593 snprintf(str, sizeof(str), " #%d", i+1);
594 al_string_append_cstr(&entry.name, str);
596 ++i;
598 #define MATCH_NAME(i) (al_string_cmp(entry.name, (i)->name) == 0)
599 VECTOR_FIND_IF(iter, const HrtfEntry, *list, MATCH_NAME);
600 #undef MATCH_NAME
601 } while(iter != VECTOR_END(*list));
603 TRACE("Adding entry \"%s\" from file \"%s\"\n", al_string_get_cstr(entry.name),
604 al_string_get_cstr(*filename));
605 VECTOR_PUSH_BACK(*list, entry);
607 done:
608 al_string_deinit(filename);
611 vector_HrtfEntry EnumerateHrtf(const_al_string devname)
613 vector_HrtfEntry list = VECTOR_INIT_STATIC();
614 const char *defaulthrtf = "";
615 const char *pathlist = "";
616 bool usedefaults = true;
618 if(ConfigValueStr(al_string_get_cstr(devname), NULL, "hrtf-paths", &pathlist))
620 while(pathlist && *pathlist)
622 const char *next, *end;
624 while(isspace(*pathlist) || *pathlist == ',')
625 pathlist++;
626 if(*pathlist == '\0')
627 continue;
629 next = strchr(pathlist, ',');
630 if(next)
631 end = next++;
632 else
634 end = pathlist + strlen(pathlist);
635 usedefaults = false;
638 while(end != pathlist && isspace(*(end-1)))
639 --end;
640 if(end != pathlist)
642 al_string pname = AL_STRING_INIT_STATIC();
643 vector_al_string flist;
645 al_string_append_range(&pname, pathlist, end);
647 flist = SearchDataFiles(".mhr", al_string_get_cstr(pname));
648 VECTOR_FOR_EACH_PARAMS(al_string, flist, AddFileEntry, &list);
649 VECTOR_DEINIT(flist);
651 al_string_deinit(&pname);
654 pathlist = next;
657 else if(ConfigValueExists(al_string_get_cstr(devname), NULL, "hrtf_tables"))
658 ERR("The hrtf_tables option is deprecated, please use hrtf-paths instead.\n");
660 if(usedefaults)
662 vector_al_string flist = SearchDataFiles(".mhr", "openal/hrtf");
663 VECTOR_FOR_EACH_PARAMS(al_string, flist, AddFileEntry, &list);
664 VECTOR_DEINIT(flist);
667 if(VECTOR_SIZE(list) > 1 && ConfigValueStr(al_string_get_cstr(devname), NULL, "default-hrtf", &defaulthrtf))
669 const HrtfEntry *iter;
670 /* Find the preferred HRTF and move it to the front of the list. */
671 #define FIND_ENTRY(i) (al_string_cmp_cstr((i)->name, defaulthrtf) == 0)
672 VECTOR_FIND_IF(iter, const HrtfEntry, list, FIND_ENTRY);
673 if(iter != VECTOR_END(list) && iter != VECTOR_BEGIN(list))
675 HrtfEntry entry = *iter;
676 memmove(&VECTOR_ELEM(list,1), &VECTOR_ELEM(list,0),
677 (iter-VECTOR_BEGIN(list))*sizeof(HrtfEntry));
678 VECTOR_ELEM(list,0) = entry;
680 else
681 WARN("Failed to find default HRTF \"%s\"\n", defaulthrtf);
682 #undef FIND_ENTRY
685 return list;
688 void FreeHrtfList(vector_HrtfEntry *list)
690 #define CLEAR_ENTRY(i) do { \
691 al_string_deinit(&(i)->name); \
692 } while(0)
693 VECTOR_FOR_EACH(HrtfEntry, *list, CLEAR_ENTRY);
694 VECTOR_DEINIT(*list);
695 #undef CLEAR_ENTRY
699 ALuint GetHrtfSampleRate(const struct Hrtf *Hrtf)
701 return Hrtf->sampleRate;
704 ALuint GetHrtfIrSize(const struct Hrtf *Hrtf)
706 return Hrtf->irSize;
710 void FreeHrtfs(void)
712 struct Hrtf *Hrtf = LoadedHrtfs;
713 LoadedHrtfs = NULL;
715 while(Hrtf != NULL)
717 struct Hrtf *next = Hrtf->next;
718 free(Hrtf);
719 Hrtf = next;