Store the loaded hrtf entry container in the enumerated hrtf entry

This commit is contained in:
Chris Robinson 2017-04-05 11:29:58 -07:00
parent e7ca61e8b5
commit f76dea0c03
5 changed files with 70 additions and 65 deletions

View File

@ -2056,11 +2056,11 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
} }
if(VECTOR_SIZE(device->HrtfList) > 0) if(VECTOR_SIZE(device->HrtfList) > 0)
{ {
device->FmtChans = DevFmtStereo; const struct Hrtf *hrtf = VECTOR_ELEM(device->HrtfList, 0).hrtf->handle;
if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList)) if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
device->Frequency = VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf->sampleRate; hrtf = VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf->handle;
else device->FmtChans = DevFmtStereo;
device->Frequency = VECTOR_ELEM(device->HrtfList, 0).hrtf->sampleRate; device->Frequency = hrtf->sampleRate;
device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST; device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
} }
else else
@ -2088,7 +2088,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
} }
for(i = 0;i < VECTOR_SIZE(device->HrtfList);i++) for(i = 0;i < VECTOR_SIZE(device->HrtfList);i++)
{ {
const struct Hrtf *hrtf = VECTOR_ELEM(device->HrtfList, i).hrtf; const struct Hrtf *hrtf = VECTOR_ELEM(device->HrtfList, i).hrtf->handle;
if(hrtf->sampleRate == device->Frequency) if(hrtf->sampleRate == device->Frequency)
break; break;
} }

View File

