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