Mercurial > mplayer.hg
annotate libaf/af_format.c @ 30387:30d6f38357c7
If audio was identified as DTS in the PMT do not override that with TrueHD
based only on substream id.
Works with all available DTS and TrueHD samples available (2 each).
author | reimar |
---|---|
date | Sun, 24 Jan 2010 20:54:17 +0000 |
parents | 02b9c1a452e1 |
children | 6c8743e5fa30 |
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 |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
29401
diff
changeset
|
101 // Allow trivial AC3-endianness conversion |
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
29401
diff
changeset
|
102 if (!AF_FORMAT_IS_AC3(af->data->format) || !AF_FORMAT_IS_AC3(data->format)) |
24521 | 103 // Check for errors in configuration |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
104 if((AF_OK != check_bps(data->bps)) || |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
105 (AF_OK != check_format(data->format)) || |
8607 | 106 (AF_OK != check_bps(af->data->bps)) || |
107 (AF_OK != check_format(af->data->format))) | |
8167 | 108 return AF_ERROR; |
109 | |
29049 | 110 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
|
111 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
|
112 af_fmt2str(af->data->format,buf2,256)); |
7568 | 113 |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
114 af->data->rate = data->rate; |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
115 af->data->nch = data->nch; |
24888 | 116 af->mul = (double)af->data->bps / data->bps; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
117 |
14272 | 118 af->play = play; // set default |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
119 |
24561 | 120 // look whether only endianness differences are there |
14272 | 121 if ((af->data->format & ~AF_FORMAT_END_MASK) == |
122 (data->format & ~AF_FORMAT_END_MASK)) | |
123 { | |
29049 | 124 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Accelerated endianness conversion only\n"); |
14272 | 125 af->play = play_swapendian; |
126 } | |
127 if ((data->format == AF_FORMAT_FLOAT_NE) && | |
128 (af->data->format == AF_FORMAT_S16_NE)) | |
129 { | |
29049 | 130 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
|
131 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
|
132 af_fmt2str(af->data->format,buf2,256)); |
14272 | 133 af->play = play_float_s16; |
134 } | |
135 if ((data->format == AF_FORMAT_S16_NE) && | |
136 (af->data->format == AF_FORMAT_FLOAT_NE)) | |
137 { | |
29049 | 138 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
|
139 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
|
140 af_fmt2str(af->data->format,buf2,256)); |
14272 | 141 af->play = play_s16_float; |
142 } | |
7568 | 143 return AF_OK; |
8167 | 144 } |
7998
d48a06d07afb
Adding commandline options for filters and fixing stupid bug in cfg
anders
parents:
7719
diff
changeset
|
145 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
|
146 int format = af_str2fmt_short(arg); |
15311 | 147 if (format == -1) { |
29049 | 148 mp_msg(MSGT_AFILTER, MSGL_ERR, "[format] %s is not a valid format\n", (char *)arg); |
15311 | 149 return AF_ERROR; |
150 } | |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
151 if(AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET,&format)) |
8607 | 152 return AF_ERROR; |
153 return AF_OK; | |
8167 | 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 case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET:{ |
24561 | 156 // Check for errors in configuration |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
29401
diff
changeset
|
157 if(!AF_FORMAT_IS_AC3(*(int*)arg) && AF_OK != check_format(*(int*)arg)) |
8607 | 158 return AF_ERROR; |
159 | |
160 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
|
161 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
|
162 |
7568 | 163 return AF_OK; |
164 } | |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
165 } |
7568 | 166 return AF_UNKNOWN; |
167 } | |
168 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
169 // Deallocate memory |
7568 | 170 static void uninit(struct af_instance_s* af) |
171 { | |
22179 | 172 if (af->data) |
173 free(af->data->audio); | |
174 free(af->data); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
175 af->setup = 0; |
7568 | 176 } |
177 | |
14272 | 178 static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data) |
179 { | |
180 af_data_t* l = af->data; // Local data | |
181 af_data_t* c = data; // Current working data | |
24561 | 182 int len = c->len/c->bps; // Length in samples of current audio block |
14272 | 183 |
184 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
185 return NULL; | |
186 | |
187 endian(c->audio,l->audio,len,c->bps); | |
188 | |
189 c->audio = l->audio; | |
190 c->format = l->format; | |
191 | |
192 return c; | |
193 } | |
194 | |
195 static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data) | |
196 { | |
197 af_data_t* l = af->data; // Local data | |
198 af_data_t* c = data; // Current working data | |
24561 | 199 int len = c->len/4; // Length in samples of current audio block |
14272 | 200 |
201 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
202 return NULL; | |
203 | |
204 float2int(c->audio, l->audio, len, 2); | |
205 | |
206 c->audio = l->audio; | |
207 c->len = len*2; | |
208 c->bps = 2; | |
209 c->format = l->format; | |
210 | |
211 return c; | |
212 } | |
213 | |
214 static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data) | |
215 { | |
216 af_data_t* l = af->data; // Local data | |
217 af_data_t* c = data; // Current working data | |
24561 | 218 int len = c->len/2; // Length in samples of current audio block |
14272 | 219 |
220 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
221 return NULL; | |
222 | |
223 int2float(c->audio, l->audio, len, 2); | |
224 | |
225 c->audio = l->audio; | |
226 c->len = len*4; | |
227 c->bps = 4; | |
228 c->format = l->format; | |
229 | |
230 return c; | |
231 } | |
232 | |
7568 | 233 // Filter data through filter |
234 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
235 { | |
8167 | 236 af_data_t* l = af->data; // Local data |
237 af_data_t* c = data; // Current working data | |
24561 | 238 int len = c->len/c->bps; // Length in samples of current audio block |
7568 | 239 |
240 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
241 return NULL; | |
242 | |
8167 | 243 // Change to cpu native endian format |
244 if((c->format&AF_FORMAT_END_MASK)!=AF_FORMAT_NE) | |
245 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
|
246 |
8167 | 247 // Conversion table |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
248 if((c->format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_MU_LAW) { |
8167 | 249 from_ulaw(c->audio, l->audio, len, l->bps, l->format&AF_FORMAT_POINT_MASK); |
250 if(AF_FORMAT_A_LAW == (l->format&AF_FORMAT_SPECIAL_MASK)) | |
251 to_ulaw(l->audio, l->audio, len, 1, AF_FORMAT_SI); | |
252 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) | |
16664 | 253 si2us(l->audio,len,l->bps); |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
254 } else if((c->format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_A_LAW) { |
8167 | 255 from_alaw(c->audio, l->audio, len, l->bps, l->format&AF_FORMAT_POINT_MASK); |
256 if(AF_FORMAT_A_LAW == (l->format&AF_FORMAT_SPECIAL_MASK)) | |
257 to_alaw(l->audio, l->audio, len, 1, AF_FORMAT_SI); | |
258 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) | |
16664 | 259 si2us(l->audio,len,l->bps); |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
260 } else if((c->format & AF_FORMAT_POINT_MASK) == AF_FORMAT_F) { |
8167 | 261 switch(l->format&AF_FORMAT_SPECIAL_MASK){ |
262 case(AF_FORMAT_MU_LAW): | |
263 to_ulaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
264 break; | |
265 case(AF_FORMAT_A_LAW): | |
266 to_alaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
7568 | 267 break; |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
268 default: |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
269 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
|
270 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) |
16664 | 271 si2us(l->audio,len,l->bps); |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
272 break; |
8167 | 273 } |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
274 } else { |
8167 | 275 // Input must be int |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
276 |
8167 | 277 // Change signed/unsigned |
278 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
|
279 si2us(c->audio,len,c->bps); |
8167 | 280 } |
281 // Convert to special formats | |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
282 switch(l->format&(AF_FORMAT_SPECIAL_MASK|AF_FORMAT_POINT_MASK)){ |
8167 | 283 case(AF_FORMAT_MU_LAW): |
284 to_ulaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
285 break; | |
286 case(AF_FORMAT_A_LAW): | |
287 to_alaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
288 break; | |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
289 case(AF_FORMAT_F): |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
290 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
|
291 break; |
8167 | 292 default: |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
293 // Change the number of bits |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
294 if(c->bps != l->bps) |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
295 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
|
296 else |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
22748
diff
changeset
|
297 fast_memcpy(l->audio,c->audio,len*c->bps); |
7568 | 298 break; |
299 } | |
300 } | |
7719
41e8d0916c60
Fix for audio filters on big endian cpus. It's working now on Solaris SPARC &
jkeil
parents:
7711
diff
changeset
|
301 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
302 // Switch from cpu native endian to the correct endianness |
8167 | 303 if((l->format&AF_FORMAT_END_MASK)!=AF_FORMAT_NE) |
304 endian(l->audio,l->audio,len,l->bps); | |
7568 | 305 |
306 // Set output data | |
307 c->audio = l->audio; | |
8167 | 308 c->len = len*l->bps; |
7568 | 309 c->bps = l->bps; |
310 c->format = l->format; | |
311 return c; | |
312 } | |
313 | |
314 // 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
|
315 static int af_open(af_instance_t* af){ |
7568 | 316 af->control=control; |
317 af->uninit=uninit; | |
318 af->play=play; | |
24888 | 319 af->mul=1; |
7568 | 320 af->data=calloc(1,sizeof(af_data_t)); |
321 if(af->data == NULL) | |
322 return AF_ERROR; | |
323 return AF_OK; | |
324 } | |
325 | |
326 // Description of this filter | |
327 af_info_t af_info_format = { | |
328 "Sample format conversion", | |
329 "format", | |
330 "Anders", | |
331 "", | |
7615 | 332 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
|
333 af_open |
7568 | 334 }; |
8167 | 335 |
12478 | 336 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
|
337 #if HAVE_BIGENDIAN |
12478 | 338 return (((uint32_t)((uint8_t*)data)[3*pos])<<24) | |
339 (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | | |
340 (((uint32_t)((uint8_t*)data)[3*pos+2])<<8); | |
341 #else | |
342 return (((uint32_t)((uint8_t*)data)[3*pos])<<8) | | |
343 (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | | |
344 (((uint32_t)((uint8_t*)data)[3*pos+2])<<24); | |
345 #endif | |
346 } | |
347 | |
348 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
|
349 #if HAVE_BIGENDIAN |
12478 | 350 ((uint8_t*)data)[3*pos]=expanded_value>>24; |
351 ((uint8_t*)data)[3*pos+1]=expanded_value>>16; | |
352 ((uint8_t*)data)[3*pos+2]=expanded_value>>8; | |
353 #else | |
354 ((uint8_t*)data)[3*pos]=expanded_value>>8; | |
355 ((uint8_t*)data)[3*pos+1]=expanded_value>>16; | |
356 ((uint8_t*)data)[3*pos+2]=expanded_value>>24; | |
357 #endif | |
358 } | |
359 | |
8167 | 360 // Function implementations used by play |
361 static void endian(void* in, void* out, int len, int bps) | |
362 { | |
363 register int i; | |
364 switch(bps){ | |
365 case(2):{ | |
366 for(i=0;i<len;i++){ | |
12486 | 367 ((uint16_t*)out)[i]=bswap_16(((uint16_t*)in)[i]); |
8167 | 368 } |
369 break; | |
370 } | |
12478 | 371 case(3):{ |
372 register uint8_t s; | |
373 for(i=0;i<len;i++){ | |
374 s=((uint8_t*)in)[3*i]; | |
375 ((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
|
376 if (in != out) |
dbbc25ea6403
fix endian conversion for (curently unused) case where in buffer != out buffer
reimar
parents:
12478
diff
changeset
|
377 ((uint8_t*)out)[3*i+1]=((uint8_t*)in)[3*i+1]; |
12478 | 378 ((uint8_t*)out)[3*i+2]=s; |
379 } | |
380 break; | |
381 } | |
8167 | 382 case(4):{ |
383 for(i=0;i<len;i++){ | |
12486 | 384 ((uint32_t*)out)[i]=bswap_32(((uint32_t*)in)[i]); |
8167 | 385 } |
386 break; | |
387 } | |
388 } | |
389 } | |
390 | |
16664 | 391 static void si2us(void* data, int len, int bps) |
8167 | 392 { |
16664 | 393 register long i = -(len * bps); |
394 register uint8_t *p = &((uint8_t *)data)[len * bps]; | |
395 #if AF_FORMAT_NE == AF_FORMAT_LE | |
396 p += bps - 1; | |
397 #endif | |
398 if (len <= 0) return; | |
399 do { | |
400 p[i] ^= 0x80; | |
401 } while (i += bps); | |
8167 | 402 } |
403 | |
404 static void change_bps(void* in, void* out, int len, int inbps, int outbps) | |
405 { | |
406 register int i; | |
407 switch(inbps){ | |
408 case(1): | |
409 switch(outbps){ | |
410 case(2): | |
411 for(i=0;i<len;i++) | |
412 ((uint16_t*)out)[i]=((uint16_t)((uint8_t*)in)[i])<<8; | |
413 break; | |
12478 | 414 case(3): |
415 for(i=0;i<len;i++) | |
416 store24bit(out, i, ((uint32_t)((uint8_t*)in)[i])<<24); | |
417 break; | |
8167 | 418 case(4): |
419 for(i=0;i<len;i++) | |
420 ((uint32_t*)out)[i]=((uint32_t)((uint8_t*)in)[i])<<24; | |
421 break; | |
422 } | |
423 break; | |
424 case(2): | |
425 switch(outbps){ | |
426 case(1): | |
427 for(i=0;i<len;i++) | |
428 ((uint8_t*)out)[i]=(uint8_t)((((uint16_t*)in)[i])>>8); | |
429 break; | |
12478 | 430 case(3): |
431 for(i=0;i<len;i++) | |
432 store24bit(out, i, ((uint32_t)((uint16_t*)in)[i])<<16); | |
433 break; | |
8167 | 434 case(4): |
435 for(i=0;i<len;i++) | |
436 ((uint32_t*)out)[i]=((uint32_t)((uint16_t*)in)[i])<<16; | |
437 break; | |
438 } | |
439 break; | |
12478 | 440 case(3): |
441 switch(outbps){ | |
442 case(1): | |
443 for(i=0;i<len;i++) | |
444 ((uint8_t*)out)[i]=(uint8_t)(load24bit(in, i)>>24); | |
445 break; | |
446 case(2): | |
447 for(i=0;i<len;i++) | |
448 ((uint16_t*)out)[i]=(uint16_t)(load24bit(in, i)>>16); | |
449 break; | |
450 case(4): | |
451 for(i=0;i<len;i++) | |
452 ((uint32_t*)out)[i]=(uint32_t)load24bit(in, i); | |
453 break; | |
454 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
455 break; |
8167 | 456 case(4): |
457 switch(outbps){ | |
458 case(1): | |
459 for(i=0;i<len;i++) | |
460 ((uint8_t*)out)[i]=(uint8_t)((((uint32_t*)in)[i])>>24); | |
461 break; | |
462 case(2): | |
463 for(i=0;i<len;i++) | |
464 ((uint16_t*)out)[i]=(uint16_t)((((uint32_t*)in)[i])>>16); | |
465 break; | |
12478 | 466 case(3): |
467 for(i=0;i<len;i++) | |
468 store24bit(out, i, ((uint32_t*)in)[i]); | |
469 break; | |
8167 | 470 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
471 break; |
8167 | 472 } |
473 } | |
474 | |
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 static void float2int(float* in, void* out, int len, int bps) |
8167 | 476 { |
477 register int i; | |
478 switch(bps){ | |
479 case(1): | |
480 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
|
481 ((int8_t*)out)[i] = lrintf(127.0 * in[i]); |
8167 | 482 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
483 case(2): |
8167 | 484 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
|
485 ((int16_t*)out)[i] = lrintf(32767.0 * in[i]); |
8167 | 486 break; |
12478 | 487 case(3): |
488 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
|
489 store24bit(out, i, lrintf(2147483647.0 * in[i])); |
12478 | 490 break; |
8167 | 491 case(4): |
492 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
|
493 ((int32_t*)out)[i] = lrintf(2147483647.0 * in[i]); |
8167 | 494 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
495 } |
8167 | 496 } |
497 | |
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 static void int2float(void* in, float* out, int len, int bps) |
8167 | 499 { |
500 register int i; | |
501 switch(bps){ | |
502 case(1): | |
503 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
|
504 out[i]=(1.0/128.0)*((int8_t*)in)[i]; |
8167 | 505 break; |
506 case(2): | |
507 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
|
508 out[i]=(1.0/32768.0)*((int16_t*)in)[i]; |
8167 | 509 break; |
12478 | 510 case(3): |
511 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
|
512 out[i]=(1.0/2147483648.0)*((int32_t)load24bit(in, i)); |
12478 | 513 break; |
8167 | 514 case(4): |
515 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
|
516 out[i]=(1.0/2147483648.0)*((int32_t*)in)[i]; |
8167 | 517 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
518 } |
8167 | 519 } |