annotate libaf/af_hrtf.c @ 19382:7c6c205b88b6

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