2 * The Bauer stereophonic-to-binaural DSP using bs2b library:
3 * http://bs2b.sourceforge.net/
5 * Copyright (c) 2009 Andrew Savchenko
7 * This file is part of MPlayer.
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.
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.
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.
30 #include "subopt-helper.h"
32 /// Internal specific data of the filter
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)
37 t_bs2bdp filter
; ///< instance of a library filter
40 #define PLAY(name, type) \
41 static af_data_t *play_##name(struct af_instance_s *af, af_data_t *data) \
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); \
57 PLAY(s24be
, bs2b_int24_t
)
58 PLAY(u24be
, bs2b_uint24_t
)
59 PLAY(s24le
, bs2b_int24_t
)
60 PLAY(u24le
, bs2b_uint24_t
)
68 /// Sanity check for fcut value
69 static int test_fcut(void *par
)
71 const int val
= *(int*)par
;
72 if (val
>= BS2B_MINFCUT
&& val
<= BS2B_MAXFCUT
)
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
);
81 /// Sanity check for feed value
82 static int test_feed(void *par
)
84 const int val
= *(int*)par
;
85 if (val
>= BS2B_MINFEED
&& val
<= BS2B_MAXFEED
)
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
);
94 /// Initialization and runtime control
95 static int control(struct af_instance_s
*af
, int cmd
, void *arg
)
97 struct af_bs2b
*s
= af
->setup
;
100 case AF_CONTROL_REINIT
: {
104 if (!arg
) return AF_ERROR
;
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
;
112 /* check for formats supported by libbs2b
113 and assign corresponding handlers */
115 case AF_FORMAT_FLOAT_BE
:
118 case AF_FORMAT_FLOAT_LE
:
121 case AF_FORMAT_S32_BE
:
122 af
->play
= play_s32be
;
124 case AF_FORMAT_U32_BE
:
125 af
->play
= play_u32be
;
127 case AF_FORMAT_S32_LE
:
128 af
->play
= play_s32le
;
130 case AF_FORMAT_U32_LE
:
131 af
->play
= play_u32le
;
133 case AF_FORMAT_S24_BE
:
134 af
->play
= play_s24be
;
136 case AF_FORMAT_U24_BE
:
137 af
->play
= play_u24be
;
139 case AF_FORMAT_S24_LE
:
140 af
->play
= play_s24le
;
142 case AF_FORMAT_U24_LE
:
143 af
->play
= play_u24le
;
145 case AF_FORMAT_S16_BE
:
146 af
->play
= play_s16be
;
148 case AF_FORMAT_U16_BE
:
149 af
->play
= play_u16be
;
151 case AF_FORMAT_S16_LE
:
152 af
->play
= play_s16le
;
154 case AF_FORMAT_U16_LE
:
155 af
->play
= play_u16le
;
165 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
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
);
178 bs2b_set_srate(s
->filter
, (long)af
->data
->rate
);
179 mp_msg(MSGT_AFILTER
, MSGL_V
, "[bs2b] using format %s\n",
180 af_fmt2str(af
->data
->format
,buf
,256));
182 return af_test_output(af
,(af_data_t
*)arg
);
184 case AF_CONTROL_COMMAND_LINE
: {
185 const opt_t subopts
[] = {
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
},
191 if (subopt_parse(arg
, subopts
) != 0) {
192 mp_msg(MSGT_AFILTER
, MSGL_ERR
, "[bs2b] Invalid option specified.\n");
196 // parse profile if specified
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
);
205 mp_msg(MSGT_AFILTER
, MSGL_ERR
,
206 "[bs2b] Invalid profile specified: %s.\n"
207 "[bs2b] Available profiles are: default, cmoy, jmeier.\n",
213 // set fcut and feed only if specified, otherwise defaults will be used
215 bs2b_set_level_fcut(s
->filter
, s
->fcut
);
217 bs2b_set_level_feed(s
->filter
, s
->feed
);
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
));
229 /// Deallocate memory and close library
230 static void uninit(struct af_instance_s
*af
)
232 struct af_bs2b
*s
= af
->setup
;
235 bs2b_close(s
->filter
);
239 /// Allocate memory, set function pointers and init library
240 static int af_open(af_instance_t
*af
)
243 af
->control
= control
;
246 if (!(af
->data
= calloc(1, sizeof(af_data_t
))))
248 if (!(af
->setup
= s
= calloc(1, sizeof(struct af_bs2b
)))) {
253 // NULL means failed initialization
254 if (!(s
->filter
= bs2b_open())) {
259 // Set zero defaults indicating no option was specified.
266 /// Description of this filter
267 af_info_t af_info_bs2b
= {
268 "Bauer stereophonic-to-binaural audio filter",