annotate libaf/af_hrtf.c @ 22697:2fe9bd97a7f6

Fix configure -march detection for athlon-xp The configure script uses SSE support to distinguish between athlon and athlon-xp, but SSE support was tested _after_ deciding the basic CPU type. Thus athlon-xp was always misdetected as athlon. Fix this by moving the CPU extensions check before the CPU type check. Patch from Andrew Savchenko, bircoph list ru.
author uau
date Sun, 18 Mar 2007 13:38:55 +0000
parents ecf562795caf
children fd6f824ef894
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
1 /* Experimental audio filter that mixes 5.1 and 5.1 with matrix
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
2 encoded rear channels into headphone signal using FIR filtering
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
3 with HRTF.
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
4 */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
5 //#include <stdio.h>
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
6 #include <stdlib.h>
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
7 #include <string.h>
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
8 #include <unistd.h>
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
9 #include <inttypes.h>
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
10
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
11 #include <math.h>
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
12
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
13 #include "af.h"
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
14 #include "dsp.h"
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
15
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
16 /* HRTF filter coefficients and adjustable parameters */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
17 #include "af_hrtf.h"
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
18
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
19 typedef struct af_hrtf_s {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
20 /* Lengths */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
21 int dlbuflen, hrflen, basslen;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
22 /* L, C, R, Ls, Rs channels */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
23 float *lf, *rf, *lr, *rr, *cf, *cr;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
24 float *cf_ir, *af_ir, *of_ir, *ar_ir, *or_ir, *cr_ir;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
25 int cf_o, af_o, of_o, ar_o, or_o, cr_o;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
26 /* Bass */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
27 float *ba_l, *ba_r;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
28 float *ba_ir;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
29 /* Whether to matrix decode the rear center channel */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
30 int matrix_mode;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
31 /* How to decode the input:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
32 0 = 5/5+1 channels
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
33 1 = 2 channels
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
34 2 = matrix encoded 2 channels */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
35 int decode_mode;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
36 /* Full wave rectified (FWR) amplitudes and gain used to steer the
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
37 active matrix decoding of front channels (variable names
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
38 lpr/lmr means Lt + Rt, Lt - Rt) */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
39 float l_fwr, r_fwr, lpr_fwr, lmr_fwr;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
40 float adapt_l_gain, adapt_r_gain, adapt_lpr_gain, adapt_lmr_gain;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
41 /* Matrix input decoding require special FWR buffer, since the
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
42 decoding is done in place. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
43 float *fwrbuf_l, *fwrbuf_r, *fwrbuf_lr, *fwrbuf_rr;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
44 /* Rear channel delay buffer for matrix decoding */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
45 float *rear_dlbuf;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
46 /* Full wave rectified amplitude and gain used to steer the active
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
47 matrix decoding of center rear channel */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
48 float lr_fwr, rr_fwr, lrprr_fwr, lrmrr_fwr;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
49 float adapt_lr_gain, adapt_rr_gain;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
50 float adapt_lrprr_gain, adapt_lrmrr_gain;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
51 /* Cyclic position on the ring buffer */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
52 int cyc_pos;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
53 int print_flag;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
54 } af_hrtf_t;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
55
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
56 /* Convolution on a ring buffer
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
57 * nx: length of the ring buffer
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
58 * nk: length of the convolution kernel
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
59 * sx: ring buffer
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
60 * sk: convolution kernel
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
61 * offset: offset on the ring buffer, can be
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
62 */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
63 static float conv(const int nx, const int nk, float *sx, float *sk,
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
64 const int offset)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
65 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
66 /* k = reminder of offset / nx */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
67 int k = offset >= 0 ? offset % nx : nx + (offset % nx);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
68
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
69 if(nk + k <= nx)
14275
de13fd557440 less namespace pollution #2 (prefixed globals in filter.c with af_filter_)
alex
parents: 14245
diff changeset
70 return af_filter_fir(nk, sx + k, sk);
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
71 else
14275
de13fd557440 less namespace pollution #2 (prefixed globals in filter.c with af_filter_)
alex
parents: 14245
diff changeset
72 return af_filter_fir(nk + k - nx, sx, sk + nx - k) +
de13fd557440 less namespace pollution #2 (prefixed globals in filter.c with af_filter_)
alex
parents: 14245
diff changeset
73 af_filter_fir(nx - k, sx + k, sk);
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
74 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
75
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
76 /* Detect when the impulse response starts (significantly) */
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 15384
diff changeset
77 static int pulse_detect(float *sx)
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
78 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
79 /* nmax must be the reference impulse response length (128) minus
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
80 s->hrflen */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
81 const int nmax = 128 - HRTFFILTLEN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
82 const float thresh = IRTHRESH;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
83 int i;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
84
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
85 for(i = 0; i < nmax; i++)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
86 if(fabs(sx[i]) > thresh)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
87 return i;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
88 return 0;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
89 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
90
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
91 /* Fuzzy matrix coefficient transfer function to "lock" the matrix on
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
92 a effectively passive mode if the gain is approximately 1 */
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 15384
diff changeset
93 static inline float passive_lock(float x)
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
94 {
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
95 const float x1 = x - 1;
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
96 const float ax1s = fabs(x - 1) * (1.0 / MATAGCLOCK);
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
97
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
98 return x1 - x1 / (1 + ax1s * ax1s) + 1;
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
99 }
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
100
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
101 /* Unified active matrix decoder for 2 channel matrix encoded surround
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
102 sources */
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 15384
diff changeset
103 static inline void matrix_decode(short *in, const int k, const int il,
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
104 const int ir, const int decode_rear,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
105 const int dlbuflen,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
106 float l_fwr, float r_fwr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
107 float lpr_fwr, float lmr_fwr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
108 float *adapt_l_gain, float *adapt_r_gain,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
109 float *adapt_lpr_gain, float *adapt_lmr_gain,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
110 float *lf, float *rf, float *lr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
111 float *rr, float *cf)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
112 {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
113 const int kr = (k + MATREARDELAY) % dlbuflen;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
114 float l_gain = (l_fwr + r_fwr) /
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
115 (1 + l_fwr + l_fwr);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
116 float r_gain = (l_fwr + r_fwr) /
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
117 (1 + r_fwr + r_fwr);
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
118 /* The 2nd axis has strong gain fluctuations, and therefore require
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
119 limits. The factor corresponds to the 1 / amplification of (Lt
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
120 - Rt) when (Lt, Rt) is strongly correlated. (e.g. during
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
121 dialogues). It should be bigger than -12 dB to prevent
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
122 distortion. */
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
123 float lmr_lim_fwr = lmr_fwr > M9_03DB * lpr_fwr ?
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
124 lmr_fwr : M9_03DB * lpr_fwr;
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
125 float lpr_gain = (lpr_fwr + lmr_lim_fwr) /
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
126 (1 + lpr_fwr + lpr_fwr);
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
127 float lmr_gain = (lpr_fwr + lmr_lim_fwr) /
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
128 (1 + lmr_lim_fwr + lmr_lim_fwr);
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
129 float lmr_unlim_gain = (lpr_fwr + lmr_fwr) /
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
130 (1 + lmr_fwr + lmr_fwr);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
131 float lpr, lmr;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
132 float l_agc, r_agc, lpr_agc, lmr_agc;
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
133 float f, d_gain, c_gain, c_agc_cfk;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
134
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
135 #if 0
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
136 static int counter = 0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
137 static FILE *fp_out;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
138
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
139 if(counter == 0)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
140 fp_out = fopen("af_hrtf.log", "w");
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
141 if(counter % 240 == 0)
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
142 fprintf(fp_out, "%g %g %g %g %g ", counter * (1.0 / 48000),
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
143 l_gain, r_gain, lpr_gain, lmr_gain);
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
144 #endif
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
145
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
146 /*** AXIS NO. 1: (Lt, Rt) -> (C, Ls, Rs) ***/
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
147 /* AGC adaption */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
148 d_gain = (fabs(l_gain - *adapt_l_gain) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
149 fabs(r_gain - *adapt_r_gain)) * 0.5;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
150 f = d_gain * (1.0 / MATAGCTRIG);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
151 f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
152 *adapt_l_gain = (1 - f) * *adapt_l_gain + f * l_gain;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
153 *adapt_r_gain = (1 - f) * *adapt_r_gain + f * r_gain;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
154 /* Matrix */
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
155 l_agc = in[il] * passive_lock(*adapt_l_gain);
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
156 r_agc = in[ir] * passive_lock(*adapt_r_gain);
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
157 cf[k] = (l_agc + r_agc) * M_SQRT1_2;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
158 if(decode_rear) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
159 lr[kr] = rr[kr] = (l_agc - r_agc) * M_SQRT1_2;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
160 /* Stereo rear channel is steered with the same AGC steering as
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
161 the decoding matrix. Note this requires a fast updating AGC
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
162 at the order of 20 ms (which is the case here). */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
163 lr[kr] *= (l_fwr + l_fwr) /
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
164 (1 + l_fwr + r_fwr);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
165 rr[kr] *= (r_fwr + r_fwr) /
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
166 (1 + l_fwr + r_fwr);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
167 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
168
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
169 /*** AXIS NO. 2: (Lt + Rt, Lt - Rt) -> (L, R) ***/
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
170 lpr = (in[il] + in[ir]) * M_SQRT1_2;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
171 lmr = (in[il] - in[ir]) * M_SQRT1_2;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
172 /* AGC adaption */
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
173 d_gain = fabs(lmr_unlim_gain - *adapt_lmr_gain);
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
174 f = d_gain * (1.0 / MATAGCTRIG);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
175 f = MATAGCDECAY - MATAGCDECAY / (1 + f * f);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
176 *adapt_lpr_gain = (1 - f) * *adapt_lpr_gain + f * lpr_gain;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
177 *adapt_lmr_gain = (1 - f) * *adapt_lmr_gain + f * lmr_gain;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
178 /* Matrix */
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
179 lpr_agc = lpr * passive_lock(*adapt_lpr_gain);
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
180 lmr_agc = lmr * passive_lock(*adapt_lmr_gain);
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
181 lf[k] = (lpr_agc + lmr_agc) * M_SQRT1_2;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
182 rf[k] = (lpr_agc - lmr_agc) * M_SQRT1_2;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
183
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
184 /*** CENTER FRONT CANCELLATION ***/
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
185 /* A heuristic approach exploits that Lt + Rt gain contains the
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
186 information about Lt, Rt correlation. This effectively reshapes
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
187 the front and rear "cones" to concentrate Lt + Rt to C and
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
188 introduce Lt - Rt in L, R. */
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
189 /* 0.67677 is the emprical lower bound for lpr_gain. */
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
190 c_gain = 8 * (*adapt_lpr_gain - 0.67677);
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
191 c_gain = c_gain > 0 ? c_gain : 0;
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
192 /* c_gain should not be too high, not even reaching full
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
193 cancellation (~ 0.50 - 0.55 at current AGC implementation), or
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
194 the center will s0und too narrow. */
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
195 c_gain = MATCOMPGAIN / (1 + c_gain * c_gain);
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
196 c_agc_cfk = c_gain * cf[k];
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
197 lf[k] -= c_agc_cfk;
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
198 rf[k] -= c_agc_cfk;
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
199 cf[k] += c_agc_cfk + c_agc_cfk;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
200 #if 0
15124
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
201 if(counter % 240 == 0)
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
202 fprintf(fp_out, "%g %g %g %g %g\n",
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
203 *adapt_l_gain, *adapt_r_gain,
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
204 *adapt_lpr_gain, *adapt_lmr_gain,
e267fad254fb More HRTF enhancements
henry
parents: 15082
diff changeset
205 c_gain);
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
206 counter++;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
207 #endif
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
208 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
209
18967
36db63e8e5d7 makes several libaf functions static coz they are not used outside their source files. Patch by Stefan Huehner, stefan AT huehner-org
reynaldo
parents: 15384
diff changeset
210 static inline void update_ch(af_hrtf_t *s, short *in, const int k)
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
211 {
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
212 const int fwr_pos = (k + FWRDURATION) % s->dlbuflen;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
213 /* Update the full wave rectified total amplitude */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
214 /* Input matrix decoder */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
215 if(s->decode_mode == HRTF_MIX_MATRIX2CH) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
216 s->l_fwr += abs(in[0]) - fabs(s->fwrbuf_l[fwr_pos]);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
217 s->r_fwr += abs(in[1]) - fabs(s->fwrbuf_r[fwr_pos]);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
218 s->lpr_fwr += abs(in[0] + in[1]) -
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
219 fabs(s->fwrbuf_l[fwr_pos] + s->fwrbuf_r[fwr_pos]);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
220 s->lmr_fwr += abs(in[0] - in[1]) -
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
221 fabs(s->fwrbuf_l[fwr_pos] - s->fwrbuf_r[fwr_pos]);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
222 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
223 /* Rear matrix decoder */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
224 if(s->matrix_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
225 s->lr_fwr += abs(in[2]) - fabs(s->fwrbuf_lr[fwr_pos]);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
226 s->rr_fwr += abs(in[3]) - fabs(s->fwrbuf_rr[fwr_pos]);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
227 s->lrprr_fwr += abs(in[2] + in[3]) -
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
228 fabs(s->fwrbuf_lr[fwr_pos] + s->fwrbuf_rr[fwr_pos]);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
229 s->lrmrr_fwr += abs(in[2] - in[3]) -
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
230 fabs(s->fwrbuf_lr[fwr_pos] - s->fwrbuf_rr[fwr_pos]);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
231 }
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
232
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
233 switch (s->decode_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
234 case HRTF_MIX_51:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
235 /* 5/5+1 channel sources */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
236 s->lf[k] = in[0];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
237 s->cf[k] = in[4];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
238 s->rf[k] = in[1];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
239 s->fwrbuf_lr[k] = s->lr[k] = in[2];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
240 s->fwrbuf_rr[k] = s->rr[k] = in[3];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
241 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
242 case HRTF_MIX_MATRIX2CH:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
243 /* Matrix encoded 2 channel sources */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
244 s->fwrbuf_l[k] = in[0];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
245 s->fwrbuf_r[k] = in[1];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
246 matrix_decode(in, k, 0, 1, 1, s->dlbuflen,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
247 s->l_fwr, s->r_fwr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
248 s->lpr_fwr, s->lmr_fwr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
249 &(s->adapt_l_gain), &(s->adapt_r_gain),
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
250 &(s->adapt_lpr_gain), &(s->adapt_lmr_gain),
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
251 s->lf, s->rf, s->lr, s->rr, s->cf);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
252 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
253 case HRTF_MIX_STEREO:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
254 /* Stereo sources */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
255 s->lf[k] = in[0];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
256 s->rf[k] = in[1];
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
257 s->cf[k] = s->lr[k] = s->rr[k] = 0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
258 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
259 }
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
260
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
261 /* We need to update the bass compensation delay line, too. */
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
262 s->ba_l[k] = in[0] + in[4] + in[2];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
263 s->ba_r[k] = in[4] + in[1] + in[3];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
264 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
265
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
266 /* Initialization and runtime control */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
267 static int control(struct af_instance_s *af, int cmd, void* arg)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
268 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
269 af_hrtf_t *s = af->setup;
15384
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
270 int test_output_res;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
271 char mode;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
272
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
273 switch(cmd) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
274 case AF_CONTROL_REINIT:
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
275 af->data->rate = ((af_data_t*)arg)->rate;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
276 if(af->data->rate != 48000) {
14213
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 13996
diff changeset
277 // automatic samplerate adjustment in the filter chain
3c56b18bbb0c Make filters request a supported input format instead of failing.
reimar
parents: 13996
diff changeset
278 // is not yet supported.
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
279 af_msg(AF_MSG_ERROR,
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
280 "[hrtf] ERROR: Sampling rate is not 48000 Hz (%d)!\n",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
281 af->data->rate);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
282 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
283 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
284 af->data->nch = ((af_data_t*)arg)->nch;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
285 if(af->data->nch == 2) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
286 /* 2 channel input */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
287 if(s->decode_mode != HRTF_MIX_MATRIX2CH) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
288 /* Default behavior is stereo mixing. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
289 s->decode_mode = HRTF_MIX_STEREO;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
290 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
291 }
15384
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
292 else if (af->data->nch < 5)
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
293 af->data->nch = 5;
14245
815f03b7cee5 removing AFMT_ dependancy
alex
parents: 14213
diff changeset
294 af->data->format = AF_FORMAT_S16_NE;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
295 af->data->bps = 2;
15384
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
296 test_output_res = af_test_output(af, (af_data_t*)arg);
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
297 af->mul.n = 2;
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
298 af->mul.d = af->data->nch;
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
299 // after testing input set the real output format
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
300 af->data->nch = 2;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
301 s->print_flag = 1;
15384
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
302 return test_output_res;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
303 case AF_CONTROL_COMMAND_LINE:
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
304 sscanf((char*)arg, "%c", &mode);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
305 switch(mode) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
306 case 'm':
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
307 /* Use matrix rear decoding. */
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
308 s->matrix_mode = 1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
309 break;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
310 case 's':
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
311 /* Input needs matrix decoding. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
312 s->decode_mode = HRTF_MIX_MATRIX2CH;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
313 break;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
314 case '0':
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
315 s->matrix_mode = 0;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
316 break;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
317 default:
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
318 af_msg(AF_MSG_ERROR,
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
319 "[hrtf] Mode is neither 'm', 's', nor '0' (%c).\n",
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
320 mode);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
321 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
322 }
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
323 s->print_flag = 1;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
324 return AF_OK;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
325 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
326
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
327 return AF_UNKNOWN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
328 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
329
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
330 /* Deallocate memory */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
331 static void uninit(struct af_instance_s *af)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
332 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
333 if(af->setup) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
334 af_hrtf_t *s = af->setup;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
335
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
336 if(s->lf)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
337 free(s->lf);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
338 if(s->rf)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
339 free(s->rf);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
340 if(s->lr)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
341 free(s->lr);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
342 if(s->rr)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
343 free(s->rr);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
344 if(s->cf)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
345 free(s->cf);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
346 if(s->cr)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
347 free(s->cr);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
348 if(s->ba_l)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
349 free(s->ba_l);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
350 if(s->ba_r)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
351 free(s->ba_r);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
352 if(s->ba_ir)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
353 free(s->ba_ir);
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
354 if(s->fwrbuf_l)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
355 free(s->fwrbuf_l);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
356 if(s->fwrbuf_r)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
357 free(s->fwrbuf_r);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
358 if(s->fwrbuf_lr)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
359 free(s->fwrbuf_lr);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
360 if(s->fwrbuf_rr)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
361 free(s->fwrbuf_rr);
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
362 free(af->setup);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
363 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
364 if(af->data)
22179
ecf562795caf Fix memory leaks.
uau
parents: 18967
diff changeset
365 free(af->data->audio);
ecf562795caf Fix memory leaks.
uau
parents: 18967
diff changeset
366 free(af->data);
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
367 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
368
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
369 /* Filter data through filter
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
370
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
371 Two "tricks" are used to compensate the "color" of the KEMAR data:
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
372
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
373 1. The KEMAR data is refiltered to ensure that the front L, R channels
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
374 on the same side of the ear are equalized (especially in the high
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
375 frequencies).
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
376
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
377 2. A bass compensation is introduced to ensure that 0-200 Hz are not
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
378 damped (without any real 3D acoustical image, however).
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
379 */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
380 static af_data_t* play(struct af_instance_s *af, af_data_t *data)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
381 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
382 af_hrtf_t *s = af->setup;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
383 short *in = data->audio; // Input audio data
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
384 short *out = NULL; // Output audio data
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
385 short *end = in + data->len / sizeof(short); // Loop end
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
386 float common, left, right, diff, left_b, right_b;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
387 const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
388
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
389 if(AF_OK != RESIZE_LOCAL_BUFFER(af, data))
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
390 return NULL;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
391
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
392 if(s->print_flag) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
393 s->print_flag = 0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
394 switch (s->decode_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
395 case HRTF_MIX_51:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
396 af_msg(AF_MSG_INFO,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
397 "[hrtf] Using HRTF to mix %s discrete surround into "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
398 "L, R channels\n", s->matrix_mode ? "5+1" : "5");
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
399 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
400 case HRTF_MIX_STEREO:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
401 af_msg(AF_MSG_INFO,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
402 "[hrtf] Using HRTF to mix stereo into "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
403 "L, R channels\n");
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
404 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
405 case HRTF_MIX_MATRIX2CH:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
406 af_msg(AF_MSG_INFO,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
407 "[hrtf] Using active matrix to decode 2 channel "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
408 "input, HRTF to mix %s matrix surround into "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
409 "L, R channels\n", "3/2");
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
410 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
411 default:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
412 af_msg(AF_MSG_WARN,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
413 "[hrtf] bogus decode_mode: %d\n", s->decode_mode);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
414 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
415 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
416
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
417 if(s->matrix_mode)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
418 af_msg(AF_MSG_INFO,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
419 "[hrtf] Using active matrix to decode rear center "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
420 "channel\n");
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
421 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
422
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
423 out = af->data->audio;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
424
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
425 /* MPlayer's 5 channel layout (notation for the variable):
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
426 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
427 * 0: L (LF), 1: R (RF), 2: Ls (LR), 3: Rs (RR), 4: C (CF), matrix
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
428 * encoded: Cs (CR)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
429 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
430 * or: L = left, C = center, R = right, F = front, R = rear
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
431 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
432 * Filter notation:
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
433 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
434 * CF
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
435 * OF AF
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
436 * Ear->
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
437 * OR AR
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
438 * CR
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
439 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
440 * or: C = center, A = same side, O = opposite, F = front, R = rear
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
441 */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
442
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
443 while(in < end) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
444 const int k = s->cyc_pos;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
445
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
446 update_ch(s, in, k);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
447
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
448 /* Simulate a 7.5 ms -20 dB echo of the center channel in the
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
449 front channels (like reflection from a room wall) - a kind of
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
450 psycho-acoustically "cheating" to focus the center front
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
451 channel, which is normally hard to be perceived as front */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
452 s->lf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
453 s->rf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
454
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
455 switch (s->decode_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
456 case HRTF_MIX_51:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
457 case HRTF_MIX_MATRIX2CH:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
458 /* Mixer filter matrix */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
459 common = conv(dblen, hlen, s->cf, s->cf_ir, k + s->cf_o);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
460 if(s->matrix_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
461 /* In matrix decoding mode, the rear channel gain must be
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
462 renormalized, as there is an additional channel. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
463 matrix_decode(in, k, 2, 3, 0, s->dlbuflen,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
464 s->lr_fwr, s->rr_fwr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
465 s->lrprr_fwr, s->lrmrr_fwr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
466 &(s->adapt_lr_gain), &(s->adapt_rr_gain),
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
467 &(s->adapt_lrprr_gain), &(s->adapt_lrmrr_gain),
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
468 s->lr, s->rr, NULL, NULL, s->cr);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
469 common +=
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
470 conv(dblen, hlen, s->cr, s->cr_ir, k + s->cr_o) *
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
471 M1_76DB;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
472 left =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
473 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
474 conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
475 (conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
476 conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o)) *
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
477 M1_76DB + common);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
478 right =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
479 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
480 conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
481 (conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
482 conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o)) *
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
483 M1_76DB + common);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
484 } else {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
485 left =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
486 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
487 conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
488 conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
489 conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
490 common);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
491 right =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
492 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
493 conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
494 conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
495 conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
496 common);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
497 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
498 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
499 case HRTF_MIX_STEREO:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
500 left =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
501 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
502 conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o));
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
503 right =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
504 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
505 conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o));
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
506 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
507 default:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
508 /* make gcc happy */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
509 left = 0.0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
510 right = 0.0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
511 break;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
512 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
513
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
514 /* Bass compensation for the lower frequency cut of the HRTF. A
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
515 cross talk of the left and right channel is introduced to
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
516 match the directional characteristics of higher frequencies.
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
517 The bass will not have any real 3D perception, but that is
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
518 OK (note at 180 Hz, the wavelength is about 2 m, and any
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
519 spatial perception is impossible). */
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
520 left_b = conv(dblen, blen, s->ba_l, s->ba_ir, k);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
521 right_b = conv(dblen, blen, s->ba_r, s->ba_ir, k);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
522 left += (1 - BASSCROSS) * left_b + BASSCROSS * right_b;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
523 right += (1 - BASSCROSS) * right_b + BASSCROSS * left_b;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
524 /* Also mix the LFE channel (if available) */
15384
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
525 if(data->nch >= 6) {
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
526 left += in[5] * M3_01DB;
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
527 right += in[5] * M3_01DB;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
528 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
529
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
530 /* Amplitude renormalization. */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
531 left *= AMPLNORM;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
532 right *= AMPLNORM;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
533
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
534 switch (s->decode_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
535 case HRTF_MIX_51:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
536 case HRTF_MIX_STEREO:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
537 /* "Cheating": linear stereo expansion to amplify the 3D
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
538 perception. Note: Too much will destroy the acoustic space
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
539 and may even result in headaches. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
540 diff = STEXPAND2 * (left - right);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
541 out[0] = (int16_t)(left + diff);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
542 out[1] = (int16_t)(right - diff);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
543 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
544 case HRTF_MIX_MATRIX2CH:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
545 /* Do attempt any stereo expansion with matrix encoded
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
546 sources. The L, R channels are already stereo expanded
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
547 by the steering, any further stereo expansion will sound
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
548 very unnatural. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
549 out[0] = (int16_t)left;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
550 out[1] = (int16_t)right;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
551 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
552 }
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
553
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
554 /* Next sample... */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
555 in = &in[data->nch];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
556 out = &out[af->data->nch];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
557 (s->cyc_pos)--;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
558 if(s->cyc_pos < 0)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
559 s->cyc_pos += dblen;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
560 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
561
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
562 /* Set output data */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
563 data->audio = af->data->audio;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
564 data->len = (data->len * af->mul.n) / af->mul.d;
15384
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
565 data->nch = 2;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
566
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
567 return data;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
568 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
569
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
570 static int allocate(af_hrtf_t *s)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
571 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
572 if ((s->lf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
573 if ((s->rf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
574 if ((s->lr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
575 if ((s->rr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
576 if ((s->cf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
577 if ((s->cr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
578 if ((s->ba_l = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
579 if ((s->ba_r = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
580 if ((s->fwrbuf_l =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
581 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
582 if ((s->fwrbuf_r =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
583 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
584 if ((s->fwrbuf_lr =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
585 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
586 if ((s->fwrbuf_rr =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
587 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
588 return 0;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
589 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
590
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
591 /* Allocate memory and set function pointers */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
592 static int open(af_instance_t* af)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
593 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
594 int i;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
595 af_hrtf_t *s;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
596 float fc;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
597
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
598 af->control = control;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
599 af->uninit = uninit;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
600 af->play = play;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
601 af->mul.n = 1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
602 af->mul.d = 1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
603 af->data = calloc(1, sizeof(af_data_t));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
604 af->setup = calloc(1, sizeof(af_hrtf_t));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
605 if((af->data == NULL) || (af->setup == NULL))
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
606 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
607
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
608 s = af->setup;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
609
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
610 s->dlbuflen = DELAYBUFLEN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
611 s->hrflen = HRTFFILTLEN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
612 s->basslen = BASSFILTLEN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
613
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
614 s->cyc_pos = s->dlbuflen - 1;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
615 /* With a full (two axis) steering matrix decoder, s->matrix_mode
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
616 should not be enabled lightly (it will also steer the Ls, Rs
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
617 channels). */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
618 s->matrix_mode = 0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
619 s->decode_mode = HRTF_MIX_51;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
620
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
621 s->print_flag = 1;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
622
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
623 if (allocate(s) != 0) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
624 af_msg(AF_MSG_ERROR, "[hrtf] Memory allocation error.\n");
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
625 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
626 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
627
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
628 for(i = 0; i < s->dlbuflen; i++)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
629 s->lf[i] = s->rf[i] = s->lr[i] = s->rr[i] = s->cf[i] =
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
630 s->cr[i] = 0;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
631
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
632 s->lr_fwr =
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
633 s->rr_fwr = 0;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
634
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
635 s->cf_ir = cf_filt + (s->cf_o = pulse_detect(cf_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
636 s->af_ir = af_filt + (s->af_o = pulse_detect(af_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
637 s->of_ir = of_filt + (s->of_o = pulse_detect(of_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
638 s->ar_ir = ar_filt + (s->ar_o = pulse_detect(ar_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
639 s->or_ir = or_filt + (s->or_o = pulse_detect(or_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
640 s->cr_ir = cr_filt + (s->cr_o = pulse_detect(cr_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
641
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
642 if((s->ba_ir = malloc(s->basslen * sizeof(float))) == NULL) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
643 af_msg(AF_MSG_ERROR, "[hrtf] Memory allocation error.\n");
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
644 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
645 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
646 fc = 2.0 * BASSFILTFREQ / (float)af->data->rate;
14275
de13fd557440 less namespace pollution #2 (prefixed globals in filter.c with af_filter_)
alex
parents: 14245
diff changeset
647 if(af_filter_design_fir(s->basslen, s->ba_ir, &fc, LP | KAISER, 4 * M_PI) ==
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
648 -1) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
649 af_msg(AF_MSG_ERROR, "[hrtf] Unable to design low-pass "
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
650 "filter.\n");
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
651 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
652 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
653 for(i = 0; i < s->basslen; i++)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
654 s->ba_ir[i] *= BASSGAIN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
655
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
656 return AF_OK;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
657 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
658
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
659 /* Description of this filter */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
660 af_info_t af_info_hrtf = {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
661 "HRTF Headphone",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
662 "hrtf",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
663 "ylai",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
664 "",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
665 AF_FLAGS_REENTRANT,
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
666 open
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
667 };