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