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