75 #define M_PI (3.14159265358979323846)
79 #define HUGE_VAL (1.0 / 0.0)
83 #define EPSILON (1e-15)
86 #define TR_RING_BITS (16)
87 #define TR_RING_SIZE (1 << TR_RING_BITS)
88 #define TR_RING_MASK (TR_RING_SIZE - 1)
91 #define TR_LOAD_SIZE (TR_RING_SIZE >> 2)
95 #define MAX_IDENT_LEN (16)
98 #define MAX_PATH_LEN (256)
102 #define MIN_RATE (32000)
103 #define MAX_RATE (96000)
106 #define MIN_POINTS (16)
107 #define MAX_POINTS (8192)
110 #define MIN_EV_COUNT (5)
111 #define MAX_EV_COUNT (128)
114 #define MIN_AZ_COUNT (1)
115 #define MAX_AZ_COUNT (128)
118 #define MIN_RADIUS (0.05)
119 #define MAX_RADIUS (0.15)
123 #define MIN_DISTANCE (0.5)
124 #define MAX_DISTANCE (2.5)
128 #define MAX_WAVE_CHANNELS (65535)
132 #define MIN_BIN_SIZE (2)
133 #define MAX_BIN_SIZE (4)
137 #define MIN_BIN_BITS (16)
141 #define MIN_ASCII_BITS (16)
142 #define MAX_ASCII_BITS (32)
145 #define MIN_FFTSIZE (512)
146 #define MAX_FFTSIZE (16384)
149 #define MIN_LIMIT (2.0)
150 #define MAX_LIMIT (120.0)
153 #define MIN_TRUNCSIZE (8)
154 #define MAX_TRUNCSIZE (128)
158 #define MOD_TRUNCSIZE (8)
161 #define DEFAULT_EQUALIZE (1)
162 #define DEFAULT_SURFACE (1)
163 #define DEFAULT_LIMIT (24.0)
164 #define DEFAULT_TRUNCSIZE (32)
167 #define FOURCC_RIFF (0x46464952) // 'RIFF'
168 #define FOURCC_RIFX (0x58464952) // 'RIFX'
169 #define FOURCC_WAVE (0x45564157) // 'WAVE'
170 #define FOURCC_FMT (0x20746D66) // 'fmt '
171 #define FOURCC_DATA (0x61746164) // 'data'
172 #define FOURCC_LIST (0x5453494C) // 'LIST'
173 #define FOURCC_WAVL (0x6C766177) // 'wavl'
174 #define FOURCC_SLNT (0x746E6C73) // 'slnt'
177 #define WAVE_FORMAT_PCM (0x0001)
178 #define WAVE_FORMAT_IEEE_FLOAT (0x0003)
179 #define WAVE_FORMAT_EXTENSIBLE (0xFFFE)
182 #define MAX_HRTD (63.0)
186 #define MHR_FORMAT ("MinPHR01")
227 #if defined (HAVE_STDINT_H)
231 #elif defined (HAVE___INT64)
232 typedef unsigned __int64 uint8;
233 #elif (SIZEOF_LONG == 8)
234 typedef unsigned long uint8;
235 #elif (SIZEOF_LONG_LONG == 8)
236 typedef unsigned long long uint8;
315 if (filename !=
NULL) {
316 while ((ch = (* filename)) !=
'\0') {
317 if ((ch ==
'/') || (ch ==
'\\'))
335 if ((toLoad >=
TR_LOAD_SIZE) && (! feof (tr -> mFile))) {
340 if (count < toLoad) {
341 tr -> mIn += fread (& tr -> mRing [in], 1, count, tr -> mFile);
342 tr -> mIn += fread (& tr -> mRing [0], 1, toLoad - count, tr -> mFile);
344 tr -> mIn += fread (& tr -> mRing [in], 1, toLoad, tr -> mFile);
351 if (tr -> mIn > tr -> mOut)
358 if (tr -> mName !=
NULL) {
359 fprintf (stderr,
"Error (%s:%u:%u): ", tr -> mName, line, column);
360 vfprintf (stderr, format, argPtr);
368 va_start (argPtr, format);
369 TrErrorVA (tr, line, column, format, argPtr);
377 va_start (argPtr, format);
378 TrErrorVA (tr, tr -> mLine, tr -> mColumn, format, argPtr);
412 }
else if (ch ==
'#') {
425 (* line) = tr -> mLine;
427 (* column) = tr -> mColumn;
440 while ((op [len] !=
'\0') && (out < tr -> mIn)) {
447 if (op [len] ==
'\0')
466 if ((ch ==
'_') || isalpha (ch)) {
476 }
while ((ch ==
'_') || isdigit (ch) || isalpha (ch));
477 tr -> mColumn +=
len;
479 TrErrorAt (tr, tr -> mLine, col,
"Identifier is too long.\n");
486 TrErrorAt (tr, tr -> mLine, col,
"Expected an identifier.\n");
493 char ch, temp [64 + 1];
500 if ((ch ==
'+') || (ch ==
'-')) {
516 tr -> mColumn +=
len;
517 if ((digis > 0) && (ch !=
'.') && (! isalpha (ch))) {
519 TrErrorAt (tr, tr -> mLine, col,
"Integer is too long.");
523 (* value) = strtol (temp,
NULL, 10);
524 if (((* value) < loBound) || ((* value) > hiBound)) {
525 TrErrorAt (tr, tr -> mLine, col,
"Expected a value from %d to %d.\n", loBound, hiBound);
531 TrErrorAt (tr, tr -> mLine, col,
"Expected an integer.\n");
538 char ch, temp [64 + 1];
545 if ((ch ==
'+') || (ch ==
'-')) {
578 if ((ch ==
'E') || (ch ==
'e')) {
584 if ((ch ==
'+') || (ch ==
'-')) {
601 tr -> mColumn +=
len;
602 if ((digis > 0) && (ch !=
'.') && (! isalpha (ch))) {
604 TrErrorAt (tr, tr -> mLine, col,
"Float is too long.");
608 (* value) = strtod (temp,
NULL);
609 if (((* value) < loBound) || ((* value) > hiBound)) {
610 TrErrorAt (tr, tr -> mLine, col,
"Expected a value from %f to %f.\n", loBound, hiBound);
616 tr -> mColumn +=
len;
619 TrErrorAt (tr, tr -> mLine, col,
"Expected a float.\n");
641 TrErrorAt (tr, tr -> mLine, col,
"Unterminated string at end of line.\n");
649 tr -> mColumn += 1 +
len;
650 TrErrorAt (tr, tr -> mLine, col,
"Unterminated string at end of input.\n");
653 tr -> mColumn += 2 +
len;
655 TrErrorAt (tr, tr -> mLine, col,
"String is too long.\n");
662 TrErrorAt (tr, tr -> mLine, col,
"Expected a string.\n");
675 while ((op [len] !=
'\0') &&
TrLoad (tr)) {
682 tr -> mColumn +=
len;
683 if (op [len] ==
'\0')
686 TrErrorAt (tr, tr -> mLine, col,
"Expected '%s' operator.\n", op);
694 static int StrSubst (
const char *
in,
const char * pat,
const char * rep,
const size_t maxLen,
char * out) {
695 size_t inLen, patLen, repLen;
700 patLen = strlen (pat);
701 repLen = strlen (rep);
705 while ((si < inLen) && (di < maxLen)) {
706 if (patLen <= (inLen - si)) {
707 if (strncasecmp (& in [si], pat, patLen) == 0) {
708 if (repLen > (maxLen - di)) {
709 repLen = maxLen - di;
712 strncpy (& out [di], rep, repLen);
724 return (! truncated);
729 static double round (
double val) {
731 return (ceil (val - 0.5));
732 return (
floor (val + 0.5));
735 static double fmin (
double a,
double b) {
736 return ((a < b) ? a : b);
739 static double fmax (
double a,
double b) {
740 return ((a > b) ? a : b);
745 static double Clamp (
const double val,
const double lower,
const double upper) {
746 return (fmin (fmax (val, lower), upper));
750 static double Lerp (
const double a,
const double b,
const double f) {
751 return (a + (f * (b - a)));
757 const double PRNG_SCALE = 1.0 / (RAND_MAX + 1.0);
762 out = round (in + (PRNG_SCALE * (prn - (* hpHist))));
771 a = (
double *)
calloc (n,
sizeof (
double));
773 fprintf (stderr,
"Error: Out of memory.\n");
788 return (sqrt ((r * r) + (i * i)));
792 static void ComplexMul (
const double aR,
const double aI,
const double bR,
const double bI,
double * outR,
double * outI) {
793 (* outR) = (aR * bR) - (aI * bI);
794 (* outI) = (aI * bR) + (aR * bI);
798 static void ComplexExp (
const double inR,
const double inI,
double * outR,
double * outI) {
802 (* outR) = e *
cos (inI);
803 (* outI) = e *
sin (inI);
812 static void FftArrange (
const uint n,
const double * inR,
const double * inI,
double * outR,
double * outI) {
816 if ((inR == outR) && (inI == outI)) {
819 for (k = 0; k <
n; k ++) {
829 while (rk & (m >>= 1))
836 for (k = 0; k <
n; k ++) {
840 while (rk & (m >>= 1))
851 double vR, vI, wR, wI;
856 for (m = 1, m2 = 2; m <
n; m <<= 1, m2 <<= 1) {
858 vR =
sin (0.5 * pi / m);
864 for (i = 0; i <
m; i ++) {
865 for (k = i; k <
n; k += m2) {
868 tR = (wR * re [mk]) - (wI * im [mk]);
869 tI = (wR * im [mk]) + (wI * re [mk]);
871 re [mk] = re [
k] - tR;
872 im [mk] = im [
k] - tI;
878 tR = (vR * wR) - (vI * wI);
879 tI = (vR * wI) + (vI * wR);
888 static void FftForward (
const uint n,
const double * inR,
const double * inI,
double * outR,
double * outI) {
894 static void FftInverse (
const uint n,
const double * inR,
const double * inI,
double * outR,
double * outI) {
901 for (i = 0; i <
n; i ++) {
912 static void Hilbert (
const uint n,
const double *
in,
double * outR,
double * outI) {
917 for (i = 0; i <
n; i ++)
921 for (i = 0; i <
n; i ++) {
931 for (i = 1; i < (n / 2); i ++) {
937 for (; i <
n; i ++) {
950 const uint m = 1 + (n / 2);
953 for (i = 0; i <
m; i ++)
962 const uint m = 1 + (n / 2);
964 uint i, lower, upper;
967 halfLim = limit / 2.0;
969 for (i = 0; i <
m; i ++)
970 out [i] = 20.0 * log10 (in [i]);
972 lower = ((
uint) ceil (n / pow (2.0, 8.0))) - 1;
973 upper = ((
uint)
floor (n / pow (2.0, 2.0))) - 1;
975 for (i = lower; i <= upper; i ++)
977 ave /= upper - lower + 1;
979 for (i = 0; i <
m; i ++)
980 out [i] =
Clamp (out [i], ave - halfLim, ave + halfLim);
982 for (i = 0; i <
m; i ++)
983 out [i] = pow (10.0, out [i] / 20.0);
992 const uint m = 1 + (n / 2);
993 double * mags =
NULL;
998 for (i = 0; i <
m; i ++) {
1000 outR [
i] = -log (mags [i]);
1002 for (; i <
n; i ++) {
1003 mags [
i] = mags [n -
i];
1004 outR [
i] = outR [n -
i];
1006 Hilbert (n, outR, outR, outI);
1010 for (i = 1; i <
n; i ++) {
1012 ComplexMul (mags [i], 0.0, aR, aI, & outR [i], & outI [i]);
1035 double term, sum,
x2,
y, last_sum;
1051 }
while (sum != last_sum);
1069 static double Kaiser (
const double b,
const double k) {
1072 k2 =
Clamp (k, -1.0, 1.0);
1073 if ((k < -1.0) || (k > 1.0))
1103 w_t = 2.0 *
M_PI * transition;
1104 if (rejection > 21.0)
1105 return ((
uint) ceil ((rejection - 7.95) / (2.285 * w_t)));
1106 return ((
uint) ceil (5.79 / w_t));
1111 if (rejection > 50.0)
1112 return (0.1102 * (rejection - 8.7));
1113 else if (rejection >= 21.0)
1114 return ((0.5842 * pow (rejection - 21.0, 0.4)) +
1115 (0.07886 * (rejection - 21.0)));
1132 static double SincFilter (
const int l,
const double b,
const double gain,
const double cutoff,
const int i) {
1133 return (
Kaiser (b, ((
double) (i - l)) / l) * 2.0 * gain * cutoff *
Sinc (2.0 * cutoff * (i - l)));
1166 double cutoff,
width, beta;
1169 gcd =
Gcd (srcRate, dstRate);
1170 rs -> mP = dstRate / gcd;
1171 rs -> mQ = srcRate / gcd;
1176 if (rs -> mP > rs -> mQ) {
1177 cutoff = 0.45 / rs -> mP;
1178 width = 0.1 / rs -> mP;
1180 cutoff = 0.45 / rs -> mQ;
1181 width = 0.1 / rs -> mQ;
1186 rs -> mM = (2 *
l) + 1;
1189 for (i = 0; i < ((
int) rs -> mM); i ++)
1190 rs -> mF [i] =
SincFilter ((
int)
l, beta, rs -> mP, cutoff,
i);
1202 const uint p = rs -> mP,
q = rs -> mQ,
m = rs -> mM,
l = rs -> mL;
1203 const double *
f = rs -> mF;
1204 double * work =
NULL;
1215 for (i = 0; i < outN; i ++) {
1219 j_f = (l + (q *
i)) %
p;
1220 j_s = (l + (q *
i)) /
p;
1225 r += f [j_f] * in [j_s];
1233 for (i = 0; i < outN; i ++)
1246 if (fread (in, 1, bytes, fp) != bytes) {
1247 fprintf (stderr,
"Error: Bad read from file '%s'.\n", filename);
1253 for (i = 0; i < bytes; i ++)
1254 accum = (accum << 8) | in [bytes - i - 1];
1257 for (i = 0; i < bytes; i ++)
1258 accum = (accum << 8) | in [
i];
1274 if (fread (in, 1, 8, fp) != 8) {
1275 fprintf (stderr,
"Error: Bad read from file '%s'.\n", filename);
1281 for (i = 0; i < 8; i ++)
1282 accum = (accum << 8) | in [8 - i - 1];
1285 for (i = 0; i < 8; i ++)
1286 accum = (accum << 8) | in [
i];
1300 if (fwrite (out, 1, len, fp) != len) {
1302 fprintf (stderr,
"Error: Bad write to file '%s'.\n", filename);
1316 for (i = 0; i < bytes; i ++)
1317 out [i] = (in >> (i * 8)) & 0x000000FF;
1320 for (i = 0; i < bytes; i ++)
1321 out [bytes - i - 1] = (in >> (i * 8)) & 0x000000FF;
1326 if (fwrite (out, 1, bytes, fp) != bytes) {
1327 fprintf (stderr,
"Error: Bad write to file '%s'.\n", filename);
1352 if (!
ReadBin8 (fp, filename, order, & v8 . ui))
1357 if (!
ReadBin4 (fp, filename, order, bytes, & v4 . ui))
1359 if (type ==
ET_FP) {
1360 (* out) = (double) v4 .
f;
1363 v4 . ui >>= (8 * bytes) - ((
uint)
bits);
1365 v4 . ui &= (0xFFFFFFFF >> (32 +
bits));
1366 if (v4 . ui & ((
uint) (1 << (abs (bits) - 1))))
1367 v4 . ui |= (0xFFFFFFFF << abs (bits));
1368 (* out) = v4 .
i / ((double) (1 << (abs (bits) - 1)));
1390 if (type ==
ET_FP) {
1391 if (!
TrReadFloat (tr, -HUGE_VAL, HUGE_VAL, out)) {
1392 fprintf (stderr,
"Error: Bad read from file '%s'.\n", filename);
1396 if (!
TrReadInt (tr, -(1 << (bits - 1)), (1 << (bits - 1)) - 1, & v)) {
1397 fprintf (stderr,
"Error: Bad read from file '%s'.\n", filename);
1400 (* out) = v / ((double) ((1 << (bits - 1)) - 1));
1408 uint4 fourCC, chunkSize;
1414 fseek (fp, (
long) chunkSize,
SEEK_CUR);
1416 (!
ReadBin4 (fp, src -> mPath, order, 4, & chunkSize)))
1419 if ((!
ReadBin4 (fp, src -> mPath, order, 2, & format)) ||
1420 (!
ReadBin4 (fp, src -> mPath, order, 2, & channels)) ||
1421 (!
ReadBin4 (fp, src -> mPath, order, 4, & rate)) ||
1422 (!
ReadBin4 (fp, src -> mPath, order, 4, & dummy)) ||
1423 (!
ReadBin4 (fp, src -> mPath, order, 2, & block)))
1426 if (chunkSize > 14) {
1427 if (!
ReadBin4 (fp, src -> mPath, order, 2, & size))
1437 if (!
ReadBin4 (fp, src -> mPath, order, 2, & bits))
1442 if (!
ReadBin4 (fp, src -> mPath, order, 2, & format))
1444 fseek (fp, (
long) (chunkSize - 26),
SEEK_CUR);
1448 fseek (fp, (
long) (chunkSize - 16),
SEEK_CUR);
1450 fseek (fp, (
long) (chunkSize - 14),
SEEK_CUR);
1453 fprintf (stderr,
"Error: Unsupported WAVE format in file '%s'.\n", src -> mPath);
1456 if (src -> mChannel >= channels) {
1457 fprintf (stderr,
"Error: Missing source channel in WAVE file '%s'.\n", src -> mPath);
1460 if (rate != hrirRate) {
1461 fprintf (stderr,
"Error: Mismatched source sample rate in WAVE file '%s'.\n", src -> mPath);
1465 if ((size < 2) || (size > 4)) {
1466 fprintf (stderr,
"Error: Unsupported sample size in WAVE file '%s'.\n", src -> mPath);
1469 if ((bits < 16) || (bits > (8 * size))) {
1470 fprintf (stderr,
"Error: Bad significant bits in WAVE file '%s'.\n", src -> mPath);
1475 if ((size != 4) && (size != 8)) {
1476 fprintf (stderr,
"Error: Unsupported sample size in WAVE file '%s'.\n", src -> mPath);
1479 src -> mType =
ET_FP;
1481 src -> mSize =
size;
1482 src -> mBits = (
int) bits;
1483 src -> mSkip = channels;
1489 int pre, post,
skip;
1492 pre = (
int) (src -> mSize * src -> mChannel);
1493 post = (
int) (src -> mSize * (src -> mSkip - src -> mChannel - 1));
1495 for (i = 0; i <
n; i ++) {
1499 if (!
ReadBinAsDouble (fp, src -> mPath, order, src -> mType, src -> mSize, src -> mBits, & hrir [i]))
1517 (!
ReadBin4 (fp, src -> mPath, order, 4, & chunkSize)))
1520 block = src -> mSize * src -> mSkip;
1521 count = chunkSize / block;
1522 if (count < (src -> mOffset + n)) {
1523 fprintf (stderr,
"Error: Bad read from file '%s'.\n", src -> mPath);
1526 fseek (fp, (
long) (src -> mOffset * block),
SEEK_CUR);
1538 fseek (fp, (
long) chunkSize,
SEEK_CUR);
1540 listSize = chunkSize;
1541 block = src -> mSize * src -> mSkip;
1542 skip = src -> mOffset;
1545 while ((offset < n) && (listSize > 8)) {
1547 (!
ReadBin4 (fp, src -> mPath, order, 4, & chunkSize)))
1549 listSize -= 8 + chunkSize;
1551 count = chunkSize / block;
1553 fseek (fp, (
long) (skip * block),
SEEK_CUR);
1554 chunkSize -= skip * block;
1557 if (count > (n - offset))
1559 if (!
ReadWaveData (fp, src, order, count, & hrir [offset]))
1561 chunkSize -= count * block;
1563 lastSample = hrir [offset - 1];
1569 if (!
ReadBin4 (fp, src -> mPath, order, 4, & count))
1575 if (count > (n - offset))
1577 for (i = 0; i <
count; i ++)
1578 hrir [offset + i] = lastSample;
1586 fseek (fp, (
long) chunkSize,
SEEK_CUR);
1589 fprintf (stderr,
"Error: Bad read from file '%s'.\n", src -> mPath);
1597 uint4 fourCC, dummy;
1608 fprintf (stderr,
"Error: No RIFF/RIFX chunk in file '%s'.\n", src -> mPath);
1614 fprintf (stderr,
"Error: Not a RIFF/RIFX WAVE file '%s'.\n", src -> mPath);
1628 fseek (fp, (
long) src -> mOffset,
SEEK_SET);
1629 for (i = 0; i <
n; i ++) {
1630 if (!
ReadBinAsDouble (fp, src -> mPath, order, src -> mType, src -> mSize, src -> mBits, & hrir [i]))
1632 if (src -> mSkip > 0)
1633 fseek (fp, (
long) src -> mSkip,
SEEK_CUR);
1646 for (i = 0; i < src -> mOffset; i ++) {
1650 for (i = 0; i <
n; i ++) {
1653 for (j = 0; j < src -> mSkip; j ++) {
1667 fp = fopen (src -> mPath,
"r");
1669 fp = fopen (src -> mPath,
"rb");
1671 fprintf (stderr,
"Error: Could not open source file '%s'.\n", src -> mPath);
1674 if (src -> mFormat ==
SF_WAVE)
1692 n = hData -> mFftSize;
1695 for (i = 0; i < hData -> mIrPoints; i ++) {
1699 for (; i <
n; i ++) {
1706 j = (hData -> mEvOffset [ei] + ai) * hData -> mIrSize;
1707 for (i = 0; i <
m; i ++)
1708 hData -> mHrirs [j + i] =
Lerp (hData -> mHrirs [j + i], re [i], f);
1719 double evs, sum, ev, up_ev, down_ev, solidAngle;
1721 evs = 90.0 / (hData -> mEvCount - 1);
1723 for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) {
1726 ev = -90.0 + (ei * 2.0 * evs);
1727 if (ei < (hData -> mEvCount - 1))
1728 up_ev = (ev + evs) *
M_PI / 180.0;
1732 down_ev = (ev - evs) *
M_PI / 180.0;
1734 down_ev = -
M_PI / 2.0;
1736 solidAngle = 2.0 *
M_PI * (
sin (up_ev) -
sin (down_ev));
1738 weights [ei] = solidAngle / hData -> mAzCount [ei];
1743 for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++)
1744 weights [ei] /= sum;
1765 for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++)
1766 count += hData -> mAzCount [ei];
1767 for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++)
1768 weights [ei] = 1.0 / count;
1770 ei = hData -> mEvStart;
1772 step = hData -> mIrSize;
1773 start = hData -> mEvOffset [ei] * step;
1774 end = hData -> mIrCount * step;
1775 m = 1 + (hData -> mFftSize / 2);
1776 for (i = 0; i <
m; i ++)
1778 for (j = start; j <
end; j += step) {
1780 weight = weights [ei];
1782 for (i = 0; i <
m; i ++)
1783 dfa [i] += weight * hData -> mHrirs [j + i] * hData -> mHrirs [j + i];
1786 if (ai >= hData -> mAzCount [ei]) {
1792 for (i = 0; i <
m; i ++)
1793 dfa [i] = fmax (sqrt (dfa [i]),
EPSILON);
1806 step = hData -> mIrSize;
1807 start = hData -> mEvOffset [hData -> mEvStart] * step;
1808 end = hData -> mIrCount * step;
1809 m = 1 + (hData -> mFftSize / 2);
1810 for (j = start; j <
end; j += step) {
1811 for (i = 0; i <
m; i ++)
1812 hData -> mHrirs [j + i] /= dfa [i];
1822 step = hData -> mIrSize;
1823 start = hData -> mEvOffset [hData -> mEvStart] * step;
1824 end = hData -> mIrCount * step;
1825 n = hData -> mFftSize;
1828 for (j = start; j <
end; j += step) {
1831 for (i = 0; i < hData -> mIrPoints; i ++)
1832 hData -> mHrirs [j + i] = re [i];
1844 n = hData -> mIrPoints;
1845 step = hData -> mIrSize;
1846 start = hData -> mEvOffset [hData -> mEvStart] * step;
1847 end = hData -> mIrCount * step;
1848 for (j = start; j <
end; j += step)
1849 ResamplerRun (& rs, n, & hData -> mHrirs [j], n, & hData -> mHrirs [j]);
1851 hData -> mIrRate = rate;
1862 af = ((2.0 *
M_PI) + az) * hData -> mAzCount [ei] / (2.0 *
M_PI);
1863 ai = ((
uint) af) % hData -> mAzCount [ei];
1865 (* j0) = hData -> mEvOffset [ei] + ai;
1866 (* j1) = hData -> mEvOffset [ei] + ((ai + 1) % hData -> mAzCount [ei]);
1880 double lp [4],
s0,
s1;
1882 if (hData -> mEvStart <= 0)
1884 step = hData -> mIrSize;
1885 oi = hData -> mEvStart;
1886 n = hData -> mIrPoints;
1887 for (i = 0; i <
n; i ++)
1888 hData -> mHrirs [i] = 0.0;
1889 for (a = 0; a < hData -> mAzCount [oi]; a ++) {
1890 j = (hData -> mEvOffset [oi] +
a) * step;
1891 for (i = 0; i <
n; i ++)
1892 hData -> mHrirs [i] += hData -> mHrirs [j + i] / hData -> mAzCount [oi];
1894 for (e = 1; e < hData -> mEvStart; e ++) {
1895 of = ((double) e) / hData -> mEvStart;
1896 b = (1.0 - of) * (3.5e-6 * hData -> mIrRate);
1897 for (a = 0; a < hData -> mAzCount [
e]; a ++) {
1898 j = (hData -> mEvOffset [
e] +
a) * step;
1899 CalcAzIndices (hData, oi, a * 2.0 *
M_PI / hData -> mAzCount [e], & j0, & j1, & jf);
1906 for (i = 0; i <
n; i ++) {
1907 s0 = hData -> mHrirs [
i];
1908 s1 =
Lerp (hData -> mHrirs [j0 + i], hData -> mHrirs [j1 + i], jf);
1909 s0 =
Lerp (s0, s1, of);
1910 lp [0] =
Lerp (s0, lp [0], b);
1911 lp [1] =
Lerp (lp [0], lp [1], b);
1912 lp [2] =
Lerp (lp [1], lp [2], b);
1913 lp [3] =
Lerp (lp [2], lp [3], b);
1914 hData -> mHrirs [j +
i] = lp [3];
1918 b = 3.5e-6 * hData -> mIrRate;
1923 for (i = 0; i <
n; i ++) {
1924 s0 = hData -> mHrirs [
i];
1925 lp [0] =
Lerp (s0, lp [0], b);
1926 lp [1] =
Lerp (lp [0], lp [1], b);
1927 lp [2] =
Lerp (lp [1], lp [2], b);
1928 lp [3] =
Lerp (lp [2], lp [3], b);
1929 hData -> mHrirs [
i] = lp [3];
1931 hData -> mEvStart = 0;
1941 step = hData -> mIrSize;
1942 end = hData -> mIrCount * step;
1943 n = hData -> mIrPoints;
1945 for (j = 0; j <
end; j += step) {
1946 for (i = 0; i <
n; i ++)
1947 maxLevel = fmax (
fabs (hData -> mHrirs [j + i]), maxLevel);
1949 maxLevel = 1.01 * maxLevel;
1950 for (j = 0; j <
end; j += step) {
1951 for (i = 0; i <
n; i ++)
1952 hData -> mHrirs [j + i] /= maxLevel;
1957 static double CalcLTD (
const double ev,
const double az,
const double rad,
const double dist) {
1958 double azp, dlp,
l, al;
1960 azp = asin (
cos (ev) *
sin (az));
1961 dlp = sqrt ((dist * dist) + (rad * rad) + (2.0 * dist * rad *
sin (azp)));
1962 l = sqrt ((dist * dist) - (rad * rad));
1963 al = (0.5 *
M_PI) + azp;
1965 dlp = l + (rad * (al - acos (rad / dist)));
1966 return (dlp / 343.3);
1972 double minHrtd, maxHrtd;
1978 for (e = 0; e < hData -> mEvCount; e ++) {
1979 for (a = 0; a < hData -> mAzCount [
e]; a ++) {
1980 j = hData -> mEvOffset [
e] +
a;
1981 t =
CalcLTD ((-90.0 + (e * 180.0 / (hData -> mEvCount - 1))) *
M_PI / 180.0,
1982 (a * 360.0 / hData -> mAzCount [e]) *
M_PI / 180.0,
1983 hData -> mRadius, hData -> mDistance);
1984 hData -> mHrtds [
j] =
t;
1985 maxHrtd = fmax (t, maxHrtd);
1986 minHrtd = fmin (t, minHrtd);
1990 for (j = 0; j < hData -> mIrCount; j ++)
1991 hData -> mHrtds [j] -= minHrtd;
1992 hData -> mMaxHrtd = maxHrtd;
2001 if ((fp = fopen (filename,
"wb")) ==
NULL) {
2002 fprintf (stderr,
"Error: Could not open MHR file '%s'.\n", filename);
2013 for (e = 0; e < hData -> mEvCount; e ++) {
2017 step = hData -> mIrSize;
2018 end = hData -> mIrCount * step;
2019 n = hData -> mIrPoints;
2021 for (j = 0; j <
end; j += step) {
2023 for (i = 0; i <
n; i ++) {
2024 v =
HpTpdfDither (32767.0 * hData -> mHrirs [j + i], & hpHist);
2029 for (j = 0; j < hData -> mIrCount; j ++) {
2030 v = (
int) fmin (round (hData -> mIrRate * hData -> mHrtds [j]),
MAX_HRTD);
2043 char text [128 + 1];
2045 if ((fp = fopen (filename,
"wb")) ==
NULL) {
2046 fprintf (stderr,
"Error: Could not open table file '%s'.\n", filename);
2049 snprintf (text, 128,
"/* Elevation metrics */\n"
2050 "static const ALubyte defaultAzCount[%u] = { ", hData -> mEvCount);
2053 for (i = 0; i < hData -> mEvCount; i ++) {
2054 snprintf (text, 128,
"%u, ", hData -> mAzCount [i]);
2058 snprintf (text, 128,
"};\n"
2059 "static const ALushort defaultEvOffset[%u] = { ", hData -> mEvCount);
2062 for (i = 0; i < hData -> mEvCount; i ++) {
2063 snprintf (text, 128,
"%u, ", hData -> mEvOffset [i]);
2067 step = hData -> mIrSize;
2068 end = hData -> mIrCount * step;
2069 n = hData -> mIrPoints;
2070 snprintf (text, 128,
"};\n\n"
2071 "/* HRIR Coefficients */\n"
2072 "static const ALshort defaultCoeffs[%u] =\n{\n", hData -> mIrCount * n);
2076 for (j = 0; j <
end; j += step) {
2080 for (i = 0; i <
n; i ++) {
2081 v =
HpTpdfDither (32767.0 * hData -> mHrirs [j + i], & hpHist);
2082 snprintf (text, 128,
" %+d,", v);
2089 snprintf (text, 128,
"};\n\n"
2090 "/* HRIR Delays */\n"
2091 "static const ALubyte defaultDelays[%u] =\n{\n"
2092 " ", hData -> mIrCount);
2095 for (j = 0; j < hData -> mIrCount; j ++) {
2096 v = (
int) fmin (round (hData -> mIrRate * hData -> mHrtds [j]),
MAX_HRTD);
2097 snprintf (text, 128,
" %d,", v);
2102 "/* Default HRTF Definition */\n", fp, filename))
2104 snprintf (text, 128,
"static const struct Hrtf DefaultHrtf = {\n"
2105 " %u, %u, %u, defaultAzCount, defaultEvOffset,\n",
2106 hData -> mIrRate, hData -> mIrPoints, hData -> mEvCount);
2109 if (!
WriteAscii (
" defaultCoeffs, defaultDelays, NULL\n"
2110 "};\n", fp, filename))
2123 int hasRate = 0, hasPoints = 0, hasAzimuths = 0;
2124 int hasRadius = 0, hasDistance = 0;
2126 while (! (hasRate && hasPoints && hasAzimuths && hasRadius && hasDistance)) {
2130 if (strcasecmp (ident,
"rate") == 0) {
2132 TrErrorAt (tr, line, col,
"Redefinition of 'rate'.\n");
2139 hData -> mIrRate = (
uint) intVal;
2141 }
else if (strcasecmp (ident,
"points") == 0) {
2143 TrErrorAt (tr, line, col,
"Redefinition of 'points'.\n");
2151 points = (
uint) intVal;
2152 if ((fftSize > 0) && (points > fftSize)) {
2153 TrErrorAt (tr, line, col,
"Value exceeds the overriden FFT size.\n");
2156 if (points < truncSize) {
2157 TrErrorAt (tr, line, col,
"Value is below the truncation size.\n");
2160 hData -> mIrPoints =
points;
2161 hData -> mFftSize = fftSize;
2164 while (points < (4 * hData -> mIrPoints))
2166 hData -> mFftSize =
points;
2167 hData -> mIrSize = 1 + (points / 2);
2169 hData -> mFftSize = fftSize;
2170 hData -> mIrSize = 1 + (fftSize / 2);
2171 if (points > hData -> mIrSize)
2172 hData -> mIrSize =
points;
2175 }
else if (strcasecmp (ident,
"azimuths") == 0) {
2177 TrErrorAt (tr, line, col,
"Redefinition of 'azimuths'.\n");
2182 hData -> mIrCount = 0;
2183 hData -> mEvCount = 0;
2184 hData -> mEvOffset [0] = 0;
2188 hData -> mAzCount [hData -> mEvCount] = (
uint) intVal;
2189 hData -> mIrCount += (
uint) intVal;
2190 hData -> mEvCount ++;
2197 hData -> mEvOffset [hData -> mEvCount] = hData -> mEvOffset [hData -> mEvCount - 1] + ((
uint) intVal);
2205 }
else if (strcasecmp (ident,
"radius") == 0) {
2207 TrErrorAt (tr, line, col,
"Redefinition of 'radius'.\n");
2214 hData -> mRadius = fpVal;
2216 }
else if (strcasecmp (ident,
"distance") == 0) {
2218 TrErrorAt (tr, line, col,
"Redefinition of 'distance'.\n");
2225 hData -> mDistance = fpVal;
2228 TrErrorAt (tr, line, col,
"Expected a metric name.\n");
2240 if (!
TrReadInt (tr, 0, (
int) hData -> mEvCount, & intVal))
2242 (* ei) = (
uint) intVal;
2245 if (!
TrReadInt (tr, 0, (
int) hData -> mAzCount [(* ei)], & intVal))
2247 (* ai) = (
uint) intVal;
2253 if (strcasecmp (ident,
"wave") == 0)
2255 else if (strcasecmp (ident,
"bin_le") == 0)
2257 else if (strcasecmp (ident,
"bin_be") == 0)
2259 else if (strcasecmp (ident,
"ascii") == 0)
2266 if (strcasecmp (ident,
"int") == 0)
2268 else if (strcasecmp (ident,
"fp") == 0)
2283 if (src -> mFormat ==
SF_NONE) {
2284 TrErrorAt (tr, line, col,
"Expected a source format.\n");
2289 if (src -> mFormat ==
SF_WAVE) {
2295 src -> mChannel = (
uint) intVal;
2302 if (src -> mType ==
ET_NONE) {
2303 TrErrorAt (tr, line, col,
"Expected a source element type.\n");
2309 if (src -> mType ==
ET_INT) {
2312 src -> mSize = (
uint) intVal;
2316 if (!
TrReadInt (tr, -2147483647 - 1, 2147483647, & intVal))
2318 if ((abs (intVal) <
MIN_BIN_BITS) || (((
uint) abs (intVal)) > (8 * src -> mSize))) {
2322 src -> mBits = intVal;
2324 src -> mBits = (
int) (8 * src -> mSize);
2328 if (!
TrReadInt (tr, -2147483647 - 1, 2147483647, & intVal))
2330 if ((intVal != 4) && (intVal != 8)) {
2331 TrErrorAt (tr, line, col,
"Expected a value of 4 or 8.\n");
2334 src -> mSize = (
uint) intVal;
2337 }
else if ((src -> mFormat ==
SF_ASCII) && (src -> mType ==
ET_INT)) {
2343 src -> mBits = intVal;
2350 if (!
TrReadInt (tr, 0, 0x7FFFFFFF, & intVal))
2352 src -> mSkip = (
uint) intVal;
2361 if (!
TrReadInt (tr, 0, 0x7FFFFFFF, & intVal))
2363 src -> mOffset = (
uint) intVal;
2377 double * hrir =
NULL;
2378 uint line, col, ei, ai;
2390 if (! setFlag [hData -> mEvOffset [ei] + ai]) {
2395 if (
LoadSource (& src, hData -> mIrRate, hData -> mIrPoints, hrir)) {
2409 setFlag [hData -> mEvOffset [ei] + ai] = 1;
2414 TrErrorAt (tr, line, col,
"Redefinition of source.\n");
2424 while ((ei < hData -> mEvCount) && (setCount [ei] < 1))
2426 if (ei < hData -> mEvCount) {
2427 hData -> mEvStart = ei;
2428 while ((ei < hData -> mEvCount) && (setCount [ei] == hData -> mAzCount [ei]))
2430 if (ei >= hData -> mEvCount) {
2437 TrError (tr,
"Errant data at end of source list.\n");
2440 TrError (tr,
"Missing sources for elevation index %d.\n", ei);
2443 TrError (tr,
"Missing source references.\n");
2459 double * dfa =
NULL;
2462 hData . mIrRate = 0;
2463 hData . mIrPoints = 0;
2464 hData . mFftSize = 0;
2465 hData . mIrSize = 0;
2466 hData . mIrCount = 0;
2467 hData . mEvCount = 0;
2468 hData . mRadius = 0;
2469 hData . mDistance = 0;
2470 fprintf (stdout,
"Reading HRIR definition...\n");
2471 if (inName !=
NULL) {
2472 fp = fopen (inName,
"r");
2474 fprintf (stderr,
"Error: Could not open definition file '%s'\n", inName);
2480 TrSetup (fp,
"<stdin>", & tr);
2487 hData . mHrirs =
CreateArray (hData . mIrCount * hData . mIrSize);
2500 fprintf (stdout,
"Calculating diffuse-field average...\n");
2502 fprintf (stdout,
"Performing diffuse-field equalization...\n");
2506 fprintf (stdout,
"Performing minimum phase reconstruction...\n");
2508 if ((outRate != 0) && (outRate != hData . mIrRate)) {
2509 fprintf (stdout,
"Resampling HRIRs...\n");
2512 fprintf (stdout,
"Truncating minimum-phase HRIRs...\n");
2513 hData . mIrPoints = truncSize;
2514 fprintf (stdout,
"Synthesizing missing elevations...\n");
2516 fprintf (stdout,
"Normalizing final HRIRs...\n");
2518 fprintf (stdout,
"Calculating impulse delays...\n");
2520 snprintf (rateStr, 8,
"%u", hData . mIrRate);
2522 switch (outFormat) {
2524 fprintf (stdout,
"Creating MHR data set file...\n");
2529 fprintf (stderr,
"Creating OpenAL Soft table file...\n");
2542 int main (
const int argc,
const char * argv []) {
2543 const char * inName =
NULL, * outName =
NULL;
2546 uint outRate, fftSize;
2553 fprintf (stderr,
"Error: No command specified. See '%s -h' for help.\n", argv [0]);
2556 if ((strcmp (argv [1],
"--help") == 0) || (strcmp (argv [1],
"-h") == 0)) {
2557 fprintf (stdout,
"HRTF Processing and Composition Utility\n\n");
2558 fprintf (stdout,
"Usage: %s <command> [<option>...]\n\n", argv [0]);
2559 fprintf (stdout,
"Commands:\n");
2560 fprintf (stdout,
" -m, --make-mhr Makes an OpenAL Soft compatible HRTF data set.\n");
2561 fprintf (stdout,
" Defaults output to: ./oalsoft_hrtf_%%r.mhr\n");
2562 fprintf (stdout,
" -t, --make-tab Makes the built-in table used when compiling OpenAL Soft.\n");
2563 fprintf (stdout,
" Defaults output to: ./hrtf_tables.inc\n");
2564 fprintf (stdout,
" -h, --help Displays this help information.\n\n");
2565 fprintf (stdout,
"Options:\n");
2566 fprintf (stdout,
" -r=<rate> Change the data set sample rate to the specified value and\n");
2567 fprintf (stdout,
" resample the HRIRs accordingly.\n");
2568 fprintf (stdout,
" -f=<points> Override the FFT window size (defaults to the first power-\n");
2569 fprintf (stdout,
" of-two that fits four times the number of HRIR points).\n");
2570 fprintf (stdout,
" -e={on|off} Toggle diffuse-field equalization (default: %s).\n", (
DEFAULT_EQUALIZE ?
"on" :
"off"));
2571 fprintf (stdout,
" -s={on|off} Toggle surface-weighted diffuse-field average (default: %s).\n", (
DEFAULT_SURFACE ?
"on" :
"off"));
2572 fprintf (stdout,
" -l={<dB>|none} Specify a limit to the magnitude range of the diffuse-field\n");
2573 fprintf (stdout,
" average (default: %.2f).\n",
DEFAULT_LIMIT);
2574 fprintf (stdout,
" -w=<points> Specify the size of the truncation window that's applied\n");
2575 fprintf (stdout,
" after minimum-phase reconstruction (default: %u).\n",
DEFAULT_TRUNCSIZE);
2576 fprintf (stdout,
" -i=<filename> Specify an HRIR definition file to use (defaults to stdin).\n");
2577 fprintf (stdout,
" -o=<filename> Specify an output file. Overrides command-selected default.\n");
2578 fprintf (stdout,
" Use of '%%r' will be substituted with the data set sample rate.\n");
2581 if ((strcmp (argv [1],
"--make-mhr") == 0) || (strcmp (argv [1],
"-m") == 0)) {
2585 outName =
"./oalsoft_hrtf_%r.mhr";
2587 }
else if ((strcmp (argv [1],
"--make-tab") == 0) || (strcmp (argv [1],
"-t") == 0)) {
2591 outName =
"./hrtf_tables.inc";
2594 fprintf (stderr,
"Error: Invalid command '%s'.\n", argv [1]);
2604 while (argi < argc) {
2605 if (strncmp (argv [argi],
"-r=", 3) == 0) {
2606 outRate = strtoul (& argv [argi] [3], & end, 10);
2608 fprintf (stderr,
"Error: Expected a value from %u to %u for '-r'.\n",
MIN_RATE,
MAX_RATE);
2611 }
else if (strncmp (argv [argi],
"-f=", 3) == 0) {
2612 fftSize = strtoul (& argv [argi] [3], & end, 10);
2613 if ((end [0] !=
'\0') || (fftSize & (fftSize - 1)) || (fftSize <
MIN_FFTSIZE) || (fftSize >
MAX_FFTSIZE)) {
2614 fprintf (stderr,
"Error: Expected a power-of-two value from %u to %u for '-f'.\n",
MIN_FFTSIZE,
MAX_FFTSIZE);
2617 }
else if (strncmp (argv [argi],
"-e=", 3) == 0) {
2618 if (strcmp (& argv [argi] [3],
"on") == 0) {
2620 }
else if (strcmp (& argv [argi] [3],
"off") == 0) {
2623 fprintf (stderr,
"Error: Expected 'on' or 'off' for '-e'.\n");
2626 }
else if (strncmp (argv [argi],
"-s=", 3) == 0) {
2627 if (strcmp (& argv [argi] [3],
"on") == 0) {
2629 }
else if (strcmp (& argv [argi] [3],
"off") == 0) {
2632 fprintf (stderr,
"Error: Expected 'on' or 'off' for '-s'.\n");
2635 }
else if (strncmp (argv [argi],
"-l=", 3) == 0) {
2636 if (strcmp (& argv [argi] [3],
"none") == 0) {
2639 limit = strtod (& argv [argi] [3], & end);
2641 fprintf (stderr,
"Error: Expected 'none' or a value from %.2f to %.2f for '-l'.\n",
MIN_LIMIT,
MAX_LIMIT);
2645 }
else if (strncmp (argv [argi],
"-w=", 3) == 0) {
2646 truncSize = strtoul (& argv [argi] [3], & end, 10);
2648 fprintf (stderr,
"Error: Expected a value from %u to %u in multiples of %u for '-w'.\n",
MIN_TRUNCSIZE,
MAX_TRUNCSIZE, MOD_TRUNCSIZE);
2651 }
else if (strncmp (argv [argi],
"-i=", 3) == 0) {
2652 inName = & argv [argi] [3];
2653 }
else if (strncmp (argv [argi],
"-o=", 3) == 0) {
2654 outName = & argv [argi] [3];
2656 fprintf (stderr,
"Error: Invalid option '%s'.\n", argv [argi]);
2661 if (!
ProcessDefinition (inName, outRate, fftSize, equalize, surface, limit, truncSize, outFormat, outName))
2663 fprintf (stdout,
"Operation completed.\n");
static int StoreTable(const HrirDataT *hData, const char *filename)
static int ReadWaveData(FILE *fp, const SourceRefT *src, const ByteOrderT order, const uint n, double *hrir)
static int TrSkipWhitespace(TokenReaderT *tr)
static void TrSetup(FILE *fp, const char *filename, TokenReaderT *tr)
GLuint const GLfloat * val
static void AverageHrirMagnitude(const double *hrir, const double f, const uint ei, const uint ai, const HrirDataT *hData)
static void SynthesizeHrirs(HrirDataT *hData)
static void FftForward(const uint n, const double *inR, const double *inI, double *outR, double *outI)
static void TrIndication(TokenReaderT *tr, uint *line, uint *column)
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
#define DEFAULT_TRUNCSIZE
static double CalcLTD(const double ev, const double az, const double rad, const double dist)
int main(int argc, char **argv)
static double ComplexAbs(const double r, const double i)
static void DiffuseFieldEqualize(const double *dfa, const HrirDataT *hData)
static void MagnitudeResponse(const uint n, const double *inR, const double *inI, double *out)
static void LimitMagnitudeResponse(const uint n, const double limit, const double *in, double *out)
static void CalcAzIndices(const HrirDataT *hData, const uint ei, const double az, uint *j0, uint *j1, double *jf)
return Display return Display Bool Bool int int e
unsigned long long uint64_t
static double Kaiser(const double b, const double k)
static int ReadAsciiAsDouble(TokenReaderT *tr, const char *filename, const ElementTypeT type, const uint bits, double *out)
static double SincFilter(const int l, const double b, const double gain, const double cutoff, const int i)
GLboolean GLboolean GLboolean GLboolean a
static double BesselI_0(const double x)
static void FftInverse(const uint n, const double *inR, const double *inI, double *outR, double *outI)
EGLImageKHR EGLint * name
static ElementTypeT MatchElementType(const char *ident)
static void CalculateHrtds(HrirDataT *hData)
static int ProcessSources(TokenReaderT *tr, HrirDataT *hData)
static int StrSubst(const char *in, const char *pat, const char *rep, const size_t maxLen, char *out)
GLuint GLuint GLfloat weight
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s0
static void ResamplerSetup(ResamplerT *rs, const uint srcRate, const uint dstRate)
static void TrErrorAt(const TokenReaderT *tr, uint line, uint column, const char *format,...)
static int LoadWaveSource(FILE *fp, SourceRefT *src, const uint hrirRate, const uint n, double *hrir)
static double Lerp(const double a, const double b, const double f)
static int ProcessDefinition(const char *inName, const uint outRate, const uint fftSize, const int equalize, const int surface, const double limit, const uint truncSize, const OutputFormatT outFormat, const char *outName)
static void ResamplerRun(ResamplerT *rs, const uint inN, const double *in, const uint outN, double *out)
static int TrReadInt(TokenReaderT *tr, const int loBound, const int hiBound, int *value)
static void MinimumPhase(const uint n, const double *in, double *outR, double *outI)
static void ComplexMul(const double aR, const double aI, const double bR, const double bI, double *outR, double *outI)
struct TokenReaderT TokenReaderT
#define WAVE_FORMAT_EXTENSIBLE
static void CalculateDfWeights(const HrirDataT *hData, double *weights)
static void FftArrange(const uint n, const double *inR, const double *inI, double *outR, double *outI)
static void ResampleHrirs(const uint rate, HrirDataT *hData)
static int ReadWaveList(FILE *fp, const SourceRefT *src, const ByteOrderT order, const uint n, double *hrir)
static int ReadSourceRef(TokenReaderT *tr, SourceRefT *src)
static SourceFormatT MatchSourceFormat(const char *ident)
static uint Gcd(const uint a, const uint b)
static int TrReadIdent(TokenReaderT *tr, const uint maxLen, char *ident)
EGLSurface EGLint EGLint EGLint width
static int TrIsOperator(TokenReaderT *tr, const char *op)
static double * CreateArray(const size_t n)
#define WAVE_FORMAT_IEEE_FLOAT
#define MAX_WAVE_CHANNELS
const GLubyte GLuint GLuint GLuint GLuint alpha GLboolean GLboolean GLboolean GLboolean alpha GLint GLint GLsizei GLsizei GLenum type GLenum GLint GLenum GLint GLint GLsizei GLsizei GLint border GLenum GLint GLint GLint GLint GLint GLsizei GLsizei height GLsizei GLsizei GLenum GLenum const GLvoid *pixels GLenum GLint GLint GLint j1
static int ReadBin8(FILE *fp, const char *filename, const ByteOrderT order, uint8 *out)
GLenum GLenum GLvoid GLvoid * column
static void ResamplerClear(ResamplerT *rs)
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
static void NormalizeHrirs(const HrirDataT *hData)
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
static int WriteBin4(const ByteOrderT order, const uint bytes, const uint4 in, FILE *fp, const char *filename)
static void ReconstructHrirs(const HrirDataT *hData)
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
static double Clamp(const double val, const double lower, const double upper)
static int ReadBinAsDouble(FILE *fp, const char *filename, const ByteOrderT order, const ElementTypeT type, const uint bytes, const int bits, double *out)
static void ComplexExp(const double inR, const double inI, double *outR, double *outI)
static int TrReadFloat(TokenReaderT *tr, const double loBound, const double hiBound, double *value)
static int LoadSource(SourceRefT *src, const uint hrirRate, const uint n, double *hrir)
static void TrSkipLine(TokenReaderT *tr)
static int LoadAsciiSource(FILE *fp, const SourceRefT *src, const uint n, double *hrir)
struct SourceRefT SourceRefT
static int TrReadOperator(TokenReaderT *tr, const char *op)
EGLSurface EGLint EGLint y
static int StoreMhr(const HrirDataT *hData, const char *filename)
static double Sinc(const double x)
EGLSurface EGLint void ** value
static int ProcessMetrics(TokenReaderT *tr, const uint fftSize, const uint truncSize, HrirDataT *hData)
static int ReadBin4(FILE *fp, const char *filename, const ByteOrderT order, const uint bytes, uint4 *out)
GLdouble GLdouble GLdouble GLdouble q
static uint CalcKaiserOrder(const double rejection, const double transition)
static void Hilbert(const uint n, const double *in, double *outR, double *outI)
static int ReadIndexPair(TokenReaderT *tr, const HrirDataT *hData, uint *ei, uint *ai)
GLdouble GLdouble GLdouble r
static void TrError(const TokenReaderT *tr, const char *format,...)
GLdouble GLdouble GLdouble b
GLint GLint GLint GLint z
static void TrErrorVA(const TokenReaderT *tr, uint line, uint column, const char *format, va_list argPtr)
GLuint GLdouble GLdouble GLint GLint order
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
static void DestroyArray(const double *a)
struct ResamplerT ResamplerT
static void FftSummation(const uint n, const double s, double *re, double *im)
static int ReadWaveFormat(FILE *fp, const ByteOrderT order, const uint hrirRate, SourceRefT *src)
static int WriteAscii(const char *out, FILE *fp, const char *filename)
static void CalculateDiffuseFieldAverage(const HrirDataT *hData, const int weighted, const double limit, double *dfa)
static int HpTpdfDither(const double in, int *hpHist)
static int TrReadString(TokenReaderT *tr, const uint maxLen, char *text)
struct HrirDataT HrirDataT
static int TrLoad(TokenReaderT *tr)
static double CalcKaiserBeta(const double rejection)
static int LoadBinarySource(FILE *fp, const SourceRefT *src, const ByteOrderT order, const uint n, double *hrir)