aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c16
-rw-r--r--Alc/hrtf.c91
-rw-r--r--Alc/hrtf.h9
-rw-r--r--Alc/vector.h18
4 files changed, 130 insertions, 4 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index b4545696..c4107a46 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2247,6 +2247,8 @@ static ALCvoid FreeDevice(ALCdevice *device)
}
ResetUIntMap(&device->FontsoundMap);
+ FreeHrtfList(&device->Hrtf_List);
+
free(device->Bs2b);
device->Bs2b = NULL;
@@ -2883,7 +2885,9 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
return 1;
case ALC_NUM_HRTF_SPECIFIER_SOFT:
- values[0] = 1;
+ FreeHrtfList(&device->Hrtf_List);
+ device->Hrtf_List = EnumerateHrtf(device->DeviceName);
+ values[0] = VECTOR_SIZE(device->Hrtf_List);
return 1;
default:
@@ -3342,6 +3346,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
device->Flags = 0;
device->Bs2b = NULL;
+ VECTOR_INIT(device->Hrtf_List);
device->Hrtf_Mode = DisabledHrtf;
AL_STRING_INIT(device->DeviceName);
device->DryBuffer = NULL;
@@ -3606,6 +3611,8 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
device->Connected = ALC_TRUE;
device->Type = Capture;
+ VECTOR_INIT(device->Hrtf_List);
+
AL_STRING_INIT(device->DeviceName);
device->DryBuffer = NULL;
@@ -3794,6 +3801,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
ATOMIC_INIT(&device->LastError, ALC_NO_ERROR);
device->Flags = 0;
+ VECTOR_INIT(device->Hrtf_List);
device->Bs2b = NULL;
device->Hrtf_Mode = DisabledHrtf;
AL_STRING_INIT(device->DeviceName);
@@ -3983,10 +3991,10 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALenum
else switch(paramName)
{
case ALC_HRTF_SPECIFIER_SOFT:
- if(index < 0 || index > 0)
- alcSetError(device, ALC_INVALID_VALUE);
+ if(index >= 0 && (size_t)index < VECTOR_SIZE(device->Hrtf_List))
+ str = al_string_get_cstr(VECTOR_ELEM(device->Hrtf_List, index).name);
else
- str = "Preset 0";
+ alcSetError(device, ALC_INVALID_VALUE);
break;
default:
diff --git a/Alc/hrtf.c b/Alc/hrtf.c
index 999b838e..d3faaa02 100644
--- a/Alc/hrtf.c
+++ b/Alc/hrtf.c
@@ -729,6 +729,97 @@ static struct Hrtf *LoadHrtf01(FILE *f, ALuint deviceRate)
}
+static void AddFileEntry(vector_HrtfEntry *list, al_string *filename)
+{
+ HrtfEntry entry = { AL_STRING_INIT_STATIC(), *filename };
+ HrtfEntry *iter;
+ const char *name;
+ int i = 0;
+
+ name = strrchr(al_string_get_cstr(entry.filename), '/');
+ if(!name) name = strrchr(al_string_get_cstr(entry.filename), '\\');
+ if(!name) name = al_string_get_cstr(entry.filename);
+ else ++name;
+
+ /* TODO: Open the file, and get a human-readable name (possibly coming in a
+ * format update). */
+
+ do {
+ al_string_copy_cstr(&entry.name, name);
+ if(i != 0)
+ {
+ char str[64];
+ snprintf(str, sizeof(str), " #%d", i+1);
+ al_string_append_cstr(&entry.name, str);
+ }
+ ++i;
+
+#define MATCH_NAME(i) (al_string_cmp(entry.name, (i)->name) == 0)
+ VECTOR_FIND_IF(iter, HrtfEntry, *list, MATCH_NAME);
+#undef MATCH_NAME
+ } while(iter != VECTOR_ITER_END(*list));
+
+ TRACE("Adding entry \"%s\" from file \"%s\"\n", al_string_get_cstr(entry.name),
+ al_string_get_cstr(entry.filename));
+ VECTOR_PUSH_BACK(*list, entry);
+}
+
+void FreeHrtfList(vector_HrtfEntry *list)
+{
+#define CLEAR_ENTRY(i) do { \
+ al_string_deinit(&(i)->name); \
+ al_string_deinit(&(i)->filename); \
+} while(0)
+ VECTOR_FOR_EACH(HrtfEntry, *list, CLEAR_ENTRY);
+ VECTOR_DEINIT(*list);
+#undef CLEAR_ENTRY
+}
+
+
+vector_HrtfEntry EnumerateHrtf(const_al_string devname)
+{
+ vector_HrtfEntry list = VECTOR_INIT_STATIC();
+ const char *fnamelist = "default-%r.mhr";
+
+ ConfigValueStr(al_string_get_cstr(devname), NULL, "hrtf_tables", &fnamelist);
+ while(fnamelist && *fnamelist)
+ {
+ while(isspace(*fnamelist) || *fnamelist == ',')
+ fnamelist++;
+ if(*fnamelist != '\0')
+ {
+ const char *next, *end;
+
+ next = strchr(fnamelist, ',');
+ if(!next)
+ end = fnamelist + strlen(fnamelist);
+ else
+ end = next++;
+
+ while(end != fnamelist && isspace(*(end-1)))
+ --end;
+ if(end != fnamelist)
+ {
+ al_string fname = AL_STRING_INIT_STATIC();
+ vector_al_string flist;
+
+ al_string_append_range(&fname, fnamelist, end);
+
+ flist = SearchDataFiles(al_string_get_cstr(fname), "openal/hrtf");
+ VECTOR_FOR_EACH_PARAMS(al_string, flist, AddFileEntry, &list);
+ VECTOR_DEINIT(flist);
+
+ al_string_deinit(&fname);
+ }
+
+ fnamelist = next;
+ }
+ }
+
+ return list;
+}
+
+
static struct Hrtf *LoadHrtf(const_al_string devname, ALuint deviceRate)
{
const char *fnamelist = "default-%r.mhr";
diff --git a/Alc/hrtf.h b/Alc/hrtf.h
index fed75173..57b8f9b0 100644
--- a/Alc/hrtf.h
+++ b/Alc/hrtf.h
@@ -10,6 +10,12 @@ enum DevFmtChannels;
struct Hrtf;
+typedef struct HrtfEntry {
+ al_string name;
+ al_string filename;
+} HrtfEntry;
+TYPEDEF_VECTOR(HrtfEntry, vector_HrtfEntry)
+
#define HRIR_BITS (7)
#define HRIR_LENGTH (1<<HRIR_BITS)
#define HRIR_MASK (HRIR_LENGTH-1)
@@ -17,6 +23,9 @@ struct Hrtf;
#define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS)
#define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1)
+vector_HrtfEntry EnumerateHrtf(const_al_string devname);
+void FreeHrtfList(vector_HrtfEntry *list);
+
const struct Hrtf *GetHrtf(const_al_string devname, enum DevFmtChannels chans, ALCuint srate);
ALCboolean FindHrtfFormat(const_al_string devname, enum DevFmtChannels *chans, ALCuint *srate);
diff --git a/Alc/vector.h b/Alc/vector.h
index 85230378..c1fc925d 100644
--- a/Alc/vector.h
+++ b/Alc/vector.h
@@ -73,6 +73,13 @@ ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_
_f(_iter); \
} while(0)
+#define VECTOR_FOR_EACH_PARAMS(_t, _x, _f, ...) do { \
+ _t *_iter = VECTOR_ITER_BEGIN((_x)); \
+ _t *_end = VECTOR_ITER_END((_x)); \
+ for(;_iter != _end;++_iter) \
+ _f(__VA_ARGS__, _iter); \
+} while(0)
+
#define VECTOR_FIND_IF(_i, _t, _x, _f) do { \
_t *_iter = VECTOR_ITER_BEGIN((_x)); \
_t *_end = VECTOR_ITER_END((_x)); \
@@ -84,4 +91,15 @@ ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_
(_i) = _iter; \
} while(0)
+#define VECTOR_FIND_IF_PARMS(_i, _t, _x, _f, ...) do { \
+ _t *_iter = VECTOR_ITER_BEGIN((_x)); \
+ _t *_end = VECTOR_ITER_END((_x)); \
+ for(;_iter != _end;++_iter) \
+ { \
+ if(_f(__VA_ARGS__, _iter)) \
+ break; \
+ } \
+ (_i) = _iter; \
+} while(0)
+
#endif /* AL_VECTOR_H */