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