Mercurial > mplayer.hg
annotate libaf/af_hrtf.c @ 35467:364387ae95f4
Fix bug with stop button and playlist.
Although the current file was stopped and its information still
displayed, play would skip to next file in list. Now, the file
stopped can be resumed.
author | ib |
---|---|
date | Sun, 02 Dec 2012 15:56:19 +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 }; |