Mercurial > mplayer.hg
annotate libaf/af_format.c @ 35805:5d163370a554
Restructure code for video window in uiChangeSkin().
Compact the conditions. It's much clearer now what's happening.
Additionally, change comment to indicate that the video window
will not be reloaded (like all other windows).
author | ib |
---|---|
date | Sat, 26 Jan 2013 15:32:37 +0000 |
parents | d206960484fe |
children | e79bac50b920 |
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" |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
33736
diff
changeset
|
32 #include "mp_msg.h" |
21507
fa99b3d31d13
Hack around libavutil/bswap.h compilation problems due to always_inline undefined.
reimar
parents:
21372
diff
changeset
|
33 #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
|
34 #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
|
35 |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
36 #include "libavutil/avutil.h" |
35712
d206960484fe
Add a number of missing libavutil header #includes.
diego
parents:
35451
diff
changeset
|
37 #include "libavutil/common.h" |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
38 |
8167 | 39 /* Functions used by play to convert the input audio to the correct |
40 format */ | |
7568 | 41 |
24561 | 42 /* The below includes retrieves functions for converting to and from |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
43 ulaw and alaw */ |
28238
1bf9023840f9
Rename libaf/af_format_alaw.c --> libaf/af_format_alaw.h and
diego
parents:
28236
diff
changeset
|
44 #include "af_format_ulaw.h" |
1bf9023840f9
Rename libaf/af_format_alaw.c --> libaf/af_format_alaw.h and
diego
parents:
28236
diff
changeset
|
45 #include "af_format_alaw.h" |
7568 | 46 |
24561 | 47 // Switch endianness |
8167 | 48 static void endian(void* in, void* out, int len, int bps); |
24561 | 49 // From signed to unsigned and the other way |
16664 | 50 static void si2us(void* data, int len, int bps); |
8167 | 51 // Change the number of bits per sample |
52 static void change_bps(void* in, void* out, int len, int inbps, int outbps); | |
53 // 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
|
54 static void float2int(float* in, void* out, int len, int bps); |
8167 | 55 // 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
|
56 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
|
57 |
14272 | 58 static af_data_t* play(struct af_instance_s* af, af_data_t* data); |
59 static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data); | |
60 static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data); | |
61 static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data); | |
62 | |
8607 | 63 // Helper functions to check sanity for input arguments |
64 | |
65 // 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
|
66 static int check_bps(int bps) |
8607 | 67 { |
12478 | 68 if(bps != 4 && bps != 3 && bps != 2 && bps != 1){ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
69 mp_msg(MSGT_AFILTER, MSGL_ERR, "[format] The number of bytes per sample" |
12478 | 70 " must be 1, 2, 3 or 4. Current value is %i \n",bps); |
8607 | 71 return AF_ERROR; |
72 } | |
73 return AF_OK; | |
74 } | |
75 | |
76 // Check for unsupported formats | |
13989
dcb6b4a33aaa
declare check_format and check_bps static, they are used nowhere else.
reimar
parents:
12486
diff
changeset
|
77 static int check_format(int format) |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
78 { |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
79 char buf[256]; |
8607 | 80 switch(format & AF_FORMAT_SPECIAL_MASK){ |
35451
29f66b254dd7
af_format: Fix check_format, non-special formats are of course supported.
reimar
parents:
35444
diff
changeset
|
81 case 0: |
35440
c2b5fda66143
Replace outdated list of unsupported formats by list of supported formats.
reimar
parents:
34174
diff
changeset
|
82 case AF_FORMAT_MU_LAW: |
c2b5fda66143
Replace outdated list of unsupported formats by list of supported formats.
reimar
parents:
34174
diff
changeset
|
83 case AF_FORMAT_A_LAW: |
c2b5fda66143
Replace outdated list of unsupported formats by list of supported formats.
reimar
parents:
34174
diff
changeset
|
84 return AF_OK; |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
85 } |
35440
c2b5fda66143
Replace outdated list of unsupported formats by list of supported formats.
reimar
parents:
34174
diff
changeset
|
86 mp_msg(MSGT_AFILTER, MSGL_ERR, "[format] Sample format %s not yet supported \n", |
c2b5fda66143
Replace outdated list of unsupported formats by list of supported formats.
reimar
parents:
34174
diff
changeset
|
87 af_fmt2str(format,buf,256)); |
c2b5fda66143
Replace outdated list of unsupported formats by list of supported formats.
reimar
parents:
34174
diff
changeset
|
88 return AF_ERROR; |
8607 | 89 } |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
90 |
7568 | 91 // Initialization and runtime control |
92 static int control(struct af_instance_s* af, int cmd, void* arg) | |
93 { | |
94 switch(cmd){ | |
8167 | 95 case AF_CONTROL_REINIT:{ |
96 char buf1[256]; | |
97 char buf2[256]; | |
14272 | 98 af_data_t *data = arg; |
35444
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
99 int supported_ac3 = 0; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
100 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
101 // Make sure this filter isn't redundant |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
102 if(af->data->format == data->format && |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
103 af->data->bps == data->bps) |
7568 | 104 return AF_DETACH; |
8607 | 105 |
35444
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
106 // A bit complex because we can convert AC3 |
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
107 // to generic iec61937 but not the other way |
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
108 // round. |
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
109 if (AF_FORMAT_IS_AC3(af->data->format)) |
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
110 supported_ac3 = AF_FORMAT_IS_AC3(data->format); |
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
111 else if (AF_FORMAT_IS_IEC61937(af->data->format)) |
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
112 supported_ac3 = AF_FORMAT_IS_IEC61937(data->format); |
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
113 |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
29401
diff
changeset
|
114 // Allow trivial AC3-endianness conversion |
35444
4644c320daf4
af_format: support endianness conversion also for iec61937
reimar
parents:
35441
diff
changeset
|
115 if (!supported_ac3) |
24521 | 116 // Check for errors in configuration |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
117 if((AF_OK != check_bps(data->bps)) || |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
118 (AF_OK != check_format(data->format)) || |
8607 | 119 (AF_OK != check_bps(af->data->bps)) || |
120 (AF_OK != check_format(af->data->format))) | |
8167 | 121 return AF_ERROR; |
122 | |
35441
6dc94af7016d
Do not call af_fmt2str on the same data over and over.
reimar
parents:
35440
diff
changeset
|
123 af_fmt2str(data->format,buf1,256); |
6dc94af7016d
Do not call af_fmt2str on the same data over and over.
reimar
parents:
35440
diff
changeset
|
124 af_fmt2str(af->data->format,buf2,256); |
29049 | 125 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Changing sample format from %s to %s\n", |
35441
6dc94af7016d
Do not call af_fmt2str on the same data over and over.
reimar
parents:
35440
diff
changeset
|
126 buf1, buf2); |
7568 | 127 |
14717
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
128 af->data->rate = data->rate; |
51a7560a92b7
confusing mixture of typecasts and casted variable, removed typecasts
reimar
parents:
14433
diff
changeset
|
129 af->data->nch = data->nch; |
24888 | 130 af->mul = (double)af->data->bps / data->bps; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
131 |
14272 | 132 af->play = play; // set default |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
133 |
24561 | 134 // look whether only endianness differences are there |
14272 | 135 if ((af->data->format & ~AF_FORMAT_END_MASK) == |
136 (data->format & ~AF_FORMAT_END_MASK)) | |
137 { | |
29049 | 138 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Accelerated endianness conversion only\n"); |
14272 | 139 af->play = play_swapendian; |
140 } | |
141 if ((data->format == AF_FORMAT_FLOAT_NE) && | |
142 (af->data->format == AF_FORMAT_S16_NE)) | |
143 { | |
29049 | 144 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Accelerated %s to %s conversion\n", |
35441
6dc94af7016d
Do not call af_fmt2str on the same data over and over.
reimar
parents:
35440
diff
changeset
|
145 buf1, buf2); |
14272 | 146 af->play = play_float_s16; |
147 } | |
148 if ((data->format == AF_FORMAT_S16_NE) && | |
149 (af->data->format == AF_FORMAT_FLOAT_NE)) | |
150 { | |
29049 | 151 mp_msg(MSGT_AFILTER, MSGL_V, "[format] Accelerated %s to %s conversion\n", |
35441
6dc94af7016d
Do not call af_fmt2str on the same data over and over.
reimar
parents:
35440
diff
changeset
|
152 buf1, buf2); |
14272 | 153 af->play = play_s16_float; |
154 } | |
7568 | 155 return AF_OK; |
8167 | 156 } |
7998
d48a06d07afb
Adding commandline options for filters and fixing stupid bug in cfg
anders
parents:
7719
diff
changeset
|
157 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
|
158 int format = af_str2fmt_short(arg); |
15311 | 159 if (format == -1) { |
29049 | 160 mp_msg(MSGT_AFILTER, MSGL_ERR, "[format] %s is not a valid format\n", (char *)arg); |
15311 | 161 return AF_ERROR; |
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 if(AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET,&format)) |
8607 | 164 return AF_ERROR; |
165 return AF_OK; | |
8167 | 166 } |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
167 case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET:{ |
24561 | 168 // Check for errors in configuration |
30241
02b9c1a452e1
Add support for distinguishing between little- and big-endian SPDIF AC3
reimar
parents:
29401
diff
changeset
|
169 if(!AF_FORMAT_IS_AC3(*(int*)arg) && AF_OK != check_format(*(int*)arg)) |
8607 | 170 return AF_ERROR; |
171 | |
172 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
|
173 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
|
174 |
7568 | 175 return AF_OK; |
176 } | |
14335
8380694ba14f
af_bits2fmt and af_str2fmt_short, also removed the extra FORMAT_BPS control in format.c
alex
parents:
14272
diff
changeset
|
177 } |
7568 | 178 return AF_UNKNOWN; |
179 } | |
180 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
181 // Deallocate memory |
7568 | 182 static void uninit(struct af_instance_s* af) |
183 { | |
22179 | 184 if (af->data) |
185 free(af->data->audio); | |
186 free(af->data); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
187 af->setup = 0; |
7568 | 188 } |
189 | |
14272 | 190 static af_data_t* play_swapendian(struct af_instance_s* af, af_data_t* data) |
191 { | |
192 af_data_t* l = af->data; // Local data | |
193 af_data_t* c = data; // Current working data | |
24561 | 194 int len = c->len/c->bps; // Length in samples of current audio block |
14272 | 195 |
196 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
197 return NULL; | |
198 | |
199 endian(c->audio,l->audio,len,c->bps); | |
200 | |
201 c->audio = l->audio; | |
202 c->format = l->format; | |
203 | |
204 return c; | |
205 } | |
206 | |
207 static af_data_t* play_float_s16(struct af_instance_s* af, af_data_t* data) | |
208 { | |
209 af_data_t* l = af->data; // Local data | |
210 af_data_t* c = data; // Current working data | |
24561 | 211 int len = c->len/4; // Length in samples of current audio block |
14272 | 212 |
213 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
214 return NULL; | |
215 | |
216 float2int(c->audio, l->audio, len, 2); | |
217 | |
218 c->audio = l->audio; | |
219 c->len = len*2; | |
220 c->bps = 2; | |
221 c->format = l->format; | |
222 | |
223 return c; | |
224 } | |
225 | |
226 static af_data_t* play_s16_float(struct af_instance_s* af, af_data_t* data) | |
227 { | |
228 af_data_t* l = af->data; // Local data | |
229 af_data_t* c = data; // Current working data | |
24561 | 230 int len = c->len/2; // Length in samples of current audio block |
14272 | 231 |
232 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
233 return NULL; | |
234 | |
235 int2float(c->audio, l->audio, len, 2); | |
236 | |
237 c->audio = l->audio; | |
238 c->len = len*4; | |
239 c->bps = 4; | |
240 c->format = l->format; | |
241 | |
242 return c; | |
243 } | |
244 | |
7568 | 245 // Filter data through filter |
246 static af_data_t* play(struct af_instance_s* af, af_data_t* data) | |
247 { | |
8167 | 248 af_data_t* l = af->data; // Local data |
249 af_data_t* c = data; // Current working data | |
24561 | 250 int len = c->len/c->bps; // Length in samples of current audio block |
7568 | 251 |
252 if(AF_OK != RESIZE_LOCAL_BUFFER(af,data)) | |
253 return NULL; | |
254 | |
8167 | 255 // Change to cpu native endian format |
256 if((c->format&AF_FORMAT_END_MASK)!=AF_FORMAT_NE) | |
257 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
|
258 |
8167 | 259 // Conversion table |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
260 if((c->format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_MU_LAW) { |
8167 | 261 from_ulaw(c->audio, l->audio, len, l->bps, l->format&AF_FORMAT_POINT_MASK); |
262 if(AF_FORMAT_A_LAW == (l->format&AF_FORMAT_SPECIAL_MASK)) | |
263 to_ulaw(l->audio, l->audio, len, 1, AF_FORMAT_SI); | |
264 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) | |
16664 | 265 si2us(l->audio,len,l->bps); |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
266 } else if((c->format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_A_LAW) { |
8167 | 267 from_alaw(c->audio, l->audio, len, l->bps, l->format&AF_FORMAT_POINT_MASK); |
268 if(AF_FORMAT_A_LAW == (l->format&AF_FORMAT_SPECIAL_MASK)) | |
269 to_alaw(l->audio, l->audio, len, 1, AF_FORMAT_SI); | |
270 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) | |
16664 | 271 si2us(l->audio,len,l->bps); |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
272 } else if((c->format & AF_FORMAT_POINT_MASK) == AF_FORMAT_F) { |
8167 | 273 switch(l->format&AF_FORMAT_SPECIAL_MASK){ |
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); | |
7568 | 279 break; |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
280 default: |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
281 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
|
282 if((l->format&AF_FORMAT_SIGN_MASK) == AF_FORMAT_US) |
16664 | 283 si2us(l->audio,len,l->bps); |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
284 break; |
8167 | 285 } |
14261
710b223604fa
100l use right mask type when checking for input format
rtognimp
parents:
14256
diff
changeset
|
286 } else { |
8167 | 287 // Input must be int |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
288 |
8167 | 289 // Change signed/unsigned |
290 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
|
291 si2us(c->audio,len,c->bps); |
8167 | 292 } |
293 // Convert to special formats | |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
294 switch(l->format&(AF_FORMAT_SPECIAL_MASK|AF_FORMAT_POINT_MASK)){ |
8167 | 295 case(AF_FORMAT_MU_LAW): |
296 to_ulaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
297 break; | |
298 case(AF_FORMAT_A_LAW): | |
299 to_alaw(c->audio, l->audio, len, c->bps, c->format&AF_FORMAT_POINT_MASK); | |
300 break; | |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
301 case(AF_FORMAT_F): |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
302 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
|
303 break; |
8167 | 304 default: |
8180
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
305 // Change the number of bits |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
306 if(c->bps != l->bps) |
4ba9aed295f2
Fixing segfault bug and addnig support for lrintf() in format conversion
anders
parents:
8167
diff
changeset
|
307 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
|
308 else |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
22748
diff
changeset
|
309 fast_memcpy(l->audio,c->audio,len*c->bps); |
7568 | 310 break; |
311 } | |
312 } | |
7719
41e8d0916c60
Fix for audio filters on big endian cpus. It's working now on Solaris SPARC &
jkeil
parents:
7711
diff
changeset
|
313 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
314 // Switch from cpu native endian to the correct endianness |
8167 | 315 if((l->format&AF_FORMAT_END_MASK)!=AF_FORMAT_NE) |
316 endian(l->audio,l->audio,len,l->bps); | |
7568 | 317 |
318 // Set output data | |
319 c->audio = l->audio; | |
8167 | 320 c->len = len*l->bps; |
7568 | 321 c->bps = l->bps; |
322 c->format = l->format; | |
323 return c; | |
324 } | |
325 | |
326 // 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
|
327 static int af_open(af_instance_t* af){ |
7568 | 328 af->control=control; |
329 af->uninit=uninit; | |
330 af->play=play; | |
24888 | 331 af->mul=1; |
7568 | 332 af->data=calloc(1,sizeof(af_data_t)); |
333 if(af->data == NULL) | |
334 return AF_ERROR; | |
335 return AF_OK; | |
336 } | |
337 | |
338 // Description of this filter | |
339 af_info_t af_info_format = { | |
340 "Sample format conversion", | |
341 "format", | |
342 "Anders", | |
343 "", | |
7615 | 344 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
|
345 af_open |
7568 | 346 }; |
8167 | 347 |
12478 | 348 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
|
349 #if HAVE_BIGENDIAN |
12478 | 350 return (((uint32_t)((uint8_t*)data)[3*pos])<<24) | |
351 (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | | |
352 (((uint32_t)((uint8_t*)data)[3*pos+2])<<8); | |
353 #else | |
354 return (((uint32_t)((uint8_t*)data)[3*pos])<<8) | | |
355 (((uint32_t)((uint8_t*)data)[3*pos+1])<<16) | | |
356 (((uint32_t)((uint8_t*)data)[3*pos+2])<<24); | |
357 #endif | |
358 } | |
359 | |
360 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
|
361 #if HAVE_BIGENDIAN |
12478 | 362 ((uint8_t*)data)[3*pos]=expanded_value>>24; |
363 ((uint8_t*)data)[3*pos+1]=expanded_value>>16; | |
364 ((uint8_t*)data)[3*pos+2]=expanded_value>>8; | |
365 #else | |
366 ((uint8_t*)data)[3*pos]=expanded_value>>8; | |
367 ((uint8_t*)data)[3*pos+1]=expanded_value>>16; | |
368 ((uint8_t*)data)[3*pos+2]=expanded_value>>24; | |
369 #endif | |
370 } | |
371 | |
8167 | 372 // Function implementations used by play |
373 static void endian(void* in, void* out, int len, int bps) | |
374 { | |
375 register int i; | |
376 switch(bps){ | |
377 case(2):{ | |
378 for(i=0;i<len;i++){ | |
12486 | 379 ((uint16_t*)out)[i]=bswap_16(((uint16_t*)in)[i]); |
8167 | 380 } |
381 break; | |
382 } | |
12478 | 383 case(3):{ |
384 register uint8_t s; | |
385 for(i=0;i<len;i++){ | |
386 s=((uint8_t*)in)[3*i]; | |
387 ((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
|
388 if (in != out) |
dbbc25ea6403
fix endian conversion for (curently unused) case where in buffer != out buffer
reimar
parents:
12478
diff
changeset
|
389 ((uint8_t*)out)[3*i+1]=((uint8_t*)in)[3*i+1]; |
12478 | 390 ((uint8_t*)out)[3*i+2]=s; |
391 } | |
392 break; | |
393 } | |
8167 | 394 case(4):{ |
395 for(i=0;i<len;i++){ | |
12486 | 396 ((uint32_t*)out)[i]=bswap_32(((uint32_t*)in)[i]); |
8167 | 397 } |
398 break; | |
399 } | |
400 } | |
401 } | |
402 | |
16664 | 403 static void si2us(void* data, int len, int bps) |
8167 | 404 { |
16664 | 405 register long i = -(len * bps); |
406 register uint8_t *p = &((uint8_t *)data)[len * bps]; | |
407 #if AF_FORMAT_NE == AF_FORMAT_LE | |
408 p += bps - 1; | |
409 #endif | |
410 if (len <= 0) return; | |
411 do { | |
412 p[i] ^= 0x80; | |
413 } while (i += bps); | |
8167 | 414 } |
415 | |
416 static void change_bps(void* in, void* out, int len, int inbps, int outbps) | |
417 { | |
418 register int i; | |
419 switch(inbps){ | |
420 case(1): | |
421 switch(outbps){ | |
422 case(2): | |
423 for(i=0;i<len;i++) | |
424 ((uint16_t*)out)[i]=((uint16_t)((uint8_t*)in)[i])<<8; | |
425 break; | |
12478 | 426 case(3): |
427 for(i=0;i<len;i++) | |
428 store24bit(out, i, ((uint32_t)((uint8_t*)in)[i])<<24); | |
429 break; | |
8167 | 430 case(4): |
431 for(i=0;i<len;i++) | |
432 ((uint32_t*)out)[i]=((uint32_t)((uint8_t*)in)[i])<<24; | |
433 break; | |
434 } | |
435 break; | |
436 case(2): | |
437 switch(outbps){ | |
438 case(1): | |
439 for(i=0;i<len;i++) | |
440 ((uint8_t*)out)[i]=(uint8_t)((((uint16_t*)in)[i])>>8); | |
441 break; | |
12478 | 442 case(3): |
443 for(i=0;i<len;i++) | |
444 store24bit(out, i, ((uint32_t)((uint16_t*)in)[i])<<16); | |
445 break; | |
8167 | 446 case(4): |
447 for(i=0;i<len;i++) | |
448 ((uint32_t*)out)[i]=((uint32_t)((uint16_t*)in)[i])<<16; | |
449 break; | |
450 } | |
451 break; | |
12478 | 452 case(3): |
453 switch(outbps){ | |
454 case(1): | |
455 for(i=0;i<len;i++) | |
456 ((uint8_t*)out)[i]=(uint8_t)(load24bit(in, i)>>24); | |
457 break; | |
458 case(2): | |
459 for(i=0;i<len;i++) | |
460 ((uint16_t*)out)[i]=(uint16_t)(load24bit(in, i)>>16); | |
461 break; | |
462 case(4): | |
463 for(i=0;i<len;i++) | |
464 ((uint32_t*)out)[i]=(uint32_t)load24bit(in, i); | |
465 break; | |
466 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
467 break; |
8167 | 468 case(4): |
469 switch(outbps){ | |
470 case(1): | |
471 for(i=0;i<len;i++) | |
472 ((uint8_t*)out)[i]=(uint8_t)((((uint32_t*)in)[i])>>24); | |
473 break; | |
474 case(2): | |
475 for(i=0;i<len;i++) | |
476 ((uint16_t*)out)[i]=(uint16_t)((((uint32_t*)in)[i])>>16); | |
477 break; | |
12478 | 478 case(3): |
479 for(i=0;i<len;i++) | |
480 store24bit(out, i, ((uint32_t*)in)[i]); | |
481 break; | |
8167 | 482 } |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
483 break; |
8167 | 484 } |
485 } | |
486 | |
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 static void float2int(float* in, void* out, int len, int bps) |
8167 | 488 { |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
489 float f; |
8167 | 490 register int i; |
491 switch(bps){ | |
492 case(1): | |
493 for(i=0;i<len;i++) | |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
494 ((int8_t *)out)[i] = av_clip_int8(lrintf(128.0 * in[i])); |
8167 | 495 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
496 case(2): |
8167 | 497 for(i=0;i<len;i++) |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
498 ((int16_t*)out)[i] = av_clip_int16(lrintf(32768.0 * in[i])); |
8167 | 499 break; |
12478 | 500 case(3): |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
501 for(i=0;i<len;i++){ |
33736
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
502 f = in[i] * 8388608; |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
503 store24bit(out, i, av_clip(lrintf(f), -1*(1<<23), (1<<23)-1) << 8); |
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
504 } |
12478 | 505 break; |
8167 | 506 case(4): |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
507 for(i=0;i<len;i++){ |
33736
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
508 f = in[i]; |
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
509 if (f <= -1.0) |
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
510 ((int32_t*)out)[i] = INT_MIN; |
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
511 else |
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
512 if (f >= 1.0)//no need to use corrected constant, rounding won't cause overflow |
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
513 ((int32_t*)out)[i] = INT_MAX; |
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
514 else |
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
515 ((int32_t*)out)[i] = lrintf(f*2147483648.0); |
a5a54c7a15ce
Fix the precision loss in float -> 32bit conversion case, introduced
iive
parents:
33723
diff
changeset
|
516 |
33723
6c8743e5fa30
Audio format conversion from float to int is not checked for overflow.
iive
parents:
30241
diff
changeset
|
517 } |
8167 | 518 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
519 } |
8167 | 520 } |
521 | |
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
|
522 static void int2float(void* in, float* out, int len, int bps) |
8167 | 523 { |
524 register int i; | |
525 switch(bps){ | |
526 case(1): | |
527 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
|
528 out[i]=(1.0/128.0)*((int8_t*)in)[i]; |
8167 | 529 break; |
530 case(2): | |
531 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
|
532 out[i]=(1.0/32768.0)*((int16_t*)in)[i]; |
8167 | 533 break; |
12478 | 534 case(3): |
535 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
|
536 out[i]=(1.0/2147483648.0)*((int32_t)load24bit(in, i)); |
12478 | 537 break; |
8167 | 538 case(4): |
539 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
|
540 out[i]=(1.0/2147483648.0)*((int32_t*)in)[i]; |
8167 | 541 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29049
diff
changeset
|
542 } |
8167 | 543 } |