annotate libaf/af_hrtf.c @ 25661:293aeec83153

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