Use the enumerated HRTF list for selecting an HRTF

Also report the proper specifier of the one currently in use.
This commit is contained in:
Chris Robinson
2015-10-06 06:48:53 -07:00
parent 1b51ee8b87
commit 0eef6d9d51
4 changed files with 57 additions and 148 deletions
+48 -8
View File
@@ -1903,8 +1903,17 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
if(hrtf_userreq == Hrtf_Enable || (hrtf_userreq != Hrtf_Disable && hrtf_appreq == Hrtf_Enable))
{
if(FindHrtfFormat(device->DeviceName, &device->FmtChans, &device->Frequency))
if(VECTOR_SIZE(device->Hrtf_List) == 0)
{
VECTOR_DEINIT(device->Hrtf_List);
device->Hrtf_List = EnumerateHrtf(device->DeviceName);
}
if(VECTOR_SIZE(device->Hrtf_List) > 0)
{
device->FmtChans = DevFmtStereo;
device->Frequency = GetHrtfSampleRate(VECTOR_ELEM(device->Hrtf_List, 0).hrtf);
device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_FREQUENCY_REQUEST;
}
else
{
hrtf_userreq = hrtf_appreq = Hrtf_Default;
@@ -1914,10 +1923,19 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
}
else if(hrtf_appreq == Hrtf_Enable)
{
enum DevFmtChannels chans = device->FmtChans;
ALCuint freq = device->Frequency;
if(!FindHrtfFormat(device->DeviceName, &chans, &freq) ||
chans != device->FmtChans || freq != device->Frequency)
size_t i;
if(VECTOR_SIZE(device->Hrtf_List) == 0)
{
VECTOR_DEINIT(device->Hrtf_List);
device->Hrtf_List = EnumerateHrtf(device->DeviceName);
}
for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
{
const struct Hrtf *hrtf = VECTOR_ELEM(device->Hrtf_List, i).hrtf;
if(GetHrtfSampleRate(hrtf) == device->Frequency)
break;
}
if(i == VECTOR_SIZE(device->Hrtf_List))
{
ERR("Requested format not HRTF compatible: %s, %uhz\n",
DevFmtChannelsString(device->FmtChans), device->Frequency);
@@ -1973,6 +1991,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
device->Hrtf = NULL;
device->Hrtf_Mode = DisabledHrtf;
al_string_clear(&device->Hrtf_Name);
if(device->FmtChans != DevFmtStereo)
{
if(hrtf_appreq == Hrtf_Enable)
@@ -2036,14 +2055,30 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
device->Hrtf_Status = hrtf_status;
else
{
size_t i;
device->Hrtf_Status = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
device->Hrtf = GetHrtf(device->DeviceName, device->FmtChans, device->Frequency);
if(VECTOR_SIZE(device->Hrtf_List) == 0)
{
VECTOR_DEINIT(device->Hrtf_List);
device->Hrtf_List = EnumerateHrtf(device->DeviceName);
}
for(i = 0;i < VECTOR_SIZE(device->Hrtf_List);i++)
{
const HrtfEntry *entry = &VECTOR_ELEM(device->Hrtf_List, i);
if(GetHrtfSampleRate(entry->hrtf) == device->Frequency)
{
device->Hrtf = entry->hrtf;
al_string_copy(&device->Hrtf_Name, entry->name);
break;
}
}
}
if(device->Hrtf)
{
device->Hrtf_Mode = hrtf_mode;
device->Hrtf_Status = hrtf_status;
TRACE("HRTF enabled\n");
TRACE("HRTF enabled, using \"%s\"\n", al_string_get_cstr(device->Hrtf_Name));
free(device->Bs2b);
device->Bs2b = NULL;
}
@@ -2247,6 +2282,7 @@ static ALCvoid FreeDevice(ALCdevice *device)
}
ResetUIntMap(&device->FontsoundMap);
AL_STRING_DEINIT(device->Hrtf_Name);
FreeHrtfList(&device->Hrtf_List);
free(device->Bs2b);
@@ -2673,8 +2709,9 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para
else
{
LockLists();
value = (Device->Hrtf ? "Preset 0" : "");
value = (Device->Hrtf ? al_string_get_cstr(Device->Hrtf_Name) : "");
UnlockLists();
ALCdevice_DecRef(Device);
}
break;
@@ -3347,6 +3384,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
device->Flags = 0;
device->Bs2b = NULL;
VECTOR_INIT(device->Hrtf_List);
AL_STRING_INIT(device->Hrtf_Name);
device->Hrtf_Mode = DisabledHrtf;
AL_STRING_INIT(device->DeviceName);
device->DryBuffer = NULL;
@@ -3612,6 +3650,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName,
device->Type = Capture;
VECTOR_INIT(device->Hrtf_List);
AL_STRING_INIT(device->Hrtf_Name);
AL_STRING_INIT(device->DeviceName);
device->DryBuffer = NULL;
@@ -3802,6 +3841,7 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
device->Flags = 0;
VECTOR_INIT(device->Hrtf_List);
AL_STRING_INIT(device->Hrtf_Name);
device->Bs2b = NULL;
device->Hrtf_Mode = DisabledHrtf;
AL_STRING_INIT(device->DeviceName);
+4 -135
View File
@@ -884,142 +884,16 @@ void FreeHrtfList(vector_HrtfEntry *list)
}
static struct Hrtf *LoadHrtf(const_al_string devname, ALuint deviceRate)
ALuint GetHrtfSampleRate(const struct Hrtf *Hrtf)
{
const char *fnamelist = "default-%r.mhr";
ConfigValueStr(al_string_get_cstr(devname), NULL, "hrtf_tables", &fnamelist);
while(*fnamelist != '\0')
{
struct Hrtf *Hrtf = NULL;
char fname[PATH_MAX];
const char *next;
ALchar magic[8];
ALuint i;
FILE *f;
i = 0;
while(isspace(*fnamelist) || *fnamelist == ',')
fnamelist++;
next = fnamelist;
while(*(fnamelist=next) != '\0' && *fnamelist != ',')
{
next = strpbrk(fnamelist, "%,");
while(fnamelist != next && *fnamelist && i < sizeof(fname))
fname[i++] = *(fnamelist++);
if(!next || *next == ',')
break;
/* *next == '%' */
next++;
if(*next == 'r')
{
int wrote = snprintf(&fname[i], sizeof(fname)-i, "%u", deviceRate);
i += minu(wrote, sizeof(fname)-i);
next++;
}
else if(*next == '%')
{
if(i < sizeof(fname))
fname[i++] = '%';
next++;
}
else
ERR("Invalid marker '%%%c'\n", *next);
}
i = minu(i, sizeof(fname)-1);
fname[i] = '\0';
while(i > 0 && isspace(fname[i-1]))
i--;
fname[i] = '\0';
if(fname[0] == '\0')
continue;
TRACE("Loading %s...\n", fname);
f = OpenDataFile(fname, "openal/hrtf");
if(f == NULL)
{
ERR("Could not open %s\n", fname);
continue;
}
if(fread(magic, 1, sizeof(magic), f) != sizeof(magic))
ERR("Failed to read header from %s\n", fname);
else
{
if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0)
{
TRACE("Detected data set format v0\n");
Hrtf = LoadHrtf00(f, deviceRate);
}
else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0)
{
TRACE("Detected data set format v1\n");
Hrtf = LoadHrtf01(f, deviceRate);
}
else
ERR("Invalid header in %s: \"%.8s\"\n", fname, magic);
}
fclose(f);
f = NULL;
if(Hrtf)
{
Hrtf->next = LoadedHrtfs;
LoadedHrtfs = Hrtf;
TRACE("Loaded HRTF support for format: %s %uhz\n",
DevFmtChannelsString(DevFmtStereo), Hrtf->sampleRate);
return Hrtf;
}
ERR("Failed to load %s\n", fname);
}
return NULL;
return Hrtf->sampleRate;
}
const struct Hrtf *GetHrtf(const_al_string devname, enum DevFmtChannels chans, ALCuint srate)
ALuint GetHrtfIrSize(const struct Hrtf *Hrtf)
{
if(chans == DevFmtStereo)
{
struct Hrtf *Hrtf = LoadedHrtfs;
while(Hrtf != NULL)
{
if(srate == Hrtf->sampleRate)
return Hrtf;
Hrtf = Hrtf->next;
}
Hrtf = LoadHrtf(devname, srate);
if(Hrtf != NULL) return Hrtf;
}
ERR("Incompatible format: %s %uhz\n", DevFmtChannelsString(chans), srate);
return NULL;
return Hrtf->irSize;
}
ALCboolean FindHrtfFormat(const_al_string devname, enum DevFmtChannels *chans, ALCuint *srate)
{
const struct Hrtf *hrtf = LoadedHrtfs;
while(hrtf != NULL)
{
if(*srate == hrtf->sampleRate)
break;
hrtf = hrtf->next;
}
if(hrtf == NULL)
{
hrtf = LoadHrtf(devname, *srate);
if(hrtf == NULL) return ALC_FALSE;
}
*chans = DevFmtStereo;
*srate = hrtf->sampleRate;
return ALC_TRUE;
}
void FreeHrtfs(void)
{
@@ -1036,8 +910,3 @@ void FreeHrtfs(void)
free(Hrtf);
}
}
ALuint GetHrtfIrSize(const struct Hrtf *Hrtf)
{
return Hrtf->irSize;
}
+4 -5
View File
@@ -25,15 +25,14 @@ TYPEDEF_VECTOR(HrtfEntry, vector_HrtfEntry)
#define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS)
#define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1)
void FreeHrtfs(void);
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);
void FreeHrtfs(void);
ALuint GetHrtfSampleRate(const struct Hrtf *Hrtf);
ALuint GetHrtfIrSize(const struct Hrtf *Hrtf);
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays);
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep);
void GetBFormatHrtfCoeffs(const struct Hrtf *Hrtf, const ALuint num_chans, ALfloat (**coeffs_list)[2], ALuint **delay_list);
+1
View File
@@ -702,6 +702,7 @@ struct ALCdevice_struct
/* HRTF filter tables */
vector_HrtfEntry Hrtf_List;
al_string Hrtf_Name;
const struct Hrtf *Hrtf;
ALCenum Hrtf_Status;
enum HrtfMode Hrtf_Mode;