Mercurial > mplayer.hg
annotate libaf/af_format.c @ 27319:09cf111f68b8
Revert to previous dependency checking behavior.
Take included header files into account when generating dependency files.
This has problems when header files are removed or renamed, but does not
silently miscompile files.
author | diego |
---|---|
date | Sat, 26 Jul 2008 18:36:48 +0000 |
parents | f0a89eb49958 |
children | 72d0b1444141 |
rev | line source |
---|---|
7568 | 1 /* This audio output filter changes the format of a data block. Valid |
2 formats are: AFMT_U8, AFMT_S8, AFMT_S16_LE, AFMT_S16_BE | |
3 AFMT_U16_LE, AFMT_U16_BE, AFMT_S32_LE and AFMT_S32_BE. | |
4 */ | |
5 | |
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
|
6 // Must be defined before any libc headers are included! |
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
|
7 #define _ISOC9X_SOURCE |
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
|
8 |
7568 | 9 #include <stdio.h> |
10 #include <stdlib.h> | |
11 #include <string.h> | |
12 #include <inttypes.h> | |
13 #include <limits.h> | |
14 | |
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
|
15 // Integer to float conversion through lrintf() |
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
|
16 #ifdef HAVE_LRINTF |
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
|
17 #include <math.h> |
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
|
18 long int lrintf(float); |
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
|
19 #else |
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
|
20 #define lrintf(x) ((int)(x)) |
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
|
21 #endif |
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
|
22 |
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
|
23 #include "af.h" |
21507
fa99b3d31d13
Hack around libavutil/bswap.h compilation problems due to always_inline undefined.
reimar
parents:
21372
diff
changeset
|
24 #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
|
25 #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
|
26 |
8167 | 27 /* Functions used by play to convert the input audio to the correct |
28 format */ | |
7568 | 29 |
24561 | 30 /* The below includes retrieves functions for converting to and from |
8167 | 31 ulaw and alaw */ |
32 #include "af_format_ulaw.c" | |
33 #include "af_format_alaw.c" | |
7568 | 34 |
24561 | 35 // Switch endianness |
8167 | 36 static void endian(void* in, void* out, int len, int bps); |
24561 | 37 // From signed to unsigned and the other way |
16664 | 38 static void si2us(void* data, int len, int bps); |
8167 | 39 // Change the number of bits per sample |
40 static void change_bps(void* in, void* out, int len, int inbps, int outbps); | |
41 // 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
|
42 static void float2int(float* in, void* out, int len, int bps); |
8167 | 43 // 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
|
44 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
|
45 |
14272 | 46 static af_data_t* play(struct af_instance_s* af, af_data_t* data); |
47 static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data); | |
48 static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data); | |
49 static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data); | |
50 | |
8607 | 51 // Helper functions to check sanity for input arguments |
52 | |
53 // 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
|
54 static int check_bps(int bps) |
8607 | 55 { |
12478 | 56 if(bps != 4 && bps != 3 && bps != 2 && bps != 1){ |
8607 | 57 af_msg(AF_MSG_ERROR,"[format] The number of bytes per sample" |
12478 | 58 " must be 1, 2, 3 or 4. Current value is %i \n",bps); |
8607 | 59 return AF_ERROR; |
60 } | |
61 return AF_OK; | |
62 } | |
63 | |
64 // Check for unsupported formats | |
13989
dcb6b4a33aaa
declare check_format and check_bps static, they are used nowhere else.
reimar
parents:
12486
diff
changeset
|
65 static int check_format(int format) |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
66 { |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
67 char buf[256]; |
8607 | 68 switch(format & AF_FORMAT_SPECIAL_MASK){ |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
69 case(AF_FORMAT_IMA_ADPCM): |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
70 case(AF_FORMAT_MPEG2): |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
71 case(AF_FORMAT_AC3): |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
72 af_msg(AF_MSG_ERROR,"[format] Sample format %s not yet supported \n", |
14399
1a882e2a419b
af_fmt2str fixes (remove trailing space, call with size of buffer, not size-1)
reimar
parents:
14335
diff
changeset
|
73 af_fmt2str(format,buf,256)); |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
74 return AF_ERROR; |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
75 } |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
76 return AF_OK; |
8607 | 77 } |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
78 |
7568 | 79 // Initialization and runtime control |
80 static int control(struct af_instance_s* af, int cmd, void* arg) | |
81 { | |
82 switch(cmd){ | |
8167 | 83 case AF_CONTROL_REINIT:{ |
84 char buf1[256]; | |
85 char buf2[256]; | |
14272 | 86 af_data_t *data = arg; |
87 | |
7568 | 88 // Make sure this filter isn't redundant |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
89 if(af->data->format == data->format && |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
90 af->data->bps == data->bps) |
7568 | 91 return AF_DETACH; |
8607 | 92 |
24521 | 93 // Check for errors in configuration |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
94 if((AF_OK != check_bps(data->bps)) || |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
95 (AF_OK != check_format(data->format)) || |
8607 | 96 (AF_OK != check_bps(af->data->bps)) || |
97 (AF_OK != check_format(af->data->format))) | |
8167 | 98 return AF_ERROR; |
99 | |
14399
1a882e2a419b
af_fmt2str fixes (remove trailing space, call with size of buffer, not size-1)
reimar
parents:
14335
diff
changeset
|
100 af_msg(AF_MSG_VERBOSE,"[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
|
101 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
|
102 af_fmt2str(af->data->format,buf2,256)); |
7568 | 103 |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
104 af->data->rate = data->rate; |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
105 af->data->nch = data->nch; |
24888 | 106 af->mul = (double)af->data->bps / data->bps; |
14272 | 107 |
108 af->play = play; // set default | |
109 | |
24561 | 110 // look whether only endianness differences are there |
14272 | 111 if ((af->data->format & ~AF_FORMAT_END_MASK) == |
112 (data->format & ~AF_FORMAT_END_MASK)) | |
113 { | |
24561 | 114 af_msg(AF_MSG_VERBOSE,"[format] Accelerated endianness conversion only\n"); |
14272 | 115 af->play = play_swapendian; |
116 } | |
117 if ((data->format == AF_FORMAT_FLOAT_NE) && | |
118 (af->data->format == AF_FORMAT_S16_NE)) | |
119 { | |
14399
1a882e2a419b
af_fmt2str fixes (remove trailing space, call with size of buffer, not size-1)
reimar
parents:
14335
diff
changeset
|
120 af_msg(AF_MSG_VERBOSE,"[format] Accelerated %s to %s conversion\n", |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
121 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
|
122 af_fmt2str(af->data->format,buf2,256)); |
14272 | 123 af->play = play_float_s16; |
124 } | |
125 if ((data->format == AF_FORMAT_S16_NE) && | |
126 (af->data->format == AF_FORMAT_FLOAT_NE)) | |
127 { | |
14399
1a882e2a419b
af_fmt2str fixes (remove trailing space, call with size of buffer, not size-1)
reimar
parents:
14335
diff
changeset
|
128 af_msg(AF_MSG_VERBOSE,"[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_s16_float; |
132 } | |
7568 | 133 return AF_OK; |
8167 | 134 } |
7998
d48a06d07afb
Adding commandline options for filters and fixing stupid bug in cfg
anders
parents:
7719
diff
changeset
|
135 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
|
136 int format = af_str2fmt_short(arg); |
15311 | 137 if (format == -1) { |
138 af_msg(AF_MSG_ERROR, "[format] %s is not a valid format\n", (char *)arg); | |
139 return AF_ERROR; | |
140 } | |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
141 if(AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET,&format)) |
8607 | 142 return AF_ERROR; |
143 return AF_OK; | |
8167 | 144 } |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
145 case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET:{ |
24561 | 146 // Check for errors in configuration |
8607 | 147 if(AF_OK != check_format(*(int*)arg)) |
148 return AF_ERROR; | |
149 | |
150 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
|
151 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
|
152 |
7568 | 153 return AF_OK; |
154 } | |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
155 } |
7568 | 156 return AF_UNKNOWN; |
157 } | |
158 | |
159 // Deallocate memory | |
160 static void uninit(struct af_instance_s* af) | |
161 { | |
22179 | 162 if (af->data) |
163 free(af->data->audio); | |
164 free(af->data); | |
12386 | 165 af->setup = 0; |
7568 | 166 } |
167 | |
14272 | 168 static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data) |
169 { | |
170 af_data_t* l = af->data; // Local data | |
171 af_data_t* c = data; // Current working data | |
24561 | 172 int len = c->len/c->bps; // Length in samples of current audio block |
14272 | 173 |
174 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
175 return NULL; | |
176 | |
177 endian(c->audio,l->audio,len,c->bps); | |
178 | |
179 c->audio = l->audio; | |
180 c->format = l->format; | |
181 | |
182 return c; | |
183 } | |
184 | |
185 static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data) | |
186 { | |
187 af_data_t* l = af->data; // Local data | |
188 af_data_t* c = data; // Current working data | |
24561 | 189 int len = c->len/4; // Length in samples of current audio block |
14272 | 190 |
191 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
192 return NULL; | |
193 | |
194 float2int(c->audio, l->audio, len, 2); | |
195 | |
196 c->audio = l->audio; | |
197 c->len = len*2; | |
198 c->bps = 2; | |
199 c->format = l->format; | |
200 | |
201 return c; | |
202 } | |
203 | |
204 static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data) | |
205 { | |
206 af_data_t* l = af->data; // Local data | |
207 af_data_t* c = data; // Current working data | |
24561 | 208 int len = c->len/2; // Length in samples of current audio block |
14272 | 209 |
210 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
211 return NULL; | |
212 | |
213 int2float(c->audio, l->audio, len, 2); | |
214 | |
215 c->audio = l->audio; | |
216 c->len = len*4; | |
217 c->bps = 4; | |
218 c->format = l->format; | |
219 | |
220 return c; | |
221 } | |
222 | |
7568 | 223 // Filter data through filter |
224 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
225 { | |
8167 | 226 af_data_t* l = af->data; // Local data |
227 af_data_t* c = data; // Current working data | |
24561 | 228 int len = c->len/c->bps; // Length in samples of current audio block |
7568 | 229 |
230 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
231 return NULL; | |
232 | |
8167 | 233 // Change to cpu native endian format |
234 if((c->format&AF_FORMAT_END_MASK)!=AF_FORMAT_NE) | |
235 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
|
236 |
8167 | 237 // Conversion table |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
238 if((c->format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_MU_LAW) { |
8167 | 239 from_ulaw(c->audio, l->audio, len, l->bps, l->format&AF_FORMAT_POINT_MASK); |
240 if(AF_FORMAT_A_LAW == (l->format&AF_FORMAT_SPECIAL_MASK)) | |
241 to_ulaw(l->audio, l->audio, len, 1, AF_FORMAT_SI); | |
242 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) | |
16664 | 243 si2us(l->audio,len,l->bps); |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
244 } else if((c->format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_A_LAW) { |
8167 | 245 from_alaw(c->audio, l->audio, len, l->bps, l->format&AF_FORMAT_POINT_MASK); |
246 if(AF_FORMAT_A_LAW == (l->format&AF_FORMAT_SPECIAL_MASK)) | |
247 to_alaw(l->audio, l->audio, len, 1, AF_FORMAT_SI); | |
248 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) | |
16664 | 249 si2us(l->audio,len,l->bps); |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
250 } else if((c->format & AF_FORMAT_POINT_MASK) == AF_FORMAT_F) { |
8167 | 251 switch(l->format&AF_FORMAT_SPECIAL_MASK){ |
252 case(AF_FORMAT_MU_LAW): | |
253 to_ulaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
254 break; | |
255 case(AF_FORMAT_A_LAW): | |
256 to_alaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
7568 | 257 break; |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
258 default: |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
259 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
|
260 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) |
16664 | 261 si2us(l->audio,len,l->bps); |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
262 break; |
8167 | 263 } |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
264 } else { |
8167 | 265 // Input must be int |
266 | |
267 // Change signed/unsigned | |
268 if((c->format&AF_FORMAT_SIGN_MASK) != (l->format&AF_FORMAT_SIGN_MASK)){ | |
16664 | 269 si2us(c->audio,len,c->bps); |
8167 | 270 } |
271 // Convert to special formats | |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
272 switch(l->format&(AF_FORMAT_SPECIAL_MASK|AF_FORMAT_POINT_MASK)){ |
8167 | 273 case(AF_FORMAT_MU_LAW): |
274 to_ulaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
275 break; | |
276 case(AF_FORMAT_A_LAW): | |
277 to_alaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
278 break; | |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
279 case(AF_FORMAT_F): |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
280 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
|
281 break; |
8167 | 282 default: |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
283 // Change the number of bits |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
284 if(c->bps != l->bps) |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
285 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
|
286 else |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
22748
diff
changeset
|
287 fast_memcpy(l->audio,c->audio,len*c->bps); |
7568 | 288 break; |
289 } | |
290 } | |
7719
41e8d0916c60
Fix for audio filters on big endian cpus. It's working now on Solaris SPARC &
jkeil
parents:
7711
diff
changeset
|
291 |
24561 | 292 // Switch from cpu native endian to the correct endianness |
8167 | 293 if((l->format&AF_FORMAT_END_MASK)!=AF_FORMAT_NE) |
294 endian(l->audio,l->audio,len,l->bps); | |
7568 | 295 |
296 // Set output data | |
297 c->audio = l->audio; | |
8167 | 298 c->len = len*l->bps; |
7568 | 299 c->bps = l->bps; |
300 c->format = l->format; | |
301 return c; | |
302 } | |
303 | |
304 // 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
|
305 static int af_open(af_instance_t* af){ |
7568 | 306 af->control=control; |
307 af->uninit=uninit; | |
308 af->play=play; | |
24888 | 309 af->mul=1; |
7568 | 310 af->data=calloc(1,sizeof(af_data_t)); |
311 if(af->data == NULL) | |
312 return AF_ERROR; | |
313 return AF_OK; | |
314 } | |
315 | |
316 // Description of this filter | |
317 af_info_t af_info_format = { | |
318 "Sample format conversion", | |
319 "format", | |
320 "Anders", | |
321 "", | |
7615 | 322 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
|
323 af_open |
7568 | 324 }; |
8167 | 325 |
12478 | 326 static inline uint32_t load24bit(void* data, int pos) { |
327 #if WORDS_BIGENDIAN | |
328 return (((uint32_t)((uint8_t*)data)[3*pos])<<24) | | |
329 (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | | |
330 (((uint32_t)((uint8_t*)data)[3*pos+2])<<8); | |
331 #else | |
332 return (((uint32_t)((uint8_t*)data)[3*pos])<<8) | | |
333 (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | | |
334 (((uint32_t)((uint8_t*)data)[3*pos+2])<<24); | |
335 #endif | |
336 } | |
337 | |
338 static inline void store24bit(void* data, int pos, uint32_t expanded_value) { | |
339 #if WORDS_BIGENDIAN | |
340 ((uint8_t*)data)[3*pos]=expanded_value>>24; | |
341 ((uint8_t*)data)[3*pos+1]=expanded_value>>16; | |
342 ((uint8_t*)data)[3*pos+2]=expanded_value>>8; | |
343 #else | |
344 ((uint8_t*)data)[3*pos]=expanded_value>>8; | |
345 ((uint8_t*)data)[3*pos+1]=expanded_value>>16; | |
346 ((uint8_t*)data)[3*pos+2]=expanded_value>>24; | |
347 #endif | |
348 } | |
349 | |
8167 | 350 // Function implementations used by play |
351 static void endian(void* in, void* out, int len, int bps) | |
352 { | |
353 register int i; | |
354 switch(bps){ | |
355 case(2):{ | |
356 for(i=0;i<len;i++){ | |
12486 | 357 ((uint16_t*)out)[i]=bswap_16(((uint16_t*)in)[i]); |
8167 | 358 } |
359 break; | |
360 } | |
12478 | 361 case(3):{ |
362 register uint8_t s; | |
363 for(i=0;i<len;i++){ | |
364 s=((uint8_t*)in)[3*i]; | |
365 ((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
|
366 if (in != out) |
dbbc25ea6403
fix endian conversion for (curently unused) case where in buffer != out buffer
reimar
parents:
12478
diff
changeset
|
367 ((uint8_t*)out)[3*i+1]=((uint8_t*)in)[3*i+1]; |
12478 | 368 ((uint8_t*)out)[3*i+2]=s; |
369 } | |
370 break; | |
371 } | |
8167 | 372 case(4):{ |
373 for(i=0;i<len;i++){ | |
12486 | 374 ((uint32_t*)out)[i]=bswap_32(((uint32_t*)in)[i]); |
8167 | 375 } |
376 break; | |
377 } | |
378 } | |
379 } | |
380 | |
16664 | 381 static void si2us(void* data, int len, int bps) |
8167 | 382 { |
16664 | 383 register long i = -(len * bps); |
384 register uint8_t *p = &((uint8_t *)data)[len * bps]; | |
385 #if AF_FORMAT_NE == AF_FORMAT_LE | |
386 p += bps - 1; | |
387 #endif | |
388 if (len <= 0) return; | |
389 do { | |
390 p[i] ^= 0x80; | |
391 } while (i += bps); | |
8167 | 392 } |
393 | |
394 static void change_bps(void* in, void* out, int len, int inbps, int outbps) | |
395 { | |
396 register int i; | |
397 switch(inbps){ | |
398 case(1): | |
399 switch(outbps){ | |
400 case(2): | |
401 for(i=0;i<len;i++) | |
402 ((uint16_t*)out)[i]=((uint16_t)((uint8_t*)in)[i])<<8; | |
403 break; | |
12478 | 404 case(3): |
405 for(i=0;i<len;i++) | |
406 store24bit(out, i, ((uint32_t)((uint8_t*)in)[i])<<24); | |
407 break; | |
8167 | 408 case(4): |
409 for(i=0;i<len;i++) | |
410 ((uint32_t*)out)[i]=((uint32_t)((uint8_t*)in)[i])<<24; | |
411 break; | |
412 } | |
413 break; | |
414 case(2): | |
415 switch(outbps){ | |
416 case(1): | |
417 for(i=0;i<len;i++) | |
418 ((uint8_t*)out)[i]=(uint8_t)((((uint16_t*)in)[i])>>8); | |
419 break; | |
12478 | 420 case(3): |
421 for(i=0;i<len;i++) | |
422 store24bit(out, i, ((uint32_t)((uint16_t*)in)[i])<<16); | |
423 break; | |
8167 | 424 case(4): |
425 for(i=0;i<len;i++) | |
426 ((uint32_t*)out)[i]=((uint32_t)((uint16_t*)in)[i])<<16; | |
427 break; | |
428 } | |
429 break; | |
12478 | 430 case(3): |
431 switch(outbps){ | |
432 case(1): | |
433 for(i=0;i<len;i++) | |
434 ((uint8_t*)out)[i]=(uint8_t)(load24bit(in, i)>>24); | |
435 break; | |
436 case(2): | |
437 for(i=0;i<len;i++) | |
438 ((uint16_t*)out)[i]=(uint16_t)(load24bit(in, i)>>16); | |
439 break; | |
440 case(4): | |
441 for(i=0;i<len;i++) | |
442 ((uint32_t*)out)[i]=(uint32_t)load24bit(in, i); | |
443 break; | |
444 } | |
445 break; | |
8167 | 446 case(4): |
447 switch(outbps){ | |
448 case(1): | |
449 for(i=0;i<len;i++) | |
450 ((uint8_t*)out)[i]=(uint8_t)((((uint32_t*)in)[i])>>24); | |
451 break; | |
452 case(2): | |
453 for(i=0;i<len;i++) | |
454 ((uint16_t*)out)[i]=(uint16_t)((((uint32_t*)in)[i])>>16); | |
455 break; | |
12478 | 456 case(3): |
457 for(i=0;i<len;i++) | |
458 store24bit(out, i, ((uint32_t*)in)[i]); | |
459 break; | |
8167 | 460 } |
461 break; | |
462 } | |
463 } | |
464 | |
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
|
465 static void float2int(float* in, void* out, int len, int bps) |
8167 | 466 { |
467 register int i; | |
468 switch(bps){ | |
469 case(1): | |
470 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
|
471 ((int8_t*)out)[i] = lrintf(127.0 * in[i]); |
8167 | 472 break; |
473 case(2): | |
474 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
|
475 ((int16_t*)out)[i] = lrintf(32767.0 * in[i]); |
8167 | 476 break; |
12478 | 477 case(3): |
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 store24bit(out, i, lrintf(2147483647.0 * in[i])); |
12478 | 480 break; |
8167 | 481 case(4): |
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 ((int32_t*)out)[i] = lrintf(2147483647.0 * in[i]); |
8167 | 484 break; |
485 } | |
486 } | |
487 | |
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
|
488 static void int2float(void* in, float* out, int len, int bps) |
8167 | 489 { |
490 register int i; | |
491 switch(bps){ | |
492 case(1): | |
493 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
|
494 out[i]=(1.0/128.0)*((int8_t*)in)[i]; |
8167 | 495 break; |
496 case(2): | |
497 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
|
498 out[i]=(1.0/32768.0)*((int16_t*)in)[i]; |
8167 | 499 break; |
12478 | 500 case(3): |
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/2147483648.0)*((int32_t)load24bit(in, i)); |
12478 | 503 break; |
8167 | 504 case(4): |
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/2147483648.0)*((int32_t*)in)[i]; |
8167 | 507 break; |
508 } | |
509 } |