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:
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user