annotate libaf/af_hrtf.c @ 33404:7dfe52e4f2e1

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