diff options
Diffstat (limited to 'Alc')
-rw-r--r-- | Alc/ALc.c | 16 | ||||
-rw-r--r-- | Alc/hrtf.c | 91 | ||||
-rw-r--r-- | Alc/hrtf.h | 9 | ||||
-rw-r--r-- | Alc/vector.h | 18 |
4 files changed, 130 insertions, 4 deletions
@@ -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: @@ -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"; @@ -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 */ |