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