@ -53,11 +53,7 @@ static const ALchar magicMarker01[8] = "MinPHR01";
* directional sounds. */ * directional sounds. */
static const ALfloat PassthruCoeff = 0.707106781187f/*sqrt(0.5)*/; static const ALfloat PassthruCoeff = 0.707106781187f/*sqrt(0.5)*/;
static struct LoadedHrtfEntry { static struct HrtfEntry *LoadedHrtfs = NULL;
struct LoadedHrtfEntry *next;
struct Hrtf *hrtf;
char filename[];
} *LoadedHrtfs = NULL;
/* Calculate the elevation index given the polar elevation in radians. This /* Calculate the elevation index given the polar elevation in radians. This
@ -610,12 +606,12 @@ static struct Hrtf *LoadHrtf01(const ALubyte *data, size_t datalen, const_al_str
return Hrtf; return Hrtf;
} }
static void AddFileEntry(vector_HrtfEntry *list, const_al_string filename) static void AddFileEntry(vector_EnumeratedHrtf *list, const_al_string filename)
{ {
HrtfEntry entry = { AL_STRING_INIT_STATIC(), NULL }; EnumeratedHrtf entry = { AL_STRING_INIT_STATIC(), NULL };
struct LoadedHrtfEntry *loaded_entry; struct HrtfEntry *loaded_entry;
struct Hrtf *hrtf = NULL; struct Hrtf *hrtf = NULL;
const HrtfEntry *iter; const EnumeratedHrtf *iter;
struct FileMapping fmap; struct FileMapping fmap;
const char *name; const char *name;
const char *ext; const char *ext;
@ -628,8 +624,8 @@ static void AddFileEntry(vector_HrtfEntry *list, const_al_string filename)
if(alstr_cmp_cstr(filename, loaded_entry->filename) == 0) if(alstr_cmp_cstr(filename, loaded_entry->filename) == 0)
{ {
/* Check if this entry has already been added to the list. */ /* Check if this entry has already been added to the list. */
#define MATCH_ENTRY(i) (loaded_entry->hrtf == (i)->hrtf) #define MATCH_ENTRY(i) (loaded_entry == (i)->hrtf)
VECTOR_FIND_IF(iter, const HrtfEntry, *list, MATCH_ENTRY); VECTOR_FIND_IF(iter, const EnumeratedHrtf, *list, MATCH_ENTRY);
if(iter != VECTOR_END(*list)) if(iter != VECTOR_END(*list))
{ {
TRACE("Skipping duplicate file entry %s\n", alstr_get_cstr(filename)); TRACE("Skipping duplicate file entry %s\n", alstr_get_cstr(filename));
@ -638,7 +634,6 @@ static void AddFileEntry(vector_HrtfEntry *list, const_al_string filename)
#undef MATCH_FNAME #undef MATCH_FNAME
TRACE("Skipping load of already-loaded file %s\n", alstr_get_cstr(filename)); TRACE("Skipping load of already-loaded file %s\n", alstr_get_cstr(filename));
hrtf = loaded_entry->hrtf;
goto skip_load; goto skip_load;
} }
loaded_entry = loaded_entry->next; loaded_entry = loaded_entry->next;
@ -679,15 +674,15 @@ static void AddFileEntry(vector_HrtfEntry *list, const_al_string filename)
} }
loaded_entry = al_calloc(DEF_ALIGN, loaded_entry = al_calloc(DEF_ALIGN,
offsetof(struct LoadedHrtfEntry, filename[alstr_length(filename)+1]) offsetof(struct HrtfEntry, filename[alstr_length(filename)+1])
); );
loaded_entry->next = LoadedHrtfs; loaded_entry->next = LoadedHrtfs;
loaded_entry->hrtf = hrtf; loaded_entry->handle = hrtf;
strcpy(loaded_entry->filename, alstr_get_cstr(filename)); strcpy(loaded_entry->filename, alstr_get_cstr(filename));
LoadedHrtfs = loaded_entry; LoadedHrtfs = loaded_entry;
TRACE("Loaded HRTF support for format: %s %uhz\n", TRACE("Loaded HRTF support for format: %s %uhz\n",
DevFmtChannelsString(DevFmtStereo), hrtf->sampleRate); DevFmtChannelsString(DevFmtStereo), hrtf->sampleRate);
skip_load: skip_load:
/* TODO: Get a human-readable name from the HRTF data (possibly coming in a /* TODO: Get a human-readable name from the HRTF data (possibly coming in a
@ -714,10 +709,10 @@ skip_load:
++i; ++i;
#define MATCH_NAME(i) (alstr_cmp(entry.name, (i)->name) == 0) #define MATCH_NAME(i) (alstr_cmp(entry.name, (i)->name) == 0)
VECTOR_FIND_IF(iter, const HrtfEntry, *list, MATCH_NAME); VECTOR_FIND_IF(iter, const EnumeratedHrtf, *list, MATCH_NAME);
#undef MATCH_NAME #undef MATCH_NAME
} while(iter != VECTOR_END(*list)); } while(iter != VECTOR_END(*list));
entry.hrtf = hrtf; entry.hrtf = loaded_entry;
TRACE("Adding entry \"%s\" from file \"%s\"\n", alstr_get_cstr(entry.name), TRACE("Adding entry \"%s\" from file \"%s\"\n", alstr_get_cstr(entry.name),
alstr_get_cstr(filename)); alstr_get_cstr(filename));
@ -727,12 +722,12 @@ skip_load:
/* Unfortunate that we have to duplicate AddFileEntry to take a memory buffer /* Unfortunate that we have to duplicate AddFileEntry to take a memory buffer
* for input instead of opening the given filename. * for input instead of opening the given filename.
*/ */
static void AddBuiltInEntry(vector_HrtfEntry *list, const ALubyte *data, size_t datalen, const_al_string filename) static void AddBuiltInEntry(vector_EnumeratedHrtf *list, const ALubyte *data, size_t datalen, const_al_string filename)
{ {
HrtfEntry entry = { AL_STRING_INIT_STATIC(), NULL }; EnumeratedHrtf entry = { AL_STRING_INIT_STATIC(), NULL };
struct LoadedHrtfEntry *loaded_entry; struct HrtfEntry *loaded_entry;
struct Hrtf *hrtf = NULL; struct Hrtf *hrtf = NULL;
const HrtfEntry *iter; const EnumeratedHrtf *iter;
const char *name; const char *name;
const char *ext; const char *ext;
int i; int i;
@ -742,8 +737,8 @@ static void AddBuiltInEntry(vector_HrtfEntry *list, const ALubyte *data, size_t
{ {
if(alstr_cmp_cstr(filename, loaded_entry->filename) == 0) if(alstr_cmp_cstr(filename, loaded_entry->filename) == 0)
{ {
#define MATCH_ENTRY(i) (loaded_entry->hrtf == (i)->hrtf) #define MATCH_ENTRY(i) (loaded_entry == (i)->hrtf)
VECTOR_FIND_IF(iter, const HrtfEntry, *list, MATCH_ENTRY); VECTOR_FIND_IF(iter, const EnumeratedHrtf, *list, MATCH_ENTRY);
if(iter != VECTOR_END(*list)) if(iter != VECTOR_END(*list))
{ {
TRACE("Skipping duplicate file entry %s\n", alstr_get_cstr(filename)); TRACE("Skipping duplicate file entry %s\n", alstr_get_cstr(filename));
@ -752,7 +747,6 @@ static void AddBuiltInEntry(vector_HrtfEntry *list, const ALubyte *data, size_t
#undef MATCH_FNAME #undef MATCH_FNAME
TRACE("Skipping load of already-loaded file %s\n", alstr_get_cstr(filename)); TRACE("Skipping load of already-loaded file %s\n", alstr_get_cstr(filename));
hrtf = loaded_entry->hrtf;
goto skip_load; goto skip_load;
} }
loaded_entry = loaded_entry->next; loaded_entry = loaded_entry->next;
@ -789,15 +783,15 @@ static void AddBuiltInEntry(vector_HrtfEntry *list, const ALubyte *data, size_t
} }
loaded_entry = al_calloc(DEF_ALIGN, loaded_entry = al_calloc(DEF_ALIGN,
offsetof(struct LoadedHrtfEntry, filename[alstr_length(filename)+1]) offsetof(struct HrtfEntry, filename[alstr_length(filename)+1])
); );
loaded_entry->next = LoadedHrtfs; loaded_entry->next = LoadedHrtfs;
loaded_entry->hrtf = hrtf; loaded_entry->handle = hrtf;
strcpy(loaded_entry->filename, alstr_get_cstr(filename)); strcpy(loaded_entry->filename, alstr_get_cstr(filename));
LoadedHrtfs = loaded_entry; LoadedHrtfs = loaded_entry;
TRACE("Loaded HRTF support for format: %s %uhz\n", TRACE("Loaded HRTF support for format: %s %uhz\n",
DevFmtChannelsString(DevFmtStereo), hrtf->sampleRate); DevFmtChannelsString(DevFmtStereo), hrtf->sampleRate);
skip_load: skip_load:
/* TODO: Get a human-readable name from the HRTF data (possibly coming in a /* TODO: Get a human-readable name from the HRTF data (possibly coming in a
@ -824,10 +818,10 @@ skip_load:
++i; ++i;
#define MATCH_NAME(i) (alstr_cmp(entry.name, (i)->name) == 0) #define MATCH_NAME(i) (alstr_cmp(entry.name, (i)->name) == 0)
VECTOR_FIND_IF(iter, const HrtfEntry, *list, MATCH_NAME); VECTOR_FIND_IF(iter, const EnumeratedHrtf, *list, MATCH_NAME);
#undef MATCH_NAME #undef MATCH_NAME
} while(iter != VECTOR_END(*list)); } while(iter != VECTOR_END(*list));
entry.hrtf = hrtf; entry.hrtf = loaded_entry;
TRACE("Adding built-in entry \"%s\"\n", alstr_get_cstr(entry.name)); TRACE("Adding built-in entry \"%s\"\n", alstr_get_cstr(entry.name));
VECTOR_PUSH_BACK(*list, entry); VECTOR_PUSH_BACK(*list, entry);
@ -928,9 +922,9 @@ static const ALubyte *GetResource(int name, size_t *size)
#endif #endif
#endif #endif
vector_HrtfEntry EnumerateHrtf(const_al_string devname) vector_EnumeratedHrtf EnumerateHrtf(const_al_string devname)
{ {
vector_HrtfEntry list = VECTOR_INIT_STATIC(); vector_EnumeratedHrtf list = VECTOR_INIT_STATIC();
const char *defaulthrtf = ""; const char *defaulthrtf = "";
const char *pathlist = ""; const char *pathlist = "";
bool usedefaults = true; bool usedefaults = true;
@ -1011,18 +1005,18 @@ vector_HrtfEntry EnumerateHrtf(const_al_string devname)
if(VECTOR_SIZE(list) > 1 && ConfigValueStr(alstr_get_cstr(devname), NULL, "default-hrtf", &defaulthrtf)) if(VECTOR_SIZE(list) > 1 && ConfigValueStr(alstr_get_cstr(devname), NULL, "default-hrtf", &defaulthrtf))
{ {
const HrtfEntry *iter; const EnumeratedHrtf *iter;
/* Find the preferred HRTF and move it to the front of the list. */ /* Find the preferred HRTF and move it to the front of the list. */
#define FIND_ENTRY(i) (alstr_cmp_cstr((i)->name, defaulthrtf) == 0) #define FIND_ENTRY(i) (alstr_cmp_cstr((i)->name, defaulthrtf) == 0)
VECTOR_FIND_IF(iter, const HrtfEntry, list, FIND_ENTRY); VECTOR_FIND_IF(iter, const EnumeratedHrtf, list, FIND_ENTRY);
#undef FIND_ENTRY #undef FIND_ENTRY
if(iter == VECTOR_END(list)) if(iter == VECTOR_END(list))
WARN("Failed to find default HRTF \"%s\"\n", defaulthrtf); WARN("Failed to find default HRTF \"%s\"\n", defaulthrtf);
else if(iter != VECTOR_BEGIN(list)) else if(iter != VECTOR_BEGIN(list))
{ {
HrtfEntry entry = *iter; EnumeratedHrtf entry = *iter;
memmove(&VECTOR_ELEM(list,1), &VECTOR_ELEM(list,0), memmove(&VECTOR_ELEM(list,1), &VECTOR_ELEM(list,0),
(iter-VECTOR_BEGIN(list))*sizeof(HrtfEntry)); (iter-VECTOR_BEGIN(list))*sizeof(EnumeratedHrtf));
VECTOR_ELEM(list,0) = entry; VECTOR_ELEM(list,0) = entry;
} }
} }
@ -1030,10 +1024,10 @@ vector_HrtfEntry EnumerateHrtf(const_al_string devname)
return list; return list;
} }
void FreeHrtfList(vector_HrtfEntry *list) void FreeHrtfList(vector_EnumeratedHrtf *list)
{ {
#define CLEAR_ENTRY(i) alstr_reset(&(i)->name) #define CLEAR_ENTRY(i) alstr_reset(&(i)->name)
VECTOR_FOR_EACH(HrtfEntry, *list, CLEAR_ENTRY); VECTOR_FOR_EACH(EnumeratedHrtf, *list, CLEAR_ENTRY);
VECTOR_DEINIT(*list); VECTOR_DEINIT(*list);
#undef CLEAR_ENTRY #undef CLEAR_ENTRY
} }
@ -1041,13 +1035,13 @@ void FreeHrtfList(vector_HrtfEntry *list)
void FreeHrtfs(void) void FreeHrtfs(void)
{ {
struct LoadedHrtfEntry *Hrtf = LoadedHrtfs; struct HrtfEntry *Hrtf = LoadedHrtfs;
LoadedHrtfs = NULL; LoadedHrtfs = NULL;
while(Hrtf != NULL) while(Hrtf != NULL)
{ {
struct LoadedHrtfEntry *next = Hrtf->next; struct HrtfEntry *next = Hrtf->next;
al_free(Hrtf->hrtf); al_free(Hrtf->handle);
al_free(Hrtf); al_free(Hrtf);
Hrtf = next; Hrtf = next;
} }

View File

@ -8,6 +8,16 @@
#include "alstring.h" #include "alstring.h"
#define HRTFDELAY_BITS (20)
#define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS)
#define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1)
/* The maximum number of virtual speakers used to generate HRTF coefficients
* for decoding B-Format.
*/
#define HRTF_AMBI_MAX_CHANNELS 16
struct Hrtf { struct Hrtf {
ALuint sampleRate; ALuint sampleRate;
ALsizei irSize; ALsizei irSize;
@ -19,19 +29,17 @@ struct Hrtf {
const ALubyte *delays; const ALubyte *delays;
}; };
#define HRTFDELAY_BITS (20) struct HrtfEntry {
#define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS) struct HrtfEntry *next;
#define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1) struct Hrtf *handle;
char filename[];
};
/* The maximum number of virtual speakers used to generate HRTF coefficients
* for decoding B-Format.
*/
#define HRTF_AMBI_MAX_CHANNELS 16
void FreeHrtfs(void); void FreeHrtfs(void);
vector_HrtfEntry EnumerateHrtf(const_al_string devname); vector_EnumeratedHrtf EnumerateHrtf(const_al_string devname);
void FreeHrtfList(vector_HrtfEntry *list); void FreeHrtfList(vector_EnumeratedHrtf *list);
void GetHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat spread, ALfloat (*coeffs)[2], ALsizei *delays); void GetHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat spread, ALfloat (*coeffs)[2], ALsizei *delays);

View File

@ -1150,20 +1150,22 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf
if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList)) if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
{ {
const HrtfEntry *entry = &VECTOR_ELEM(device->HrtfList, hrtf_id); const EnumeratedHrtf *entry = &VECTOR_ELEM(device->HrtfList, hrtf_id);
if(entry->hrtf->sampleRate == device->Frequency) const struct Hrtf *hrtf = entry->hrtf->handle;
if(hrtf->sampleRate == device->Frequency)
{ {
device->HrtfHandle = entry->hrtf; device->HrtfHandle = hrtf;
alstr_copy(&device->HrtfName, entry->name); alstr_copy(&device->HrtfName, entry->name);
} }
} }
for(i = 0;!device->HrtfHandle && i < VECTOR_SIZE(device->HrtfList);i++) for(i = 0;!device->HrtfHandle && i < VECTOR_SIZE(device->HrtfList);i++)
{ {
const HrtfEntry *entry = &VECTOR_ELEM(device->HrtfList, i); const EnumeratedHrtf *entry = &VECTOR_ELEM(device->HrtfList, i);
if(entry->hrtf->sampleRate == device->Frequency) const struct Hrtf *hrtf = entry->hrtf->handle;
if(hrtf->sampleRate == device->Frequency)
{ {
device->HrtfHandle = entry->hrtf; device->HrtfHandle = hrtf;
alstr_copy(&device->HrtfName, entry->name); alstr_copy(&device->HrtfName, entry->name);
} }
} }

View File

@ -358,6 +358,7 @@ extern "C" {
#endif #endif
struct Hrtf; struct Hrtf;
struct HrtfEntry;
#define DEFAULT_OUTPUT_RATE (44100) #define DEFAULT_OUTPUT_RATE (44100)
@ -633,12 +634,12 @@ typedef struct DirectHrtfState {
} Chan[]; } Chan[];
} DirectHrtfState; } DirectHrtfState;
typedef struct HrtfEntry { typedef struct EnumeratedHrtf {
al_string name; al_string name;
const struct Hrtf *hrtf; const struct HrtfEntry *hrtf;
} HrtfEntry; } EnumeratedHrtf;
TYPEDEF_VECTOR(HrtfEntry, vector_HrtfEntry) TYPEDEF_VECTOR(EnumeratedHrtf, vector_EnumeratedHrtf)
/* Maximum delay in samples for speaker distance compensation. */ /* Maximum delay in samples for speaker distance compensation. */
@ -702,7 +703,7 @@ struct ALCdevice_struct
DirectHrtfState *Hrtf; DirectHrtfState *Hrtf;
al_string HrtfName; al_string HrtfName;
const struct Hrtf *HrtfHandle; const struct Hrtf *HrtfHandle;
vector_HrtfEntry HrtfList; vector_EnumeratedHrtf HrtfList;
ALCenum HrtfStatus; ALCenum HrtfStatus;
/* UHJ encoder state */ /* UHJ encoder state */