Mercurial > mplayer.hg
annotate libaf/af_bs2b.c @ 34045:4831a5fa1d78
configure: Set CONFIG_PIC to 1 if PIC is enabled.
author | diego |
---|---|
date | Mon, 26 Sep 2011 10:59:39 +0000 |
parents | 80865c30ee80 |
children | a93891202051 |
rev | line source |
---|---|
29093 | 1 /* |
2 * The Bauer stereophonic-to-binaural DSP using bs2b library: | |
3 * http://bs2b.sourceforge.net/ | |
4 * | |
5 * Copyright (c) 2009 Andrew Savchenko | |
6 * | |
7 * This file is part of MPlayer. | |
8 * | |
9 * MPlayer is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * MPlayer is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License along | |
20 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
22 */ | |
23 | |
24 #include <bs2b.h> | |
25 #include <inttypes.h> | |
26 #include <stdlib.h> | |
29202 | 27 #include <string.h> |
29093 | 28 |
29 #include "af.h" | |
30 #include "subopt-helper.h" | |
31 | |
32 /// Internal specific data of the filter | |
33 struct af_bs2b { | |
29202 | 34 int fcut; ///< cut frequency in Hz |
35 int feed; ///< feed level for low frequencies in 0.1*dB | |
36 char *profile; ///< profile (available crossfeed presets) | |
29093 | 37 t_bs2bdp filter; ///< instance of a library filter |
38 }; | |
39 | |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
40 #define PLAY(name, type) \ |
29093 | 41 static af_data_t *play_##name(struct af_instance_s *af, af_data_t *data) \ |
42 { \ | |
43 /* filter is called for all pairs of samples available in the buffer */ \ | |
44 bs2b_cross_feed_##name(((struct af_bs2b*)(af->setup))->filter, \ | |
45 (type*)(data->audio), data->len/data->bps/2); \ | |
46 \ | |
47 return data; \ | |
48 } | |
49 | |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
50 PLAY(f, float) |
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
51 PLAY(fbe, float) |
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
52 PLAY(fle, float) |
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
53 PLAY(s32be, int32_t) |
29202 | 54 PLAY(u32be, uint32_t) |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
55 PLAY(s32le, int32_t) |
29202 | 56 PLAY(u32le, uint32_t) |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
57 PLAY(s24be, bs2b_int24_t) |
29202 | 58 PLAY(u24be, bs2b_uint24_t) |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
59 PLAY(s24le, bs2b_int24_t) |
29202 | 60 PLAY(u24le, bs2b_uint24_t) |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
61 PLAY(s16be, int16_t) |
29202 | 62 PLAY(u16be, uint16_t) |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
63 PLAY(s16le, int16_t) |
29202 | 64 PLAY(u16le, uint16_t) |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
65 PLAY(s8, int8_t) |
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
66 PLAY(u8, uint8_t) |
29093 | 67 |
29202 | 68 /// Sanity check for fcut value |
69 static int test_fcut(void *par) | |
29093 | 70 { |
71 const int val = *(int*)par; | |
29202 | 72 if (val >= BS2B_MINFCUT && val <= BS2B_MAXFCUT) |
29093 | 73 return 1; |
74 | |
29202 | 75 mp_msg(MSGT_AFILTER, MSGL_ERR, |
76 "[bs2b] Cut frequency must be in range [%d..%d], but current value is %d.\n", | |
77 BS2B_MINFCUT, BS2B_MAXFCUT, val); | |
29093 | 78 return 0; |
79 } | |
80 | |
29202 | 81 /// Sanity check for feed value |
82 static int test_feed(void *par) | |
29093 | 83 { |
84 const int val = *(int*)par; | |
29202 | 85 if (val >= BS2B_MINFEED && val <= BS2B_MAXFEED) |
29093 | 86 return 1; |
87 | |
29202 | 88 mp_msg(MSGT_AFILTER, MSGL_ERR, |
89 "[bs2b] Feed level must be in range [%d..%d], but current value is %d.\n", | |
90 BS2B_MINFEED, BS2B_MAXFEED, val); | |
29093 | 91 return 0; |
92 } | |
93 | |
94 /// Initialization and runtime control | |
95 static int control(struct af_instance_s *af, int cmd, void *arg) | |
96 { | |
97 struct af_bs2b *s = af->setup; | |
98 | |
99 switch (cmd) { | |
100 case AF_CONTROL_REINIT: { | |
101 int format; | |
102 char buf[256]; | |
103 // Sanity check | |
104 if (!arg) return AF_ERROR; | |
105 | |
106 format = ((af_data_t*)arg)->format; | |
107 af->data->rate = ((af_data_t*)arg)->rate; | |
108 af->data->nch = 2; // bs2b is useful only for 2ch audio | |
109 af->data->bps = ((af_data_t*)arg)->bps; | |
110 af->data->format = format; | |
111 | |
112 /* check for formats supported by libbs2b | |
113 and assign corresponding handlers */ | |
114 switch (format) { | |
115 case AF_FORMAT_FLOAT_BE: | |
116 af->play = play_fbe; | |
117 break; | |
118 case AF_FORMAT_FLOAT_LE: | |
119 af->play = play_fle; | |
120 break; | |
121 case AF_FORMAT_S32_BE: | |
122 af->play = play_s32be; | |
123 break; | |
29202 | 124 case AF_FORMAT_U32_BE: |
125 af->play = play_u32be; | |
126 break; | |
29093 | 127 case AF_FORMAT_S32_LE: |
128 af->play = play_s32le; | |
129 break; | |
29202 | 130 case AF_FORMAT_U32_LE: |
131 af->play = play_u32le; | |
132 break; | |
29093 | 133 case AF_FORMAT_S24_BE: |
134 af->play = play_s24be; | |
135 break; | |
29202 | 136 case AF_FORMAT_U24_BE: |
137 af->play = play_u24be; | |
138 break; | |
29093 | 139 case AF_FORMAT_S24_LE: |
140 af->play = play_s24le; | |
141 break; | |
29202 | 142 case AF_FORMAT_U24_LE: |
143 af->play = play_u24le; | |
144 break; | |
29093 | 145 case AF_FORMAT_S16_BE: |
146 af->play = play_s16be; | |
147 break; | |
29202 | 148 case AF_FORMAT_U16_BE: |
149 af->play = play_u16be; | |
150 break; | |
29093 | 151 case AF_FORMAT_S16_LE: |
152 af->play = play_s16le; | |
153 break; | |
29202 | 154 case AF_FORMAT_U16_LE: |
155 af->play = play_u16le; | |
156 break; | |
29093 | 157 case AF_FORMAT_S8: |
158 af->play = play_s8; | |
159 break; | |
160 case AF_FORMAT_U8: | |
161 af->play = play_u8; | |
162 break; | |
163 default: | |
29095
3afe8b737f43
Use native endian float filter provided by libbs2b instead of
bircoph
parents:
29093
diff
changeset
|
164 af->play = play_f; |
29093 | 165 af->data->format = AF_FORMAT_FLOAT_NE; |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
166 af->data->bps = 4; |
29093 | 167 break; |
168 } | |
169 | |
29202 | 170 // bs2b have srate limits, try to resample if needed |
171 if (af->data->rate > BS2B_MAXSRATE || af->data->rate < BS2B_MINSRATE) { | |
172 af->data->rate = BS2B_DEFAULT_SRATE; | |
173 mp_msg(MSGT_AFILTER, MSGL_WARN, | |
174 "[bs2b] Requested sample rate %d Hz is out of bounds [%d..%d] Hz.\n" | |
175 "[bs2b] Trying to resample to %d Hz.\n", | |
176 af->data->rate, BS2B_MINSRATE, BS2B_MAXSRATE, BS2B_DEFAULT_SRATE); | |
177 } | |
29093 | 178 bs2b_set_srate(s->filter, (long)af->data->rate); |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
179 mp_msg(MSGT_AFILTER, MSGL_V, "[bs2b] using format %s\n", |
29093 | 180 af_fmt2str(af->data->format,buf,256)); |
181 | |
182 return af_test_output(af,(af_data_t*)arg); | |
183 } | |
184 case AF_CONTROL_COMMAND_LINE: { | |
185 const opt_t subopts[] = { | |
29202 | 186 {"fcut", OPT_ARG_INT, &s->fcut, test_fcut}, |
187 {"feed", OPT_ARG_INT, &s->feed, test_feed}, | |
188 {"profile", OPT_ARG_MSTRZ, &s->profile, NULL}, | |
29093 | 189 {NULL} |
190 }; | |
191 if (subopt_parse(arg, subopts) != 0) { | |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
192 mp_msg(MSGT_AFILTER, MSGL_ERR, "[bs2b] Invalid option specified.\n"); |
29202 | 193 free(s->profile); |
29093 | 194 return AF_ERROR; |
195 } | |
29202 | 196 // parse profile if specified |
197 if (s->profile) { | |
198 if (!strcmp(s->profile, "default")) | |
199 bs2b_set_level(s->filter, BS2B_DEFAULT_CLEVEL); | |
200 else if (!strcmp(s->profile, "cmoy")) | |
201 bs2b_set_level(s->filter, BS2B_CMOY_CLEVEL); | |
202 else if (!strcmp(s->profile, "jmeier")) | |
203 bs2b_set_level(s->filter, BS2B_JMEIER_CLEVEL); | |
204 else { | |
205 mp_msg(MSGT_AFILTER, MSGL_ERR, | |
206 "[bs2b] Invalid profile specified: %s.\n" | |
207 "[bs2b] Available profiles are: default, cmoy, jmeier.\n", | |
208 s->profile); | |
209 free(s->profile); | |
210 return AF_ERROR; | |
211 } | |
212 } | |
213 // set fcut and feed only if specified, otherwise defaults will be used | |
214 if (s->fcut) | |
215 bs2b_set_level_fcut(s->filter, s->fcut); | |
216 if (s->feed) | |
217 bs2b_set_level_feed(s->filter, s->feed); | |
29093 | 218 |
29202 | 219 mp_msg(MSGT_AFILTER, MSGL_V, |
220 "[bs2b] using cut frequency %d, LF feed level %d\n", | |
221 bs2b_get_level_fcut(s->filter), bs2b_get_level_feed(s->filter)); | |
222 free(s->profile); | |
29093 | 223 return AF_OK; |
224 } | |
225 } | |
226 return AF_UNKNOWN; | |
227 } | |
228 | |
229 /// Deallocate memory and close library | |
230 static void uninit(struct af_instance_s *af) | |
231 { | |
232 struct af_bs2b *s = af->setup; | |
233 free(af->data); | |
234 if (s && s->filter) | |
235 bs2b_close(s->filter); | |
236 free(s); | |
237 } | |
238 | |
239 /// Allocate memory, set function pointers and init library | |
240 static int af_open(af_instance_t *af) | |
241 { | |
242 struct af_bs2b *s; | |
243 af->control = control; | |
244 af->uninit = uninit; | |
245 af->mul = 1; | |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
246 if (!(af->data = calloc(1, sizeof(af_data_t)))) |
29093 | 247 return AF_ERROR; |
29203
80865c30ee80
Cosmetics for r29244 to follow K&R style closely.
bircoph
parents:
29202
diff
changeset
|
248 if (!(af->setup = s = calloc(1, sizeof(struct af_bs2b)))) { |
29093 | 249 free(af->data); |
250 return AF_ERROR; | |
251 } | |
252 | |
253 // NULL means failed initialization | |
254 if (!(s->filter = bs2b_open())) { | |
255 free(af->data); | |
256 free(af->setup); | |
257 return AF_ERROR; | |
258 } | |
29202 | 259 // Set zero defaults indicating no option was specified. |
260 s->profile = NULL; | |
261 s->fcut = 0; | |
262 s->feed = 0; | |
29093 | 263 return AF_OK; |
264 } | |
265 | |
266 /// Description of this filter | |
267 af_info_t af_info_bs2b = { | |
268 "Bauer stereophonic-to-binaural audio filter", | |
269 "bs2b", | |
270 "Andrew Savchenko", | |
271 "", | |
272 AF_FLAGS_REENTRANT, | |
273 af_open | |
274 }; |