Mercurial > mplayer.hg
annotate libaf/af_bs2b.c @ 35553:29f2de5e63d6
Don't unconditionally reset playlist to first item after playback.
Only do so if the current item isn't the first one in the list.
This will continue displaying the file's media information.
author | ib |
---|---|
date | Mon, 10 Dec 2012 02:08:43 +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 }; |