Restore support for the previous mhr format
This commit is contained in:
parent
aa827790bd
commit
41f52fdd6a
360
Alc/hrtf.c
360
Alc/hrtf.c
@ -59,7 +59,8 @@ struct Hrtf {
|
||||
struct Hrtf *next;
|
||||
};
|
||||
|
||||
static const ALchar magicMarker[8] = "MinPHR01";
|
||||
static const ALchar magicMarker00[8] = "MinPHR00";
|
||||
static const ALchar magicMarker01[8] = "MinPHR01";
|
||||
|
||||
/* Define the default HRTF:
|
||||
* ALubyte defaultAzCount [DefaultHrtf.evCount]
|
||||
@ -348,90 +349,186 @@ ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat a
|
||||
return fastf2u(delta);
|
||||
}
|
||||
|
||||
static struct Hrtf *LoadHrtf(ALuint deviceRate)
|
||||
{
|
||||
const char *fnamelist = NULL;
|
||||
|
||||
if(!ConfigValueStr(NULL, "hrtf_tables", &fnamelist))
|
||||
return NULL;
|
||||
while(*fnamelist != '\0')
|
||||
{
|
||||
static struct Hrtf *LoadHrtf00(FILE *f, ALuint deviceRate)
|
||||
{
|
||||
const ALubyte maxDelay = SRC_HISTORY_LENGTH-1;
|
||||
struct Hrtf *Hrtf = NULL;
|
||||
ALboolean failed;
|
||||
ALboolean failed = AL_FALSE;
|
||||
ALuint rate = 0, irCount = 0;
|
||||
ALushort irSize = 0, evCount = 0;
|
||||
ALubyte *azCount = NULL;
|
||||
ALushort *evOffset = NULL;
|
||||
ALshort *coeffs = NULL;
|
||||
ALubyte *delays = NULL;
|
||||
ALuint i, j;
|
||||
|
||||
rate = fgetc(f);
|
||||
rate |= fgetc(f)<<8;
|
||||
rate |= fgetc(f)<<16;
|
||||
rate |= fgetc(f)<<24;
|
||||
|
||||
irCount = fgetc(f);
|
||||
irCount |= fgetc(f)<<8;
|
||||
|
||||
irSize = fgetc(f);
|
||||
irSize |= fgetc(f)<<8;
|
||||
|
||||
evCount = fgetc(f);
|
||||
|
||||
if(rate != deviceRate)
|
||||
{
|
||||
ERR("HRIR rate does not match device rate: rate=%d (%d)\n",
|
||||
rate, deviceRate);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE))
|
||||
{
|
||||
ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n",
|
||||
irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT)
|
||||
{
|
||||
ERR("Unsupported elevation count: evCount=%d (%d to %d)\n",
|
||||
evCount, MIN_EV_COUNT, MAX_EV_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
if(failed)
|
||||
return NULL;
|
||||
|
||||
azCount = malloc(sizeof(azCount[0])*evCount);
|
||||
evOffset = malloc(sizeof(evOffset[0])*evCount);
|
||||
if(azCount == NULL || evOffset == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
evOffset[0] = fgetc(f);
|
||||
evOffset[0] |= fgetc(f)<<8;
|
||||
for(i = 1;i < evCount;i++)
|
||||
{
|
||||
evOffset[i] = fgetc(f);
|
||||
evOffset[i] |= fgetc(f)<<8;
|
||||
if(evOffset[i] <= evOffset[i-1])
|
||||
{
|
||||
ERR("Invalid evOffset: evOffset[%d]=%d (last=%d)\n",
|
||||
i, evOffset[i], evOffset[i-1]);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
azCount[i-1] = evOffset[i] - evOffset[i-1];
|
||||
if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
|
||||
{
|
||||
ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
|
||||
i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
if(irCount <= evOffset[i-1])
|
||||
{
|
||||
ERR("Invalid evOffset: evOffset[%d]=%d (irCount=%d)\n",
|
||||
i-1, evOffset[i-1], irCount);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
azCount[i-1] = irCount - evOffset[i-1];
|
||||
if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
|
||||
{
|
||||
ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n",
|
||||
i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
coeffs = malloc(sizeof(coeffs[0])*irSize*irCount);
|
||||
delays = malloc(sizeof(delays[0])*irCount);
|
||||
if(coeffs == NULL || delays == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
for(i = 0;i < irCount*irSize;i+=irSize)
|
||||
{
|
||||
for(j = 0;j < irSize;j++)
|
||||
{
|
||||
ALshort coeff;
|
||||
coeff = fgetc(f);
|
||||
coeff |= fgetc(f)<<8;
|
||||
coeffs[i+j] = coeff;
|
||||
}
|
||||
}
|
||||
for(i = 0;i < irCount;i++)
|
||||
{
|
||||
delays[i] = fgetc(f);
|
||||
if(delays[i] > maxDelay)
|
||||
{
|
||||
ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(feof(f))
|
||||
{
|
||||
ERR("Premature end of data\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
Hrtf = malloc(sizeof(struct Hrtf));
|
||||
if(Hrtf == NULL)
|
||||
{
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
Hrtf->sampleRate = rate;
|
||||
Hrtf->irSize = irSize;
|
||||
Hrtf->evCount = evCount;
|
||||
Hrtf->azCount = azCount;
|
||||
Hrtf->evOffset = evOffset;
|
||||
Hrtf->coeffs = coeffs;
|
||||
Hrtf->delays = delays;
|
||||
Hrtf->next = NULL;
|
||||
return Hrtf;
|
||||
}
|
||||
|
||||
free(azCount);
|
||||
free(evOffset);
|
||||
free(coeffs);
|
||||
free(delays);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct Hrtf *LoadHrtf01(FILE *f, ALuint deviceRate)
|
||||
{
|
||||
const ALubyte maxDelay = SRC_HISTORY_LENGTH-1;
|
||||
struct Hrtf *Hrtf = NULL;
|
||||
ALboolean failed = AL_FALSE;
|
||||
ALuint rate = 0, irCount = 0;
|
||||
ALubyte irSize = 0, evCount = 0;
|
||||
ALubyte *azCount = NULL;
|
||||
ALushort *evOffset = NULL;
|
||||
ALshort *coeffs = NULL;
|
||||
ALubyte *delays = NULL;
|
||||
char fname[PATH_MAX];
|
||||
ALchar magic[9];
|
||||
ALuint i, j;
|
||||
FILE *f;
|
||||
|
||||
while(isspace(*fnamelist) || *fnamelist == ',')
|
||||
fnamelist++;
|
||||
i = 0;
|
||||
while(*fnamelist != '\0' && *fnamelist != ',')
|
||||
{
|
||||
const char *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);
|
||||
fnamelist = 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 = fopen(fname, "rb");
|
||||
if(f == NULL)
|
||||
{
|
||||
ERR("Could not open %s\n", fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
failed = AL_FALSE;
|
||||
if(fread(magic, 1, sizeof(magicMarker), f) != sizeof(magicMarker))
|
||||
{
|
||||
ERR("Failed to read magic marker\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
else if(memcmp(magic, magicMarker, sizeof(magicMarker)) != 0)
|
||||
{
|
||||
magic[8] = 0;
|
||||
ERR("Invalid magic marker: \"%s\"\n", magic);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
rate = fgetc(f);
|
||||
rate |= fgetc(f)<<8;
|
||||
rate |= fgetc(f)<<16;
|
||||
@ -459,10 +556,10 @@ static struct Hrtf *LoadHrtf(ALuint deviceRate)
|
||||
evCount, MIN_EV_COUNT, MAX_EV_COUNT);
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
if(failed)
|
||||
return NULL;
|
||||
|
||||
azCount = malloc(sizeof(azCount[0])*evCount);
|
||||
evOffset = malloc(sizeof(evOffset[0])*evCount);
|
||||
if(azCount == NULL || evOffset == NULL)
|
||||
@ -470,7 +567,6 @@ static struct Hrtf *LoadHrtf(ALuint deviceRate)
|
||||
ERR("Out of memory.\n");
|
||||
failed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
@ -534,9 +630,6 @@ static struct Hrtf *LoadHrtf(ALuint deviceRate)
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
|
||||
if(!failed)
|
||||
{
|
||||
Hrtf = malloc(sizeof(struct Hrtf));
|
||||
@ -556,21 +649,112 @@ static struct Hrtf *LoadHrtf(ALuint deviceRate)
|
||||
Hrtf->evOffset = evOffset;
|
||||
Hrtf->coeffs = coeffs;
|
||||
Hrtf->delays = delays;
|
||||
Hrtf->next = NULL;
|
||||
return Hrtf;
|
||||
}
|
||||
|
||||
free(azCount);
|
||||
free(evOffset);
|
||||
free(coeffs);
|
||||
free(delays);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct Hrtf *LoadHrtf(ALuint deviceRate)
|
||||
{
|
||||
const char *fnamelist = NULL;
|
||||
|
||||
if(!ConfigValueStr(NULL, "hrtf_tables", &fnamelist))
|
||||
return NULL;
|
||||
while(*fnamelist != '\0')
|
||||
{
|
||||
struct Hrtf *Hrtf = NULL;
|
||||
char fname[PATH_MAX];
|
||||
ALchar magic[8];
|
||||
ALuint i;
|
||||
FILE *f;
|
||||
|
||||
while(isspace(*fnamelist) || *fnamelist == ',')
|
||||
fnamelist++;
|
||||
i = 0;
|
||||
while(*fnamelist != '\0' && *fnamelist != ',')
|
||||
{
|
||||
const char *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);
|
||||
fnamelist = 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 = fopen(fname, "rb");
|
||||
if(f == NULL)
|
||||
{
|
||||
ERR("Could not open %s\n", fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(fread(magic, 1, sizeof(magic), f) != sizeof(magic))
|
||||
ERR("Failed to read magic marker\n");
|
||||
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 magic marker: \"%.8s\"\n", 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(azCount);
|
||||
free(evOffset);
|
||||
free(coeffs);
|
||||
free(delays);
|
||||
|
||||
ERR("Failed to load %s\n", fname);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user