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