annotate libaf/af_hrtf.c @ 28992:947ef23ba798

Test if create_vdp_decoder() might succeed by calling it from config() with a small value for max_reference_frames. This does not make automatic recovery by using software decoder possible, but lets MPlayer fail more graciously on - actually existing - buggy hardware that does not support certain H264 widths when using hardware accelerated decoding (784, 864, 944, 1024, 1808, 1888 pixels on NVIDIA G98) and if the user tries to hardware-decode more samples at the same time than supported. Might break playback of H264 Intra-Only samples on hardware with very little video memory.
author cehoyos
date Sat, 21 Mar 2009 20:11:05 +0000
parents 72d0b1444141
children 8c706ce21c6f
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
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
78 * offset: offset on the ring buffer, can be
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.
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
296 af_msg(AF_MSG_ERROR,
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:
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
334 af_msg(AF_MSG_ERROR,
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;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
341 }
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
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
352 if(s->lf)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
353 free(s->lf);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
354 if(s->rf)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
355 free(s->rf);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
356 if(s->lr)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
357 free(s->lr);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
358 if(s->rr)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
359 free(s->rr);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
360 if(s->cf)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
361 free(s->cf);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
362 if(s->cr)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
363 free(s->cr);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
364 if(s->ba_l)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
365 free(s->ba_l);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
366 if(s->ba_r)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
367 free(s->ba_r);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
368 if(s->ba_ir)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
369 free(s->ba_ir);
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
370 if(s->fwrbuf_l)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
371 free(s->fwrbuf_l);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
372 if(s->fwrbuf_r)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
373 free(s->fwrbuf_r);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
374 if(s->fwrbuf_lr)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
375 free(s->fwrbuf_lr);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
376 if(s->fwrbuf_rr)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
377 free(s->fwrbuf_rr);
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
378 free(af->setup);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
379 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
380 if(af->data)
22179
ecf562795caf Fix memory leaks.
uau
parents: 18967
diff changeset
381 free(af->data->audio);
ecf562795caf Fix memory leaks.
uau
parents: 18967
diff changeset
382 free(af->data);
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
383 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
384
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
385 /* Filter data through filter
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
386
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
387 Two "tricks" are used to compensate the "color" of the KEMAR data:
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
388
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
389 1. The KEMAR data is refiltered to ensure that the front L, R channels
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
390 on the same side of the ear are equalized (especially in the high
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
391 frequencies).
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
392
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
393 2. A bass compensation is introduced to ensure that 0-200 Hz are not
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
394 damped (without any real 3D acoustical image, however).
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
395 */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
396 static af_data_t* play(struct af_instance_s *af, af_data_t *data)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
397 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
398 af_hrtf_t *s = af->setup;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
399 short *in = data->audio; // Input audio data
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
400 short *out = NULL; // Output audio data
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
401 short *end = in + data->len / sizeof(short); // Loop end
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
402 float common, left, right, diff, left_b, right_b;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
403 const int dblen = s->dlbuflen, hlen = s->hrflen, blen = s->basslen;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
404
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
405 if(AF_OK != RESIZE_LOCAL_BUFFER(af, data))
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
406 return NULL;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
407
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
408 if(s->print_flag) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
409 s->print_flag = 0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
410 switch (s->decode_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
411 case HRTF_MIX_51:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
412 af_msg(AF_MSG_INFO,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
413 "[hrtf] Using HRTF to mix %s discrete surround into "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
414 "L, R channels\n", s->matrix_mode ? "5+1" : "5");
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
415 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
416 case HRTF_MIX_STEREO:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
417 af_msg(AF_MSG_INFO,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
418 "[hrtf] Using HRTF to mix stereo into "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
419 "L, R channels\n");
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
420 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
421 case HRTF_MIX_MATRIX2CH:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
422 af_msg(AF_MSG_INFO,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
423 "[hrtf] Using active matrix to decode 2 channel "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
424 "input, HRTF to mix %s matrix surround into "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
425 "L, R channels\n", "3/2");
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
426 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
427 default:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
428 af_msg(AF_MSG_WARN,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
429 "[hrtf] bogus decode_mode: %d\n", s->decode_mode);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
430 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
431 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
432
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
433 if(s->matrix_mode)
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
434 af_msg(AF_MSG_INFO,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
435 "[hrtf] Using active matrix to decode rear center "
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
436 "channel\n");
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
437 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
438
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
439 out = af->data->audio;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
440
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
441 /* MPlayer's 5 channel layout (notation for the variable):
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
442 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
443 * 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
444 * encoded: Cs (CR)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
445 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
446 * or: L = left, C = center, R = right, F = front, R = rear
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
447 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
448 * Filter notation:
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
449 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
450 * CF
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
451 * OF AF
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
452 * Ear->
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
453 * OR AR
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
454 * CR
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
455 *
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
456 * or: C = center, A = same side, O = opposite, F = front, R = rear
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
457 */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
458
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
459 while(in < end) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
460 const int k = s->cyc_pos;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
461
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
462 update_ch(s, in, k);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
463
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
464 /* Simulate a 7.5 ms -20 dB echo of the center channel in the
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
465 front channels (like reflection from a room wall) - a kind of
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
466 psycho-acoustically "cheating" to focus the center front
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
467 channel, which is normally hard to be perceived as front */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
468 s->lf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
469 s->rf[k] += CFECHOAMPL * s->cf[(k + CFECHODELAY) % s->dlbuflen];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
470
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
471 switch (s->decode_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
472 case HRTF_MIX_51:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
473 case HRTF_MIX_MATRIX2CH:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
474 /* Mixer filter matrix */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
475 common = conv(dblen, hlen, s->cf, s->cf_ir, k + s->cf_o);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
476 if(s->matrix_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
477 /* In matrix decoding mode, the rear channel gain must be
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
478 renormalized, as there is an additional channel. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
479 matrix_decode(in, k, 2, 3, 0, s->dlbuflen,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
480 s->lr_fwr, s->rr_fwr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
481 s->lrprr_fwr, s->lrmrr_fwr,
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
482 &(s->adapt_lr_gain), &(s->adapt_rr_gain),
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
483 &(s->adapt_lrprr_gain), &(s->adapt_lrmrr_gain),
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
484 s->lr, s->rr, NULL, NULL, s->cr);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
485 common +=
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
486 conv(dblen, hlen, s->cr, s->cr_ir, k + s->cr_o) *
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
487 M1_76DB;
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 M1_76DB + 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 M1_76DB + common);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
500 } else {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
501 left =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
502 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
503 conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
504 conv(dblen, hlen, s->lr, s->ar_ir, k + s->ar_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
505 conv(dblen, hlen, s->rr, s->or_ir, k + s->or_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
506 common);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
507 right =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
508 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
509 conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
510 conv(dblen, hlen, s->rr, s->ar_ir, k + s->ar_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
511 conv(dblen, hlen, s->lr, s->or_ir, k + s->or_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
512 common);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
513 }
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
514 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
515 case HRTF_MIX_STEREO:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
516 left =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
517 ( conv(dblen, hlen, s->lf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
518 conv(dblen, hlen, s->rf, s->of_ir, k + s->of_o));
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
519 right =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
520 ( conv(dblen, hlen, s->rf, s->af_ir, k + s->af_o) +
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
521 conv(dblen, hlen, s->lf, s->of_ir, k + s->of_o));
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
522 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
523 default:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
524 /* make gcc happy */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
525 left = 0.0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
526 right = 0.0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
527 break;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
528 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
529
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
530 /* Bass compensation for the lower frequency cut of the HRTF. A
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
531 cross talk of the left and right channel is introduced to
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
532 match the directional characteristics of higher frequencies.
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
533 The bass will not have any real 3D perception, but that is
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
534 OK (note at 180 Hz, the wavelength is about 2 m, and any
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
535 spatial perception is impossible). */
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
536 left_b = conv(dblen, blen, s->ba_l, s->ba_ir, k);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
537 right_b = conv(dblen, blen, s->ba_r, s->ba_ir, k);
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
538 left += (1 - BASSCROSS) * left_b + BASSCROSS * right_b;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
539 right += (1 - BASSCROSS) * right_b + BASSCROSS * left_b;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
540 /* 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
541 if(data->nch >= 6) {
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
542 left += in[5] * M3_01DB;
0189ac5804b9 actually output 2 channel audio (instead of 6 channel with 4 empty channels)
reimar
parents: 15124
diff changeset
543 right += in[5] * M3_01DB;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
544 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
545
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
546 /* Amplitude renormalization. */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
547 left *= AMPLNORM;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
548 right *= AMPLNORM;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
549
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
550 switch (s->decode_mode) {
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
551 case HRTF_MIX_51:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
552 case HRTF_MIX_STEREO:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
553 /* "Cheating": linear stereo expansion to amplify the 3D
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
554 perception. Note: Too much will destroy the acoustic space
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
555 and may even result in headaches. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
556 diff = STEXPAND2 * (left - right);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
557 out[0] = (int16_t)(left + diff);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
558 out[1] = (int16_t)(right - diff);
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
559 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
560 case HRTF_MIX_MATRIX2CH:
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
561 /* Do attempt any stereo expansion with matrix encoded
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
562 sources. The L, R channels are already stereo expanded
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
563 by the steering, any further stereo expansion will sound
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
564 very unnatural. */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
565 out[0] = (int16_t)left;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
566 out[1] = (int16_t)right;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
567 break;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
568 }
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
569
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
570 /* Next sample... */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
571 in = &in[data->nch];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
572 out = &out[af->data->nch];
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
573 (s->cyc_pos)--;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
574 if(s->cyc_pos < 0)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
575 s->cyc_pos += dblen;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
576 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
577
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
578 /* Set output data */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
579 data->audio = af->data->audio;
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 22748
diff changeset
580 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
581 data->nch = 2;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
582
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
583 return data;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
584 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
585
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
586 static int allocate(af_hrtf_t *s)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
587 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
588 if ((s->lf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
589 if ((s->rf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
590 if ((s->lr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
591 if ((s->rr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
592 if ((s->cf = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
593 if ((s->cr = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
594 if ((s->ba_l = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
595 if ((s->ba_r = malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
596 if ((s->fwrbuf_l =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
597 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
598 if ((s->fwrbuf_r =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
599 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
600 if ((s->fwrbuf_lr =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
601 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
602 if ((s->fwrbuf_rr =
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
603 malloc(s->dlbuflen * sizeof(float))) == NULL) return -1;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
604 return 0;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
605 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
606
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
607 /* 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
608 static int af_open(af_instance_t* af)
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
609 {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
610 int i;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
611 af_hrtf_t *s;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
612 float fc;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
613
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
614 af->control = control;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
615 af->uninit = uninit;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
616 af->play = play;
24888
b2402b4f0afa libaf: change filter input/output ratio calculations
uau
parents: 22748
diff changeset
617 af->mul = 1;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
618 af->data = calloc(1, sizeof(af_data_t));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
619 af->setup = calloc(1, sizeof(af_hrtf_t));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
620 if((af->data == NULL) || (af->setup == NULL))
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
621 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
622
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
623 s = af->setup;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
624
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
625 s->dlbuflen = DELAYBUFLEN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
626 s->hrflen = HRTFFILTLEN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
627 s->basslen = BASSFILTLEN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
628
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
629 s->cyc_pos = s->dlbuflen - 1;
15082
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
630 /* With a full (two axis) steering matrix decoder, s->matrix_mode
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
631 should not be enabled lightly (it will also steer the Ls, Rs
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
632 channels). */
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
633 s->matrix_mode = 0;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
634 s->decode_mode = HRTF_MIX_51;
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
635
71570687c1a3 HRTF filter updates:
henry
parents: 14396
diff changeset
636 s->print_flag = 1;
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
637
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
638 if (allocate(s) != 0) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
639 af_msg(AF_MSG_ERROR, "[hrtf] Memory allocation error.\n");
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
640 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
641 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
642
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
643 for(i = 0; i < s->dlbuflen; i++)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
644 s->lf[i] = s->rf[i] = s->lr[i] = s->rr[i] = s->cf[i] =
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
645 s->cr[i] = 0;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
646
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
647 s->lr_fwr =
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
648 s->rr_fwr = 0;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
649
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
650 s->cf_ir = cf_filt + (s->cf_o = pulse_detect(cf_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
651 s->af_ir = af_filt + (s->af_o = pulse_detect(af_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
652 s->of_ir = of_filt + (s->of_o = pulse_detect(of_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
653 s->ar_ir = ar_filt + (s->ar_o = pulse_detect(ar_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
654 s->or_ir = or_filt + (s->or_o = pulse_detect(or_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
655 s->cr_ir = cr_filt + (s->cr_o = pulse_detect(cr_filt));
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
656
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
657 if((s->ba_ir = malloc(s->basslen * sizeof(float))) == NULL) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
658 af_msg(AF_MSG_ERROR, "[hrtf] Memory allocation error.\n");
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
659 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
660 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
661 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
662 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
663 -1) {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
664 af_msg(AF_MSG_ERROR, "[hrtf] Unable to design low-pass "
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
665 "filter.\n");
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
666 return AF_ERROR;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
667 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
668 for(i = 0; i < s->basslen; i++)
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
669 s->ba_ir[i] *= BASSGAIN;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
670
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
671 return AF_OK;
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
672 }
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
673
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
674 /* Description of this filter */
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
675 af_info_t af_info_hrtf = {
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
676 "HRTF Headphone",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
677 "hrtf",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
678 "ylai",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
679 "",
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
680 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
681 af_open
13996
be8f4abbe960 head related transfer function
henry
parents:
diff changeset
682 };