aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c40
-rw-r--r--Alc/hrtf.c140
-rw-r--r--Alc/hrtf.h9
-rw-r--r--Alc/panning.c8
-rw-r--r--OpenAL32/Include/alMain.h2
5 files changed, 97 insertions, 102 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index d154e240..ed2c5e8e 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2049,6 +2049,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
{
+ const struct Hrtf *hrtf = NULL;
if(VECTOR_SIZE(device->HrtfList) == 0)
{
VECTOR_DEINIT(device->HrtfList);
@@ -2056,9 +2057,14 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
}
if(VECTOR_SIZE(device->HrtfList) > 0)
{
- const struct Hrtf *hrtf = VECTOR_ELEM(device->HrtfList, 0).hrtf->handle;
if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
- hrtf = VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf->handle;
+ hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, hrtf_id).hrtf);
+ else
+ hrtf = GetLoadedHrtf(VECTOR_ELEM(device->HrtfList, 0).hrtf);
+ }
+
+ if(hrtf)
+ {
device->FmtChans = DevFmtStereo;
device->Frequency = hrtf->sampleRate;
device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
@@ -2071,36 +2077,6 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
}
}
}
- else if(hrtf_appreq == Hrtf_Enable)
- {
- size_t i = VECTOR_SIZE(device->HrtfList);
- /* Loopback device. We don't need to match to a specific HRTF entry
- * here. If the requested ID matches, we'll pick that later, if not,
- * we'll try to auto-select one anyway. Just make sure one exists
- * that'll work.
- */
- if(device->FmtChans == DevFmtStereo)
- {
- if(VECTOR_SIZE(device->HrtfList) == 0)
- {
- VECTOR_DEINIT(device->HrtfList);
- device->HrtfList = EnumerateHrtf(device->DeviceName);
- }
- for(i = 0;i < VECTOR_SIZE(device->HrtfList);i++)
- {
- const struct Hrtf *hrtf = VECTOR_ELEM(device->HrtfList, i).hrtf->handle;
- if(hrtf->sampleRate == device->Frequency)
- break;
- }
- }
- if(i == VECTOR_SIZE(device->HrtfList))
- {
- ERR("Requested format not HRTF compatible: %s, %uhz\n",
- DevFmtChannelsString(device->FmtChans), device->Frequency);
- hrtf_appreq = Hrtf_Disable;
- device->HrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
- }
- }
oldFreq = device->Frequency;
oldChans = device->FmtChans;
diff --git a/Alc/hrtf.c b/Alc/hrtf.c
index f0ec9a98..4394cf56 100644
--- a/Alc/hrtf.c
+++ b/Alc/hrtf.c
@@ -46,6 +46,12 @@
#define MIN_AZ_COUNT (1)
#define MAX_AZ_COUNT (128)
+struct HrtfEntry {
+ struct HrtfEntry *next;
+ struct Hrtf *handle;
+ char filename[];
+};
+
static const ALchar magicMarker00[8] = "MinPHR00";
static const ALchar magicMarker01[8] = "MinPHR01";
@@ -240,7 +246,7 @@ ALsizei BuildBFormatHrtf(const struct Hrtf *Hrtf, DirectHrtfState *state, ALsize
static struct Hrtf *CreateHrtfStore(ALuint rate, ALsizei irSize, ALsizei evCount, ALsizei irCount,
const ALubyte *azCount, const ALushort *evOffset,
const ALshort *coeffs, const ALubyte *delays,
- const_al_string filename)
+ const char *filename)
{
struct Hrtf *Hrtf;
size_t total;
@@ -255,7 +261,7 @@ static struct Hrtf *CreateHrtfStore(ALuint rate, ALsizei irSize, ALsizei evCount
Hrtf = al_calloc(16, total);
if(Hrtf == NULL)
- ERR("Out of memory allocating storage for %s.\n", alstr_get_cstr(filename));
+ ERR("Out of memory allocating storage for %s.\n", filename);
else
{
uintptr_t offset = sizeof(struct Hrtf);
@@ -298,7 +304,7 @@ static struct Hrtf *CreateHrtfStore(ALuint rate, ALsizei irSize, ALsizei evCount
return Hrtf;
}
-static struct Hrtf *LoadHrtf00(const ALubyte *data, size_t datalen, const_al_string filename)
+static struct Hrtf *LoadHrtf00(const ALubyte *data, size_t datalen, const char *filename)
{
const ALubyte maxDelay = HRTF_HISTORY_LENGTH-1;
struct Hrtf *Hrtf = NULL;
@@ -314,8 +320,7 @@ static struct Hrtf *LoadHrtf00(const ALubyte *data, size_t datalen, const_al_str
if(datalen < 9)
{
- ERR("Unexpected end of %s data (req %d, rem "SZFMT")\n",
- alstr_get_cstr(filename), 9, datalen);
+ ERR("Unexpected end of %s data (req %d, rem "SZFMT")\n", filename, 9, datalen);
return NULL;
}
@@ -353,8 +358,7 @@ static struct Hrtf *LoadHrtf00(const ALubyte *data, size_t datalen, const_al_str
if(datalen < evCount*2)
{
- ERR("Unexpected end of %s data (req %d, rem "SZFMT")\n",
- alstr_get_cstr(filename), evCount*2, datalen);
+ ERR("Unexpected end of %s data (req %d, rem "SZFMT")\n", filename, evCount*2, datalen);
return NULL;
}
@@ -423,7 +427,7 @@ static struct Hrtf *LoadHrtf00(const ALubyte *data, size_t datalen, const_al_str
if(datalen < reqsize)
{
ERR("Unexpected end of %s data (req "SZFMT", rem "SZFMT")\n",
- alstr_get_cstr(filename), reqsize, datalen);
+ filename, reqsize, datalen);
failed = AL_TRUE;
}
}
@@ -463,7 +467,7 @@ static struct Hrtf *LoadHrtf00(const ALubyte *data, size_t datalen, const_al_str
return Hrtf;
}
-static struct Hrtf *LoadHrtf01(const ALubyte *data, size_t datalen, const_al_string filename)
+static struct Hrtf *LoadHrtf01(const ALubyte *data, size_t datalen, const char *filename)
{
const ALubyte maxDelay = HRTF_HISTORY_LENGTH-1;
struct Hrtf *Hrtf = NULL;
@@ -478,8 +482,7 @@ static struct Hrtf *LoadHrtf01(const ALubyte *data, size_t datalen, const_al_str
if(datalen < 6)
{
- ERR("Unexpected end of %s data (req %d, rem "SZFMT"\n",
- alstr_get_cstr(filename), 6, datalen);
+ ERR("Unexpected end of %s data (req %d, rem "SZFMT"\n", filename, 6, datalen);
return NULL;
}
@@ -512,8 +515,7 @@ static struct Hrtf *LoadHrtf01(const ALubyte *data, size_t datalen, const_al_str
if(datalen < evCount)
{
- ERR("Unexpected end of %s data (req %d, rem "SZFMT"\n",
- alstr_get_cstr(filename), evCount, datalen);
+ ERR("Unexpected end of %s data (req %d, rem "SZFMT"\n", filename, evCount, datalen);
return NULL;
}
@@ -565,7 +567,7 @@ static struct Hrtf *LoadHrtf01(const ALubyte *data, size_t datalen, const_al_str
if(datalen < reqsize)
{
ERR("Unexpected end of %s data (req "SZFMT", rem "SZFMT"\n",
- alstr_get_cstr(filename), reqsize, datalen);
+ filename, reqsize, datalen);
failed = AL_TRUE;
}
}
@@ -610,9 +612,7 @@ static void AddFileEntry(vector_EnumeratedHrtf *list, const_al_string filename)
{
EnumeratedHrtf entry = { AL_STRING_INIT_STATIC(), NULL };
struct HrtfEntry *loaded_entry;
- struct Hrtf *hrtf = NULL;
const EnumeratedHrtf *iter;
- struct FileMapping fmap;
const char *name;
const char *ext;
int i;
@@ -639,51 +639,14 @@ static void AddFileEntry(vector_EnumeratedHrtf *list, const_al_string filename)
loaded_entry = loaded_entry->next;
}
- TRACE("Loading %s...\n", alstr_get_cstr(filename));
- fmap = MapFileToMem(alstr_get_cstr(filename));
- if(fmap.ptr == NULL)
- {
- ERR("Could not open %s\n", alstr_get_cstr(filename));
- return;
- }
-
- if(fmap.len < sizeof(magicMarker01))
- ERR("%s data is too short ("SZFMT" bytes)\n", alstr_get_cstr(filename), fmap.len);
- else if(memcmp(fmap.ptr, magicMarker01, sizeof(magicMarker01)) == 0)
- {
- TRACE("Detected data set format v1\n");
- hrtf = LoadHrtf01((const ALubyte*)fmap.ptr+sizeof(magicMarker01),
- fmap.len-sizeof(magicMarker01), filename
- );
- }
- else if(memcmp(fmap.ptr, magicMarker00, sizeof(magicMarker00)) == 0)
- {
- TRACE("Detected data set format v0\n");
- hrtf = LoadHrtf00((const ALubyte*)fmap.ptr+sizeof(magicMarker00),
- fmap.len-sizeof(magicMarker00), filename
- );
- }
- else
- ERR("Invalid header in %s: \"%.8s\"\n", alstr_get_cstr(filename), (const char*)fmap.ptr);
- UnmapFileMem(&fmap);
-
- if(!hrtf)
- {
- ERR("Failed to load %s\n", alstr_get_cstr(filename));
- return;
- }
-
loaded_entry = al_calloc(DEF_ALIGN,
offsetof(struct HrtfEntry, filename[alstr_length(filename)+1])
);
loaded_entry->next = LoadedHrtfs;
- loaded_entry->handle = hrtf;
+ loaded_entry->handle = NULL;
strcpy(loaded_entry->filename, alstr_get_cstr(filename));
LoadedHrtfs = loaded_entry;
- TRACE("Loaded HRTF support for format: %s %uhz\n",
- DevFmtChannelsString(DevFmtStereo), hrtf->sampleRate);
-
skip_load:
/* TODO: Get a human-readable name from the HRTF data (possibly coming in a
* format update). */
@@ -762,19 +725,19 @@ static void AddBuiltInEntry(vector_EnumeratedHrtf *list, const ALubyte *data, si
if(memcmp(data, magicMarker01, sizeof(magicMarker01)) == 0)
{
TRACE("Detected data set format v1\n");
- hrtf = LoadHrtf01(data+sizeof(magicMarker01),
- datalen-sizeof(magicMarker01), filename
+ hrtf = LoadHrtf01((const ALubyte*)data+sizeof(magicMarker01),
+ datalen-sizeof(magicMarker01), alstr_get_cstr(filename)
);
}
else if(memcmp(data, magicMarker00, sizeof(magicMarker00)) == 0)
{
TRACE("Detected data set format v0\n");
- hrtf = LoadHrtf00(data+sizeof(magicMarker00),
- datalen-sizeof(magicMarker00), filename
+ hrtf = LoadHrtf00((const ALubyte*)data+sizeof(magicMarker00),
+ datalen-sizeof(magicMarker00), alstr_get_cstr(filename)
);
}
else
- ERR("Invalid header in %s: \"%.8s\"\n", alstr_get_cstr(filename), data);
+ ERR("Invalid header in %s: \"%.8s\"\n", alstr_get_cstr(filename), (const char*)data);
if(!hrtf)
{
@@ -1032,6 +995,65 @@ void FreeHrtfList(vector_EnumeratedHrtf *list)
#undef CLEAR_ENTRY
}
+struct Hrtf *GetLoadedHrtf(struct HrtfEntry *entry)
+{
+ static ATOMIC_FLAG LoadLock = ATOMIC_FLAG_INIT;
+ struct Hrtf *hrtf = NULL;
+ struct FileMapping fmap;
+
+ while(ATOMIC_FLAG_TEST_AND_SET(&LoadLock, almemory_order_seq_cst))
+ althrd_yield();
+
+ if(entry->handle)
+ {
+ hrtf = entry->handle;
+ goto done;
+ }
+
+ TRACE("Loading %s...\n", entry->filename);
+ fmap = MapFileToMem(entry->filename);
+ if(fmap.ptr == NULL)
+ {
+ ERR("Could not open %s\n", entry->filename);
+ goto done;
+ }
+
+ if(fmap.len < sizeof(magicMarker01))
+ ERR("%s data is too short ("SZFMT" bytes)\n", entry->filename, fmap.len);
+ else if(memcmp(fmap.ptr, magicMarker01, sizeof(magicMarker01)) == 0)
+ {
+ TRACE("Detected data set format v1\n");
+ hrtf = LoadHrtf01((const ALubyte*)fmap.ptr+sizeof(magicMarker01),
+ fmap.len-sizeof(magicMarker01), entry->filename
+ );
+ }
+ else if(memcmp(fmap.ptr, magicMarker00, sizeof(magicMarker00)) == 0)
+ {
+ TRACE("Detected data set format v0\n");
+ hrtf = LoadHrtf00((const ALubyte*)fmap.ptr+sizeof(magicMarker00),
+ fmap.len-sizeof(magicMarker00), entry->filename
+ );
+ }
+ else
+ ERR("Invalid header in %s: \"%.8s\"\n", entry->filename, (const char*)fmap.ptr);
+ UnmapFileMem(&fmap);
+
+ if(!hrtf)
+ {
+ ERR("Failed to load %s\n", entry->filename);
+ goto done;
+ }
+
+ TRACE("Loaded HRTF support for format: %s %uhz\n",
+ DevFmtChannelsString(DevFmtStereo), hrtf->sampleRate);
+
+ entry->handle = hrtf;
+
+done:
+ ATOMIC_FLAG_CLEAR(&LoadLock, almemory_order_seq_cst);
+ return hrtf;
+}
+
void FreeHrtfs(void)
{
diff --git a/Alc/hrtf.h b/Alc/hrtf.h
index 009bddea..4e25dde3 100644
--- a/Alc/hrtf.h
+++ b/Alc/hrtf.h
@@ -18,6 +18,8 @@
#define HRTF_AMBI_MAX_CHANNELS 16
+struct HrtfEntry;
+
struct Hrtf {
ALuint sampleRate;
ALsizei irSize;
@@ -29,17 +31,12 @@ struct Hrtf {
const ALubyte *delays;
};
-struct HrtfEntry {
- struct HrtfEntry *next;
- struct Hrtf *handle;
- char filename[];
-};
-
void FreeHrtfs(void);
vector_EnumeratedHrtf EnumerateHrtf(const_al_string devname);
void FreeHrtfList(vector_EnumeratedHrtf *list);
+struct Hrtf *GetLoadedHrtf(struct HrtfEntry *entry);
void GetHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat spread, ALfloat (*coeffs)[2], ALsizei *delays);
diff --git a/Alc/panning.c b/Alc/panning.c
index aa8175d4..bd550b32 100644
--- a/Alc/panning.c
+++ b/Alc/panning.c
@@ -1151,8 +1151,8 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf
if(hrtf_id >= 0 && (size_t)hrtf_id < VECTOR_SIZE(device->HrtfList))
{
const EnumeratedHrtf *entry = &VECTOR_ELEM(device->HrtfList, hrtf_id);
- const struct Hrtf *hrtf = entry->hrtf->handle;
- if(hrtf->sampleRate == device->Frequency)
+ const struct Hrtf *hrtf = GetLoadedHrtf(entry->hrtf);
+ if(hrtf && hrtf->sampleRate == device->Frequency)
{
device->HrtfHandle = hrtf;
alstr_copy(&device->HrtfName, entry->name);
@@ -1162,8 +1162,8 @@ void aluInitRenderer(ALCdevice *device, ALint hrtf_id, enum HrtfRequestMode hrtf
for(i = 0;!device->HrtfHandle && i < VECTOR_SIZE(device->HrtfList);i++)
{
const EnumeratedHrtf *entry = &VECTOR_ELEM(device->HrtfList, i);
- const struct Hrtf *hrtf = entry->hrtf->handle;
- if(hrtf->sampleRate == device->Frequency)
+ const struct Hrtf *hrtf = GetLoadedHrtf(entry->hrtf);
+ if(hrtf && hrtf->sampleRate == device->Frequency)
{
device->HrtfHandle = hrtf;
alstr_copy(&device->HrtfName, entry->name);
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 3a26bff2..4807e07d 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -637,7 +637,7 @@ typedef struct DirectHrtfState {
typedef struct EnumeratedHrtf {
al_string name;
- const struct HrtfEntry *hrtf;
+ struct HrtfEntry *hrtf;
} EnumeratedHrtf;
TYPEDEF_VECTOR(EnumeratedHrtf, vector_EnumeratedHrtf)