Mercurial > mplayer.hg
annotate libaf/af_format.c @ 29938:eb6c70e2cbea
Very preliminary code to allow selecting the OpenGL backend at runtime.
Works in the currently supported cases for only Win32 and only X11,
the mixed case is not working yet though.
But applied anyway since the code is slightly less messy than the current one.
author | reimar |
---|---|
date | Tue, 08 Dec 2009 06:42:46 +0000 |
parents | f01023c524c3 |
children | 02b9c1a452e1 |
rev | line source |
---|---|
28229
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
1 /* |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
2 * This audio filter changes the format of a data block. Valid |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
3 * formats are: AFMT_U8, AFMT_S8, AFMT_S16_LE, AFMT_S16_BE |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
4 * AFMT_U16_LE, AFMT_U16_BE, AFMT_S32_LE and AFMT_S32_BE. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
5 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
6 * This file is part of MPlayer. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
7 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
8 * MPlayer is free software; you can redistribute it and/or modify |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
9 * it under the terms of the GNU General Public License as published by |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
10 * the Free Software Foundation; either version 2 of the License, or |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
11 * (at your option) any later version. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
12 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
13 * MPlayer is distributed in the hope that it will be useful, |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
16 * GNU General Public License for more details. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
17 * |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
18 * You should have received a copy of the GNU General Public License along |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
19 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
72d0b1444141
Replace informal license notices by standard license header
diego
parents:
26345
diff
changeset
|
21 */ |
7568 | 22 |
23 #include <stdio.h> | |
24 #include <stdlib.h> | |
25 #include <string.h> | |
26 #include <inttypes.h> | |
27 #include <limits.h> | |
28337
34b7297904ac
Drop HAVE_LRINTF check, lrintf is used without checking in other places.
diego
parents:
28333
diff
changeset
|
28 #include <math.h> |
7568 | 29 |
28333
0ec2ac66f064
Fix build: Add required header and adjust preprocessor check.
diego
parents:
28238
diff
changeset
|
30 #include "config.h" |
21353
a965ca17debc
reordering of #include to avoid clash with math.h and quicktime/*.h, patch by Crhis Roccati<roccati@pobox.com>
nplourde
parents:
16982
diff
changeset
|
31 #include "af.h" |
21507
fa99b3d31d13
Hack around libavutil/bswap.h compilation problems due to always_inline undefined.
reimar
parents:
21372
diff
changeset
|
32 #include "mpbswap.h" |
21353
a965ca17debc
reordering of #include to avoid clash with math.h and quicktime/*.h, patch by Crhis Roccati<roccati@pobox.com>
nplourde
parents:
16982
diff
changeset
|
33 #include "libvo/fastmemcpy.h" |
a965ca17debc
reordering of #include to avoid clash with math.h and quicktime/*.h, patch by Crhis Roccati<roccati@pobox.com>
nplourde
parents:
16982
diff
changeset
|
34 |
8167 | 35 /* Functions used by play to convert the input audio to the correct |
36 format */ | |
7568 | 37 |
24561 | 38 /* The below includes retrieves functions for converting to and from |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
39 ulaw and alaw */ |
28238
1bf9023840f9
Rename libaf/af_format_alaw.c --> libaf/af_format_alaw.h and
diego
parents:
28236
diff
changeset
|
40 #include "af_format_ulaw.h" |
1bf9023840f9
Rename libaf/af_format_alaw.c --> libaf/af_format_alaw.h and
diego
parents:
28236
diff
changeset
|
41 #include "af_format_alaw.h" |
7568 | 42 |
24561 | 43 // Switch endianness |
8167 | 44 static void endian(void* in, void* out, int len, int bps); |
24561 | 45 // From signed to unsigned and the other way |
16664 | 46 static void si2us(void* data, int len, int bps); |
8167 | 47 // Change the number of bits per sample |
48 static void change_bps(void* in, void* out, int len, int inbps, int outbps); | |
49 // From float to int signed | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
50 static void float2int(float* in, void* out, int len, int bps); |
8167 | 51 // From signed int to float |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
52 static void int2float(void* in, float* out, int len, int bps); |
7719
41e8d0916c60
Fix for audio filters on big endian cpus. It's working now on Solaris SPARC &
jkeil
parents:
7711
diff
changeset
|
53 |
14272 | 54 static af_data_t* play(struct af_instance_s* af, af_data_t* data); |
55 static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data); | |
56 static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data); | |
57 static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data); | |
58 | |
8607 | 59 // Helper functions to check sanity for input arguments |
60 | |
61 // Sanity check for bytes per sample | |
13989
dcb6b4a33aaa
declare check_format and check_bps static, they are used nowhere else.
reimar
parents:
12486
diff
changeset
|
62 static int check_bps(int bps) |
8607 | 63 { |
12478 | 64 if(bps != 4 && bps != 3 && bps != 2 && bps != 1){ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
65 mp_msg(MSGT_AFILTER, MSGL_ERR, "[format] The number of bytes per sample" |
12478 | 66 " must be 1, 2, 3 or 4. Current value is %i \n",bps); |
8607 | 67 return AF_ERROR; |
68 } | |
69 return AF_OK; | |
70 } | |
71 | |
72 // Check for unsupported formats | |
13989
dcb6b4a33aaa
declare check_format and check_bps static, they are used nowhere else.
reimar
parents:
12486
diff
changeset
|
73 static int check_format(int format) |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
74 { |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
75 char buf[256]; |
8607 | 76 switch(format & AF_FORMAT_SPECIAL_MASK){ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
77 case(AF_FORMAT_IMA_ADPCM): |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
78 case(AF_FORMAT_MPEG2): |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
79 case(AF_FORMAT_AC3): |
29049 | 80 mp_msg(MSGT_AFILTER, MSGL_ERR, "[format] Sample format %s not yet supported \n", |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
81 af_fmt2str(format,buf,256)); |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
82 return AF_ERROR; |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
83 } |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
84 return AF_OK; |
8607 | 85 } |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
86 |
7568 | 87 // Initialization and runtime control |
88 static int control(struct af_instance_s* af, int cmd, void* arg) | |
89 { | |
90 switch(cmd){ | |
8167 | 91 case AF_CONTROL_REINIT:{ |
92 char buf1[256]; | |
93 char buf2[256]; | |
14272 | 94 af_data_t *data = arg; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
95 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
96 // Make sure this filter isn't redundant |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
97 if(af->data->format == data->format && |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
98 af->data->bps == data->bps) |
7568 | 99 return AF_DETACH; |
8607 | 100 |
24521 | 101 // Check for errors in configuration |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
102 if((AF_OK != check_bps(data->bps)) || |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
103 (AF_OK != check_format(data->format)) || |
8607 | 104 (AF_OK != check_bps(af->data->bps)) || |
105 (AF_OK != check_format(af->data->format))) | |
8167 | 106 return AF_ERROR; |
107 | |
29049 | 108 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Changing sample format from %s to %s\n", |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
109 af_fmt2str(data->format,buf1,256), |
14399
1a882e2a419b
af_fmt2str fixes (remove trailing space, call with size of buffer, not size-1)
reimar
parents:
14335
diff
changeset
|
110 af_fmt2str(af->data->format,buf2,256)); |
7568 | 111 |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
112 af->data->rate = data->rate; |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
113 af->data->nch = data->nch; |
24888 | 114 af->mul = (double)af->data->bps / data->bps; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
115 |
14272 | 116 af->play = play; // set default |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
117 |
24561 | 118 // look whether only endianness differences are there |
14272 | 119 if ((af->data->format & ~AF_FORMAT_END_MASK) == |
120 (data->format & ~AF_FORMAT_END_MASK)) | |
121 { | |
29049 | 122 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Accelerated endianness conversion only\n"); |
14272 | 123 af->play = play_swapendian; |
124 } | |
125 if ((data->format == AF_FORMAT_FLOAT_NE) && | |
126 (af->data->format == AF_FORMAT_S16_NE)) | |
127 { | |
29049 | 128 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Accelerated %s to %s conversion\n", |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
129 af_fmt2str(data->format,buf1,256), |
14399
1a882e2a419b
af_fmt2str fixes (remove trailing space, call with size of buffer, not size-1)
reimar
parents:
14335
diff
changeset
|
130 af_fmt2str(af->data->format,buf2,256)); |
14272 | 131 af->play = play_float_s16; |
132 } | |
133 if ((data->format == AF_FORMAT_S16_NE) && | |
134 (af->data->format == AF_FORMAT_FLOAT_NE)) | |
135 { | |
29049 | 136 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Accelerated %s to %s conversion\n", |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
137 af_fmt2str(data->format,buf1,256), |
14399
1a882e2a419b
af_fmt2str fixes (remove trailing space, call with size of buffer, not size-1)
reimar
parents:
14335
diff
changeset
|
138 af_fmt2str(af->data->format,buf2,256)); |
14272 | 139 af->play = play_s16_float; |
140 } | |
7568 | 141 return AF_OK; |
8167 | 142 } |
7998
d48a06d07afb
Adding commandline options for filters and fixing stupid bug in cfg
anders
parents:
7719
diff
changeset
|
143 case AF_CONTROL_COMMAND_LINE:{ |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
144 int format = af_str2fmt_short(arg); |
15311 | 145 if (format == -1) { |
29049 | 146 mp_msg(MSGT_AFILTER, MSGL_ERR, "[format] %s is not a valid format\n", (char *)arg); |
15311 | 147 return AF_ERROR; |
148 } | |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
149 if(AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET,&format)) |
8607 | 150 return AF_ERROR; |
151 return AF_OK; | |
8167 | 152 } |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
153 case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET:{ |
24561 | 154 // Check for errors in configuration |
8607 | 155 if(AF_OK != check_format(*(int*)arg)) |
156 return AF_ERROR; | |
157 | |
158 af->data->format = *(int*)arg; | |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
159 af->data->bps = af_fmt2bits(af->data->format)/8; |
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
160 |
7568 | 161 return AF_OK; |
162 } | |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
163 } |
7568 | 164 return AF_UNKNOWN; |
165 } | |
166 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
167 // Deallocate memory |
7568 | 168 static void uninit(struct af_instance_s* af) |
169 { | |
22179 | 170 if (af->data) |
171 free(af->data->audio); | |
172 free(af->data); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
173 af->setup = 0; |
7568 | 174 } |
175 | |
14272 | 176 static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data) |
177 { | |
178 af_data_t* l = af->data; // Local data | |
179 af_data_t* c = data; // Current working data | |
24561 | 180 int len = c->len/c->bps; // Length in samples of current audio block |
14272 | 181 |
182 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
183 return NULL; | |
184 | |
185 endian(c->audio,l->audio,len,c->bps); | |
186 | |
187 c->audio = l->audio; | |
188 c->format = l->format; | |
189 | |
190 return c; | |
191 } | |
192 | |
193 static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data) | |
194 { | |
195 af_data_t* l = af->data; // Local data | |
196 af_data_t* c = data; // Current working data | |
24561 | 197 int len = c->len/4; // Length in samples of current audio block |
14272 | 198 |
199 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
200 return NULL; | |
201 | |
202 float2int(c->audio, l->audio, len, 2); | |
203 | |
204 c->audio = l->audio; | |
205 c->len = len*2; | |
206 c->bps = 2; | |
207 c->format = l->format; | |
208 | |
209 return c; | |
210 } | |
211 | |
212 static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data) | |
213 { | |
214 af_data_t* l = af->data; // Local data | |
215 af_data_t* c = data; // Current working data | |
24561 | 216 int len = c->len/2; // Length in samples of current audio block |
14272 | 217 |
218 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
219 return NULL; | |
220 | |
221 int2float(c->audio, l->audio, len, 2); | |
222 | |
223 c->audio = l->audio; | |
224 c->len = len*4; | |
225 c->bps = 4; | |
226 c->format = l->format; | |
227 | |
228 return c; | |
229 } | |
230 | |
7568 | 231 // Filter data through filter |
232 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
233 { | |
8167 | 234 af_data_t* l = af->data; // Local data |
235 af_data_t* c = data; // Current working data | |
24561 | 236 int len = c->len/c->bps; // Length in samples of current audio block |
7568 | 237 |
238 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
239 return NULL; | |
240 | |
8167 | 241 // Change to cpu native endian format |
242 if((c->format&AF_FORMAT_END_MASK)!=AF_FORMAT_NE) | |
243 endian(c->audio,c->audio,len,c->bps); | |
7719
41e8d0916c60
Fix for audio filters on big endian cpus. It's working now on Solaris SPARC &
jkeil
parents:
7711
diff
changeset
|
244 |
8167 | 245 // Conversion table |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
246 if((c->format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_MU_LAW) { |
8167 | 247 from_ulaw(c->audio, l->audio, len, l->bps, l->format&AF_FORMAT_POINT_MASK); |
248 if(AF_FORMAT_A_LAW == (l->format&AF_FORMAT_SPECIAL_MASK)) | |
249 to_ulaw(l->audio, l->audio, len, 1, AF_FORMAT_SI); | |
250 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) | |
16664 | 251 si2us(l->audio,len,l->bps); |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
252 } else if((c->format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_A_LAW) { |
8167 | 253 from_alaw(c->audio, l->audio, len, l->bps, l->format&AF_FORMAT_POINT_MASK); |
254 if(AF_FORMAT_A_LAW == (l->format&AF_FORMAT_SPECIAL_MASK)) | |
255 to_alaw(l->audio, l->audio, len, 1, AF_FORMAT_SI); | |
256 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) | |
16664 | 257 si2us(l->audio,len,l->bps); |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
258 } else if((c->format & AF_FORMAT_POINT_MASK) == AF_FORMAT_F) { |
8167 | 259 switch(l->format&AF_FORMAT_SPECIAL_MASK){ |
260 case(AF_FORMAT_MU_LAW): | |
261 to_ulaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
262 break; | |
263 case(AF_FORMAT_A_LAW): | |
264 to_alaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
7568 | 265 break; |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
266 default: |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
267 float2int(c->audio, l->audio, len, l->bps); |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
268 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) |
16664 | 269 si2us(l->audio,len,l->bps); |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
270 break; |
8167 | 271 } |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
272 } else { |
8167 | 273 // Input must be int |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
274 |
8167 | 275 // Change signed/unsigned |
276 if((c->format&AF_FORMAT_SIGN_MASK) != (l->format&AF_FORMAT_SIGN_MASK)){ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
277 si2us(c->audio,len,c->bps); |
8167 | 278 } |
279 // Convert to special formats | |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
280 switch(l->format&(AF_FORMAT_SPECIAL_MASK|AF_FORMAT_POINT_MASK)){ |
8167 | 281 case(AF_FORMAT_MU_LAW): |
282 to_ulaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
283 break; | |
284 case(AF_FORMAT_A_LAW): | |
285 to_alaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
286 break; | |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
287 case(AF_FORMAT_F): |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
288 int2float(c->audio, l->audio, len, c->bps); |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
289 break; |
8167 | 290 default: |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
291 // Change the number of bits |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
292 if(c->bps != l->bps) |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
293 change_bps(c->audio,l->audio,len,c->bps,l->bps); |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
294 else |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
22748
diff
changeset
|
295 fast_memcpy(l->audio,c->audio,len*c->bps); |
7568 | 296 break; |
297 } | |
298 } | |
7719
41e8d0916c60
Fix for audio filters on big endian cpus. It's working now on Solaris SPARC &
jkeil
parents:
7711
diff
changeset
|
299 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
300 // Switch from cpu native endian to the correct endianness |
8167 | 301 if((l->format&AF_FORMAT_END_MASK)!=AF_FORMAT_NE) |
302 endian(l->audio,l->audio,len,l->bps); | |
7568 | 303 |
304 // Set output data | |
305 c->audio = l->audio; | |
8167 | 306 c->len = len*l->bps; |
7568 | 307 c->bps = l->bps; |
308 c->format = l->format; | |
309 return c; | |
310 } | |
311 | |
312 // Allocate memory and set function pointers | |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22179
diff
changeset
|
313 static int af_open(af_instance_t* af){ |
7568 | 314 af->control=control; |
315 af->uninit=uninit; | |
316 af->play=play; | |
24888 | 317 af->mul=1; |
7568 | 318 af->data=calloc(1,sizeof(af_data_t)); |
319 if(af->data == NULL) | |
320 return AF_ERROR; | |
321 return AF_OK; | |
322 } | |
323 | |
324 // Description of this filter | |
325 af_info_t af_info_format = { | |
326 "Sample format conversion", | |
327 "format", | |
328 "Anders", | |
329 "", | |
7615 | 330 AF_FLAGS_REENTRANT, |
22746
fd6f824ef894
Rename open to af_open so as not to conflict with a previous header definition.
diego
parents:
22179
diff
changeset
|
331 af_open |
7568 | 332 }; |
8167 | 333 |
12478 | 334 static inline uint32_t load24bit(void* data, int pos) { |
29401
f01023c524c3
Replace WORDS_BIGENDIAN by HAVE_BIGENDIAN in all internal code.
diego
parents:
29263
diff
changeset
|
335 #if HAVE_BIGENDIAN |
12478 | 336 return (((uint32_t)((uint8_t*)data)[3*pos])<<24) | |
337 (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | | |
338 (((uint32_t)((uint8_t*)data)[3*pos+2])<<8); | |
339 #else | |
340 return (((uint32_t)((uint8_t*)data)[3*pos])<<8) | | |
341 (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | | |
342 (((uint32_t)((uint8_t*)data)[3*pos+2])<<24); | |
343 #endif | |
344 } | |
345 | |
346 static inline void store24bit(void* data, int pos, uint32_t expanded_value) { | |
29401
f01023c524c3
Replace WORDS_BIGENDIAN by HAVE_BIGENDIAN in all internal code.
diego
parents:
29263
diff
changeset
|
347 #if HAVE_BIGENDIAN |
12478 | 348 ((uint8_t*)data)[3*pos]=expanded_value>>24; |
349 ((uint8_t*)data)[3*pos+1]=expanded_value>>16; | |
350 ((uint8_t*)data)[3*pos+2]=expanded_value>>8; | |
351 #else | |
352 ((uint8_t*)data)[3*pos]=expanded_value>>8; | |
353 ((uint8_t*)data)[3*pos+1]=expanded_value>>16; | |
354 ((uint8_t*)data)[3*pos+2]=expanded_value>>24; | |
355 #endif | |
356 } | |
357 | |
8167 | 358 // Function implementations used by play |
359 static void endian(void* in, void* out, int len, int bps) | |
360 { | |
361 register int i; | |
362 switch(bps){ | |
363 case(2):{ | |
364 for(i=0;i<len;i++){ | |
12486 | 365 ((uint16_t*)out)[i]=bswap_16(((uint16_t*)in)[i]); |
8167 | 366 } |
367 break; | |
368 } | |
12478 | 369 case(3):{ |
370 register uint8_t s; | |
371 for(i=0;i<len;i++){ | |
372 s=((uint8_t*)in)[3*i]; | |
373 ((uint8_t*)out)[3*i]=((uint8_t*)in)[3*i+2]; | |
12481
dbbc25ea6403
fix endian conversion for (curently unused) case where in buffer != out buffer
reimar
parents:
12478
diff
changeset
|
374 if (in != out) |
dbbc25ea6403
fix endian conversion for (curently unused) case where in buffer != out buffer
reimar
parents:
12478
diff
changeset
|
375 ((uint8_t*)out)[3*i+1]=((uint8_t*)in)[3*i+1]; |
12478 | 376 ((uint8_t*)out)[3*i+2]=s; |
377 } | |
378 break; | |
379 } | |
8167 | 380 case(4):{ |
381 for(i=0;i<len;i++){ | |
12486 | 382 ((uint32_t*)out)[i]=bswap_32(((uint32_t*)in)[i]); |
8167 | 383 } |
384 break; | |
385 } | |
386 } | |
387 } | |
388 | |
16664 | 389 static void si2us(void* data, int len, int bps) |
8167 | 390 { |
16664 | 391 register long i = -(len * bps); |
392 register uint8_t *p = &((uint8_t *)data)[len * bps]; | |
393 #if AF_FORMAT_NE == AF_FORMAT_LE | |
394 p += bps - 1; | |
395 #endif | |
396 if (len <= 0) return; | |
397 do { | |
398 p[i] ^= 0x80; | |
399 } while (i += bps); | |
8167 | 400 } |
401 | |
402 static void change_bps(void* in, void* out, int len, int inbps, int outbps) | |
403 { | |
404 register int i; | |
405 switch(inbps){ | |
406 case(1): | |
407 switch(outbps){ | |
408 case(2): | |
409 for(i=0;i<len;i++) | |
410 ((uint16_t*)out)[i]=((uint16_t)((uint8_t*)in)[i])<<8; | |
411 break; | |
12478 | 412 case(3): |
413 for(i=0;i<len;i++) | |
414 store24bit(out, i, ((uint32_t)((uint8_t*)in)[i])<<24); | |
415 break; | |
8167 | 416 case(4): |
417 for(i=0;i<len;i++) | |
418 ((uint32_t*)out)[i]=((uint32_t)((uint8_t*)in)[i])<<24; | |
419 break; | |
420 } | |
421 break; | |
422 case(2): | |
423 switch(outbps){ | |
424 case(1): | |
425 for(i=0;i<len;i++) | |
426 ((uint8_t*)out)[i]=(uint8_t)((((uint16_t*)in)[i])>>8); | |
427 break; | |
12478 | 428 case(3): |
429 for(i=0;i<len;i++) | |
430 store24bit(out, i, ((uint32_t)((uint16_t*)in)[i])<<16); | |
431 break; | |
8167 | 432 case(4): |
433 for(i=0;i<len;i++) | |
434 ((uint32_t*)out)[i]=((uint32_t)((uint16_t*)in)[i])<<16; | |
435 break; | |
436 } | |
437 break; | |
12478 | 438 case(3): |
439 switch(outbps){ | |
440 case(1): | |
441 for(i=0;i<len;i++) | |
442 ((uint8_t*)out)[i]=(uint8_t)(load24bit(in, i)>>24); | |
443 break; | |
444 case(2): | |
445 for(i=0;i<len;i++) | |
446 ((uint16_t*)out)[i]=(uint16_t)(load24bit(in, i)>>16); | |
447 break; | |
448 case(4): | |
449 for(i=0;i<len;i++) | |
450 ((uint32_t*)out)[i]=(uint32_t)load24bit(in, i); | |
451 break; | |
452 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
453 break; |
8167 | 454 case(4): |
455 switch(outbps){ | |
456 case(1): | |
457 for(i=0;i<len;i++) | |
458 ((uint8_t*)out)[i]=(uint8_t)((((uint32_t*)in)[i])>>24); | |
459 break; | |
460 case(2): | |
461 for(i=0;i<len;i++) | |
462 ((uint16_t*)out)[i]=(uint16_t)((((uint32_t*)in)[i])>>16); | |
463 break; | |
12478 | 464 case(3): |
465 for(i=0;i<len;i++) | |
466 store24bit(out, i, ((uint32_t*)in)[i]); | |
467 break; | |
8167 | 468 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
469 break; |
8167 | 470 } |
471 } | |
472 | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
473 static void float2int(float* in, void* out, int len, int bps) |
8167 | 474 { |
475 register int i; | |
476 switch(bps){ | |
477 case(1): | |
478 for(i=0;i<len;i++) | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
479 ((int8_t*)out)[i] = lrintf(127.0 * in[i]); |
8167 | 480 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
481 case(2): |
8167 | 482 for(i=0;i<len;i++) |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
483 ((int16_t*)out)[i] = lrintf(32767.0 * in[i]); |
8167 | 484 break; |
12478 | 485 case(3): |
486 for(i=0;i<len;i++) | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
487 store24bit(out, i, lrintf(2147483647.0 * in[i])); |
12478 | 488 break; |
8167 | 489 case(4): |
490 for(i=0;i<len;i++) | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
491 ((int32_t*)out)[i] = lrintf(2147483647.0 * in[i]); |
8167 | 492 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
493 } |
8167 | 494 } |
495 | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
496 static void int2float(void* in, float* out, int len, int bps) |
8167 | 497 { |
498 register int i; | |
499 switch(bps){ | |
500 case(1): | |
501 for(i=0;i<len;i++) | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
502 out[i]=(1.0/128.0)*((int8_t*)in)[i]; |
8167 | 503 break; |
504 case(2): | |
505 for(i=0;i<len;i++) | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
506 out[i]=(1.0/32768.0)*((int16_t*)in)[i]; |
8167 | 507 break; |
12478 | 508 case(3): |
509 for(i=0;i<len;i++) | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
510 out[i]=(1.0/2147483648.0)*((int32_t)load24bit(in, i)); |
12478 | 511 break; |
8167 | 512 case(4): |
513 for(i=0;i<len;i++) | |
14791
df515839c8a9
100l for me, lrintf is better. now fixed so it should be prototyped, and should work even if there is no prototype
rfelker
parents:
14758
diff
changeset
|
514 out[i]=(1.0/2147483648.0)*((int32_t*)in)[i]; |
8167 | 515 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
516 } |
8167 | 517 } |