Mercurial > mplayer.hg
comparison libaf/af_bs2b.c @ 29093:9d220a44caae
Add libbs2b audio filter itself.
author | bircoph |
---|---|
date | Thu, 02 Apr 2009 19:01:57 +0000 |
parents | |
children | 3afe8b737f43 |
comparison
equal
deleted
inserted
replaced
29092:5dc97d7041d1 | 29093:9d220a44caae |
---|---|
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> | |
27 | |
28 #include "af.h" | |
29 #include "subopt-helper.h" | |
30 | |
31 /// Internal specific data of the filter | |
32 struct af_bs2b { | |
33 int level; ///< crossfeed level | |
34 int profile; ///< profile (easy or normal) | |
35 t_bs2bdp filter; ///< instance of a library filter | |
36 }; | |
37 | |
38 #define PLAY(name,type) \ | |
39 static af_data_t *play_##name(struct af_instance_s *af, af_data_t *data) \ | |
40 { \ | |
41 /* filter is called for all pairs of samples available in the buffer */ \ | |
42 bs2b_cross_feed_##name(((struct af_bs2b*)(af->setup))->filter, \ | |
43 (type*)(data->audio), data->len/data->bps/2); \ | |
44 \ | |
45 return data; \ | |
46 } | |
47 | |
48 PLAY(fbe,float) | |
49 PLAY(fle,float) | |
50 PLAY(s32be,int32_t) | |
51 PLAY(s32le,int32_t) | |
52 PLAY(s24be,bs2b_int24_t) | |
53 PLAY(s24le,bs2b_int24_t) | |
54 PLAY(s16be,int16_t) | |
55 PLAY(s16le,int16_t) | |
56 PLAY(s8,int8_t) | |
57 PLAY(u8,uint8_t) | |
58 | |
59 /// Sanity check for level value | |
60 static int test_level(void *par) | |
61 { | |
62 const int val = *(int*)par; | |
63 if (val >= 1 && val <= BS2B_CLEVELS) | |
64 return 1; | |
65 | |
66 mp_msg(MSGT_AFILTER,MSGL_ERR, "[bs2b] Level must be in range 1..%i, but " | |
67 "current value is %i.\n", BS2B_CLEVELS, val); | |
68 return 0; | |
69 } | |
70 | |
71 /// Sanity check for profile value | |
72 static int test_profile(void *par) | |
73 { | |
74 const int val = *(int*)par; | |
75 if (val >= 0 && val <= 1) | |
76 return 1; | |
77 | |
78 mp_msg(MSGT_AFILTER,MSGL_ERR, "[bs2b] Profile must be either 0 or 1, but " | |
79 "current value is %i.\n", val); | |
80 return 0; | |
81 } | |
82 | |
83 /// Initialization and runtime control | |
84 static int control(struct af_instance_s *af, int cmd, void *arg) | |
85 { | |
86 struct af_bs2b *s = af->setup; | |
87 | |
88 switch (cmd) { | |
89 case AF_CONTROL_REINIT: { | |
90 int format; | |
91 char buf[256]; | |
92 // Sanity check | |
93 if (!arg) return AF_ERROR; | |
94 | |
95 format = ((af_data_t*)arg)->format; | |
96 af->data->rate = ((af_data_t*)arg)->rate; | |
97 af->data->nch = 2; // bs2b is useful only for 2ch audio | |
98 af->data->bps = ((af_data_t*)arg)->bps; | |
99 af->data->format = format; | |
100 | |
101 /* check for formats supported by libbs2b | |
102 and assign corresponding handlers */ | |
103 switch (format) { | |
104 case AF_FORMAT_FLOAT_BE: | |
105 af->play = play_fbe; | |
106 break; | |
107 case AF_FORMAT_FLOAT_LE: | |
108 af->play = play_fle; | |
109 break; | |
110 case AF_FORMAT_S32_BE: | |
111 af->play = play_s32be; | |
112 break; | |
113 case AF_FORMAT_S32_LE: | |
114 af->play = play_s32le; | |
115 break; | |
116 case AF_FORMAT_S24_BE: | |
117 af->play = play_s24be; | |
118 break; | |
119 case AF_FORMAT_S24_LE: | |
120 af->play = play_s24le; | |
121 break; | |
122 case AF_FORMAT_S16_BE: | |
123 af->play = play_s16be; | |
124 break; | |
125 case AF_FORMAT_S16_LE: | |
126 af->play = play_s16le; | |
127 break; | |
128 case AF_FORMAT_S8: | |
129 af->play = play_s8; | |
130 break; | |
131 case AF_FORMAT_U8: | |
132 af->play = play_u8; | |
133 break; | |
134 default: | |
135 #ifdef WORDS_BIGENDIAN | |
136 af->play = play_fbe; | |
137 #else | |
138 af->play = play_fle; | |
139 #endif //WORDS_BIGENDIAN | |
140 af->data->format = AF_FORMAT_FLOAT_NE; | |
141 af->data->bps=4; | |
142 break; | |
143 } | |
144 | |
145 bs2b_set_srate(s->filter, (long)af->data->rate); | |
146 mp_msg(MSGT_AFILTER,MSGL_V, "[bs2b] using format %s\n", | |
147 af_fmt2str(af->data->format,buf,256)); | |
148 | |
149 return af_test_output(af,(af_data_t*)arg); | |
150 } | |
151 case AF_CONTROL_COMMAND_LINE: { | |
152 const opt_t subopts[] = { | |
153 {"level", OPT_ARG_INT, &s->level, test_level}, | |
154 {"profile", OPT_ARG_INT, &s->profile, test_profile}, | |
155 {NULL} | |
156 }; | |
157 if (subopt_parse(arg, subopts) != 0) { | |
158 mp_msg(MSGT_AFILTER,MSGL_ERR, "[bs2b] Invalid option specified.\n"); | |
159 return AF_ERROR; | |
160 } | |
161 | |
162 bs2b_set_level(s->filter, s->level + s->profile ? BS2B_CLEVELS : 0); | |
163 mp_msg(MSGT_AFILTER,MSGL_V, "[bs2b] using profile %i, level %i\n", | |
164 s->profile, s->level); | |
165 return AF_OK; | |
166 } | |
167 } | |
168 return AF_UNKNOWN; | |
169 } | |
170 | |
171 /// Deallocate memory and close library | |
172 static void uninit(struct af_instance_s *af) | |
173 { | |
174 struct af_bs2b *s = af->setup; | |
175 free(af->data); | |
176 if (s && s->filter) | |
177 bs2b_close(s->filter); | |
178 free(s); | |
179 } | |
180 | |
181 /// Allocate memory, set function pointers and init library | |
182 static int af_open(af_instance_t *af) | |
183 { | |
184 struct af_bs2b *s; | |
185 af->control = control; | |
186 af->uninit = uninit; | |
187 af->mul = 1; | |
188 if (!(af->data = calloc(1,sizeof(af_data_t)))) | |
189 return AF_ERROR; | |
190 if (!(af->setup = s = calloc(1,sizeof(struct af_bs2b)))) { | |
191 free(af->data); | |
192 return AF_ERROR; | |
193 } | |
194 | |
195 // NULL means failed initialization | |
196 if (!(s->filter = bs2b_open())) { | |
197 free(af->data); | |
198 free(af->setup); | |
199 return AF_ERROR; | |
200 } | |
201 // Set defaults the same as in the library: | |
202 s->level = 3; | |
203 s->profile = 1; | |
204 return AF_OK; | |
205 } | |
206 | |
207 /// Description of this filter | |
208 af_info_t af_info_bs2b = { | |
209 "Bauer stereophonic-to-binaural audio filter", | |
210 "bs2b", | |
211 "Andrew Savchenko", | |
212 "", | |
213 AF_FLAGS_REENTRANT, | |
214 af_open | |
215 }; |