1 /*
2 * Copyright (C) 2002 2003 2004 2005 2008 2009 2012, Magnus Hjorth
3 *
4 * This file is part of mhWaveEdit.
5 *
6 * mhWaveEdit is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * mhWaveEdit is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with mhWaveEdit; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21
22 /* FIXME: Endian-ness stuff! */
23 /* This piece of code is imported several times into dataformat.c. */
24
25 /* Macros that must be defined and are undefined at the end of this file:
26 * FTYPE - Floating point sample type
27 * OTYPE - Other floating-point sample type
28 * C_PCMxy_FLOAT, C_FLOAT_PCMxy - Conversion routine names
29 * PZMODE - Preserve-zero level mode
30 */
31
32 #define CASTU32(x) ((guint32)x)
33 #define CASTS32(x) ((gint32)x)
34
35 #define MUL(x,m) (((FTYPE)(x))*((FTYPE)(m)))
36 #define DIV(x,d) (((FTYPE)(x))/((FTYPE)(d)))
37 #define MULADD(x,m,a) (((FTYPE)(x))*((FTYPE)(m)) + ((FTYPE)(a)))
38 #define MULSUB(x,m,a) (((FTYPE)(x))*((FTYPE)(m)) - ((FTYPE)(a)))
39 #define SUBDIV(x,s,d) ((((FTYPE)(x)) - ((FTYPE)(s))) / ((FTYPE)(d)))
40 #define ADDDIV(x,s,d) ((((FTYPE)(x)) + ((FTYPE)(s))) / ((FTYPE)(d)))
41
42 #ifdef PZMODE
43
44 #define NORM8U(x) SUBDIV(x,128.0,127.0)
45 #define NORM8S(x) DIV(x,127.0)
46 #define UNNORM8U(x) MULADD(x,127.0,128.0)
47 #define UNNORM8S(x) MUL(x,127.0)
48
49 #define NORM16U(x) SUBDIV(x,32768.0,32767.0)
50 #define NORM16S(x) DIV(x,32767.0)
51 #define UNNORM16U(x) MULADD(x,32767.0,32768.0)
52 #define UNNORM16S(x) MUL(x,32767.0)
53
54 #define NORM24U(x) SUBDIV(x,8388608.0,8388607.0)
55 #define UNNORM24U(x) MULADD(x,8388607.0,8388608.0)
56 #define UNNORM24S(x) MUL(x,8388607.0)
57
58 #define NORM32U(x) SUBDIV(x,2147483648.0,2147483647.0)
59 #define NORM32S(x) DIV(x,2147483647.0)
60 #define UNNORM32U(x) MULADD(x,2147483647.0,2147483648.0)
61 #define UNNORM32S(x) MUL(x,2147483647.0)
62
63 #undef PZMODE
64
65 #else
66
67 #define NORM8U(x) SUBDIV(x,127.5,127.5)
68 #define NORM8S(x) ADDDIV(x,0.5,127.5)
69 #define UNNORM8U(x) MULADD(x,127.5,127.5)
70 #define UNNORM8S(x) MULSUB(x,127.5,0.5)
71
72 #define NORM16U(x) SUBDIV(x,32767.5,32767.5)
73 #define NORM16S(x) ADDDIV(x,0.5,32767.5)
74 #define UNNORM16U(x) MULADD(x,32767.5,32767.5)
75 #define UNNORM16S(x) MULSUB(x,32767.5,0.5)
76
77 #define NORM24U(x) SUBDIV(x,8388607.5,8388607.5)
78 #define UNNORM24U(x) MULADD(x,8388607.5,8388607.5)
79 #define UNNORM24S(x) MULSUB(x,8388607.5,0.5)
80
81 #define NORM32U(x) SUBDIV(x,2147483647.5,2147483647.5)
82 #define NORM32S(x) ADDDIV(x,0.5,2147483647.5)
83 #define UNNORM32S(x) MULSUB(x,2147483647.5,0.5)
84
85 #endif /* ifdef PZMODE */
86
87 #if IS_BIGENDIAN == TRUE
88
89 #define C_PCM16SNE_FLOAT C_PCM16SBE_FLOAT
90 #define C_PCM16UNE_FLOAT C_PCM16UBE_FLOAT
91 #define C_PCM32SNE_FLOAT C_PCM32SBE_FLOAT
92 #define C_PCM32UNE_FLOAT C_PCM32UBE_FLOAT
93 #define C_PCM24SNEPM_FLOAT C_PCM24SBEPM_FLOAT
94 #define C_PCM24UNEPM_FLOAT C_PCM24UBEPM_FLOAT
95 #define C_PCM24SNEPL_FLOAT C_PCM24SBEPL_FLOAT
96 #define C_PCM24UNEPL_FLOAT C_PCM24UBEPL_FLOAT
97
98 #define C_PCM16SOE_FLOAT C_PCM16SLE_FLOAT
99 #define C_PCM16UOE_FLOAT C_PCM16ULE_FLOAT
100 #define C_PCM32SOE_FLOAT C_PCM32SLE_FLOAT
101 #define C_PCM32UOE_FLOAT C_PCM32ULE_FLOAT
102 #define C_PCM24SOEPM_FLOAT C_PCM24SLEPM_FLOAT
103 #define C_PCM24UOEPM_FLOAT C_PCM24ULEPM_FLOAT
104 #define C_PCM24SOEPL_FLOAT C_PCM24SLEPL_FLOAT
105 #define C_PCM24UOEPL_FLOAT C_PCM24ULEPL_FLOAT
106
107 #define C_FLOAT_PCM16SNE C_FLOAT_PCM16SBE
108 #define C_FLOAT_PCM16UNE C_FLOAT_PCM16UBE
109 #define C_FLOAT_PCM32SNE C_FLOAT_PCM32SBE
110 #define C_FLOAT_PCM32UNE C_FLOAT_PCM32UBE
111 #define C_FLOAT_PCM24SNEPM C_FLOAT_PCM32SBEPM
112 #define C_FLOAT_PCM24UNEPM C_FLOAT_PCM32UBEPM
113 #define C_FLOAT_PCM24SNEPL C_FLOAT_PCM32SBEPL
114 #define C_FLOAT_PCM24UNEPL C_FLOAT_PCM32UBEPL
115
116 #define C_FLOAT_PCM16SOE C_FLOAT_PCM16SLE
117 #define C_FLOAT_PCM16UOE C_FLOAT_PCM16ULE
118 #define C_FLOAT_PCM32SOE C_FLOAT_PCM32SLE
119 #define C_FLOAT_PCM32UOE C_FLOAT_PCM32ULE
120 #define C_FLOAT_PCM24SOE C_FLOAT_PCM24SLEPM
121 #define C_FLOAT_PCM24UOE C_FLOAT_PCM24ULEPM
122 #define C_FLOAT_PCM24SOE C_FLOAT_PCM24SLEPL
123 #define C_FLOAT_PCM24UOE C_FLOAT_PCM24ULEPL
124
C_PCM24SLE_FLOAT(guint32 * in,FTYPE * out,int count)125 static void C_PCM24SLE_FLOAT(guint32 *in, FTYPE *out, int count)
126 {
127 unsigned long l0,l1,l2,m;
128 unsigned char *c;
129 for (; count>4; count-=4,in+=3,out+=4) {
130 l0 = in[0]; /* d00 d01 d02 d10 */
131 l1 = in[1]; /* d11 d12 d20 d21 */
132 l2 = in[2]; /* d22 d30 d31 d32 */
133 m = ((l0<<8) & 0xFF0000) + ((l0>>8) & 0xFF00) + (l0>>24);
134 m = (m+0x800000) & 0xFFFFFF; /* signed -> unsigned */
135 out[0] = NORM24U(m);
136 m = (l0 & 0xFF) + ((l1 >> 16) & 0xFF00) + (l1 & 0xFF0000);
137 m = (m+0x800000) & 0xFFFFFF;
138 out[1] = NORM24U(m);
139 m = ((l1<<8) & 0xFF00) + ((l1>>8) & 0xFF) + ((l2>>8) & 0xFF0000);
140 m = (m+0x800000) & 0xFFFFFF;
141 out[2] = NORM24U(m);
142 m = (l2 << 16) + (l2 & 0xFF00) + ((l2>>16) & 0xFF);
143 m = (m+0x800000) & 0xFFFFFF;
144 out[3] = NORM24U(m);
145 }
146 c = (unsigned char *)in;
147 for (; count>0; count--,c+=3,out++) {
148 l0 = c[0];
149 l1 = c[1];
150 l2 = c[2];
151 m = l0 + (l1<<8) + (l2<<16);
152 m = (m+0x800000) & 0xFFFFFF;
153 *out = NORM24U(m);
154 }
155 }
156
C_PCM24SBE_FLOAT(guint32 * in,FTYPE * out,int count)157 static void C_PCM24SBE_FLOAT(guint32 *in, FTYPE *out, int count)
158 {
159 unsigned long l0,l1,l2,m;
160 unsigned char *c;
161 for (; count>4; count-=4,in+=3,out+=4) {
162 l0 = in[0]; /* d02 d01 d00 d12 */
163 l1 = in[1]; /* d11 d10 d22 d21 */
164 l2 = in[2]; /* d20 d32 d31 d30 */
165 m = l0 >> 8;
166 m = (m+0x800000) & 0xFFFFFF; /* signed -> unsigned */
167 out[0] = NORM24U(m);
168 m = (l0 << 16) + (l1 >> 16);
169 m = (m+0x800000) & 0xFFFFFF;
170 out[1] = NORM24U(m);
171 m = (l1<<8) + (l2>>24);
172 m = (m+0x800000) & 0xFFFFFF;
173 out[2] = NORM24U(m);
174 m = ((l2 << 16) & 0xFF0000) + (l2 & 0xFF00) + ((l2>>16) & 0xFF);
175 m = (m+0x800000) & 0xFFFFFF;
176 out[3] = NORM24U(m);
177 }
178 c = (unsigned char *)in;
179 for (; count>0; count--,c+=3,out++) {
180 l0 = c[0];
181 l1 = c[1];
182 l2 = c[2];
183 m = (l0<<16) + (l1<<8) + l2;
184 m = (m+0x800000) & 0xFFFFFF;
185 *out = NORM24U(m);
186 }
187 }
188
C_PCM24ULE_FLOAT(guint32 * in,FTYPE * out,int count)189 static void C_PCM24ULE_FLOAT(guint32 *in, FTYPE *out, int count)
190 {
191 unsigned long l0,l1,l2,m;
192 unsigned char *c;
193 for (; count>4; count-=4,in+=3,out+=4) {
194 l0 = in[0]; /* d00 d01 d02 d10 */
195 l1 = in[1]; /* d11 d12 d20 d21 */
196 l2 = in[2]; /* d22 d30 d31 d32 */
197 m = ((l0<<8) & 0xFF0000) + ((l0>>8) & 0xFF00) + (l0>>24);
198 out[0] = NORM24U(m);
199 m = (l0 & 0xFF) + ((l1 >> 16) & 0xFF00) + (l1 & 0xFF0000);
200 out[1] = NORM24U(m);
201 m = ((l1<<8) & 0xFF00) + ((l1>>8) & 0xFF) + ((l2>>8) & 0xFF0000);
202 out[2] = NORM24U(m);
203 m = ((l2 << 16) & 0xFF0000) + (l2 & 0xFF00) + ((l2>>16) & 0xFF);
204 out[3] = NORM24U(m);
205 }
206 c = (unsigned char *)in;
207 for (; count>0; count--,c+=3,out++) {
208 l0 = c[0];
209 l1 = c[1];
210 l2 = c[2];
211 m = l0 + (l1<<8) + (l2<<16);
212 *out = NORM24U(m);
213 }
214 }
215
C_PCM24UBE_FLOAT(guint32 * in,FTYPE * out,int count)216 static void C_PCM24UBE_FLOAT(guint32 *in, FTYPE *out, int count)
217 {
218 unsigned long l0,l1,l2,m;
219 unsigned char *c;
220 for (; count>4; count-=4,in+=3,out+=4) {
221 l0 = in[0]; /* d02 d01 d00 d12 */
222 l1 = in[1]; /* d11 d10 d22 d21 */
223 l2 = in[2]; /* d20 d32 d31 d30 */
224 m = l0 >> 8;
225 out[0] = NORM24U(m);
226 m = ((l0 << 16) & 0xFF0000) + (l1 >> 16);
227 out[1] = NORM24U(m);
228 m = ((l1<<8) & 0xFFFF00) + (l2>>24);
229 out[2] = NORM24U(m);
230 m = ((l2 << 16) & 0xFF0000) + (l2 & 0xFF00) + ((l2>>16) & 0xFF);
231 out[3] = NORM24U(m);
232 }
233 c = (unsigned char *)in;
234 for (; count>0; count--,c+=3,out++) {
235 l0 = c[0];
236 l1 = c[1];
237 l2 = c[2];
238 m = (l0<<16) + (l1<<8) + l2;
239 *out = NORM24U(m);
240 }
241 }
242
243 #else
244
245 #define C_PCM16SNE_FLOAT C_PCM16SLE_FLOAT
246 #define C_PCM16UNE_FLOAT C_PCM16ULE_FLOAT
247 #define C_PCM32SNE_FLOAT C_PCM32SLE_FLOAT
248 #define C_PCM32UNE_FLOAT C_PCM32ULE_FLOAT
249 #define C_PCM24SNEPM_FLOAT C_PCM24SLEPM_FLOAT
250 #define C_PCM24UNEPM_FLOAT C_PCM24ULEPM_FLOAT
251 #define C_PCM24SNEPL_FLOAT C_PCM24SLEPL_FLOAT
252 #define C_PCM24UNEPL_FLOAT C_PCM24ULEPL_FLOAT
253
254 #define C_PCM16SOE_FLOAT C_PCM16SBE_FLOAT
255 #define C_PCM16UOE_FLOAT C_PCM16UBE_FLOAT
256 #define C_PCM32SOE_FLOAT C_PCM32SBE_FLOAT
257 #define C_PCM32UOE_FLOAT C_PCM32UBE_FLOAT
258 #define C_PCM24SOEPM_FLOAT C_PCM24SBEPM_FLOAT
259 #define C_PCM24UOEPM_FLOAT C_PCM24UBEPM_FLOAT
260 #define C_PCM24SOEPL_FLOAT C_PCM24SBEPL_FLOAT
261 #define C_PCM24UOEPL_FLOAT C_PCM24UBEPL_FLOAT
262
263 #define C_FLOAT_PCM16SNE C_FLOAT_PCM16SLE
264 #define C_FLOAT_PCM16UNE C_FLOAT_PCM16ULE
265 #define C_FLOAT_PCM32SNE C_FLOAT_PCM32SLE
266 #define C_FLOAT_PCM32UNE C_FLOAT_PCM32ULE
267 #define C_FLOAT_PCM24SNEPM C_FLOAT_PCM24SLEPM
268 #define C_FLOAT_PCM24UNEPM C_FLOAT_PCM24ULEPM
269 #define C_FLOAT_PCM24SNEPL C_FLOAT_PCM24SLEPL
270 #define C_FLOAT_PCM24UNEPL C_FLOAT_PCM24ULEPL
271
272 #define C_FLOAT_PCM16SOE C_FLOAT_PCM16SBE
273 #define C_FLOAT_PCM16UOE C_FLOAT_PCM16UBE
274 #define C_FLOAT_PCM32SOE C_FLOAT_PCM32SBE
275 #define C_FLOAT_PCM32UOE C_FLOAT_PCM32UBE
276 #define C_FLOAT_PCM24SOEPM C_FLOAT_PCM24SBEPM
277 #define C_FLOAT_PCM24UOEPM C_FLOAT_PCM24UBEPM
278 #define C_FLOAT_PCM24SOEPL C_FLOAT_PCM24SBEPL
279 #define C_FLOAT_PCM24UOEPL C_FLOAT_PCM24UBEPL
280
C_PCM24SLE_FLOAT(guint32 * in,FTYPE * out,int count)281 static void C_PCM24SLE_FLOAT(guint32 *in, FTYPE *out, int count)
282 {
283 unsigned long l0,l1,l2,m;
284 unsigned char *c;
285 for (; count>4; count-=4,in+=3,out+=4) {
286 l0 = in[0]; /* d10 d02 d01 d00 */
287 l1 = in[1]; /* d21 d20 d12 d11 */
288 l2 = in[2]; /* d32 d31 d30 d22 */
289 m = l0;
290 m = (m+0x800000) & 0xFFFFFF; /* signed -> unsigned */
291 out[0] = NORM24U(m);
292 m = (l0 >> 24) + (l1 << 8);
293 m = (m+0x800000) & 0xFFFFFF;
294 out[1] = NORM24U(m);
295 m = (l1 >> 16) + (l2 << 16);
296 m = (m+0x800000) & 0xFFFFFF;
297 out[2] = NORM24U(m);
298 m = (l2 >> 8);
299 m = (m+0x800000) & 0xFFFFFF;
300 out[3] = NORM24U(m);
301 }
302 c = (unsigned char *)in;
303 for (; count>0; count--,c+=3,out++) {
304 l0 = c[0];
305 l1 = c[1];
306 l2 = c[2];
307 m = l0 + (l1<<8) + (l2<<16);
308 m = (m+0x800000) & 0xFFFFFF;
309 *out = NORM24U(m);
310 }
311 }
312
C_PCM24SBE_FLOAT(guint32 * in,FTYPE * out,int count)313 static void C_PCM24SBE_FLOAT(guint32 *in, FTYPE *out, int count)
314 {
315 unsigned long l0,l1,l2,m;
316 unsigned char *c;
317 for (; count>4; count-=4,in+=3,out+=4) {
318 l0 = in[0]; /* d12 d00 d01 d02 */
319 l1 = in[1]; /* d21 d22 d10 d11 */
320 l2 = in[2]; /* d30 d31 d32 d20 */
321 m = (l0 << 16) + (l0 & 0xFF00) + ((l0 >> 16) & 0xFF);
322 m = (m+0x800000) & 0xFFFFFF; /* signed -> unsigned */
323 out[0] = NORM24U(m);
324 m = ((l0>>8) & 0xFF0000) + ((l1<<8) & 0xFF00) + ((l1>>8) & 0xFF);
325 m = (m+0x800000) & 0xFFFFFF;
326 out[1] = NORM24U(m);
327 m = (l1 & 0xFF0000) + ((l1>>16) & 0xFF00) + (l2 & 0xFF);
328 m = (m+0x800000) & 0xFFFFFF;
329 out[2] = NORM24U(m);
330 m = ((l2 << 8) & 0xFF0000) + ((l2>>8) & 0xFF00) + ((l2>>24) & 0xFF);
331 m = (m+0x800000) & 0xFFFFFF;
332 out[3] = NORM24U(m);
333 }
334 c = (unsigned char *)in;
335 for (; count>0; count--,c+=3,out++) {
336 l0 = c[0];
337 l1 = c[1];
338 l2 = c[2];
339 m = (l0<<16) + (l1<<8) + l2;
340 m = (m+0x800000) & 0xFFFFFF;
341 *out = NORM24U(m);
342 }
343 }
344
345
C_PCM24ULE_FLOAT(guint32 * in,FTYPE * out,int count)346 static void C_PCM24ULE_FLOAT(guint32 *in, FTYPE *out, int count)
347 {
348 unsigned long l0,l1,l2,m;
349 unsigned char *c;
350 for (; count>4; count-=4,in+=3,out+=4) {
351 l0 = in[0]; /* d10 d02 d01 d00 */
352 l1 = in[1]; /* d21 d20 d12 d11 */
353 l2 = in[2]; /* d32 d31 d30 d22 */
354 m = l0 & 0xFFFFFF;
355 out[0] = NORM24U(m);
356 m = (l0 >> 24) + ((l1 << 8) & 0xFFFF00);
357 out[1] = NORM24U(m);
358 m = (l1 >> 16) + ((l2 << 16) & 0xFF0000);
359 out[2] = NORM24U(m);
360 m = (l2 >> 8);
361 out[3] = NORM24U(m);
362 }
363 c = (unsigned char *)in;
364 for (; count>0; count--,c+=3,out++) {
365 l0 = c[0];
366 l1 = c[1];
367 l2 = c[2];
368 m = l0 + (l1<<8) + (l2<<16);
369 *out = NORM24U(m);
370 }
371 }
372
C_PCM24UBE_FLOAT(guint32 * in,FTYPE * out,int count)373 static void C_PCM24UBE_FLOAT(guint32 *in, FTYPE *out, int count)
374 {
375 unsigned long l0,l1,l2,m;
376 unsigned char *c;
377 for (; count>4; count-=4,in+=3,out+=4) {
378 l0 = in[0]; /* d12 d00 d01 d02 */
379 l1 = in[1]; /* d21 d22 d10 d11 */
380 l2 = in[2]; /* d30 d31 d32 d20 */
381 m = ((l0 << 16) & 0xFF0000) + (l0 & 0xFF00) + ((l0 >> 16) & 0xFF);
382 out[0] = NORM24U(m);
383 m = ((l0>>8) & 0xFF0000) + ((l1<<8) & 0xFF00) + ((l1>>8) & 0xFF);
384 out[1] = NORM24U(m);
385 m = (l1 & 0xFF0000) + ((l1>>16) & 0xFF00) + (l2 & 0xFF);
386 out[2] = NORM24U(m);
387 m = ((l2 << 8) & 0xFF0000) + ((l2>>8) & 0xFF00) + ((l2>>24) & 0xFF);
388 out[3] = NORM24U(m);
389 }
390 c = (unsigned char *)in;
391 for (; count>0; count--,c+=3,out++) {
392 l0 = c[0];
393 l1 = c[1];
394 l2 = c[2];
395 m = (l0<<16) + (l1<<8) + l2;
396 *out = NORM24U(m);
397 }
398 }
399
400 #endif
401
402
403
C_PCM8S_FLOAT(signed char * in,FTYPE * out,int count)404 static void C_PCM8S_FLOAT(signed char *in, FTYPE *out, int count)
405 {
406 for (; count>0; count--,in++,out++)
407 *out = NORM8S(*in);
408 }
409
C_PCM8U_FLOAT(unsigned char * in,FTYPE * out,int count)410 static void C_PCM8U_FLOAT(unsigned char *in, FTYPE *out, int count)
411 {
412 for (; count>0; count--,in++,out++)
413 *out = NORM8U(*in);
414 }
415
C_PCM16SNE_FLOAT(signed short * in,FTYPE * out,int count)416 static void C_PCM16SNE_FLOAT(signed short *in, FTYPE *out, int count)
417 {
418 /* puts("HELLO!"); */
419 for (; count>0; count--,in++,out++)
420 *out = NORM16S(*in);
421 }
422
C_PCM16SOE_FLOAT(unsigned short * in,FTYPE * out,int count)423 static void C_PCM16SOE_FLOAT(unsigned short *in, FTYPE *out, int count)
424 {
425 unsigned short u;
426 signed short i;
427 for (; count>0; count--,in++,out++) {
428 u = *in;
429 i = (u >> 8) + (u << 8);
430 *out = NORM16S(i);
431 }
432 }
433
C_PCM16UNE_FLOAT(unsigned short * in,FTYPE * out,int count)434 static void C_PCM16UNE_FLOAT(unsigned short *in, FTYPE *out, int count)
435 {
436 for (; count>0; count--,in++,out++)
437 *out = NORM16U(*in);
438 }
439
C_PCM16UOE_FLOAT(unsigned short * in,FTYPE * out,int count)440 static void C_PCM16UOE_FLOAT(unsigned short *in, FTYPE *out, int count)
441 {
442 unsigned short i;
443 for (; count>0; count--,in++,out++) {
444 i = *in;
445 i = (i >> 8) + (i << 8);
446 *out = NORM16U(i);
447 }
448 }
449
C_PCM32SNE_FLOAT(gint32 * in,FTYPE * out,int count)450 static void C_PCM32SNE_FLOAT(gint32 *in, FTYPE *out, int count)
451 {
452 for (; count>0; count--,in++,out++)
453 *out = NORM32S(*in);
454 }
455
C_PCM32SOE_FLOAT(guint32 * in,FTYPE * out,int count)456 static void C_PCM32SOE_FLOAT(guint32 *in, FTYPE *out, int count)
457 {
458 guint32 u;
459 guint32 x;
460 gint32 i;
461 /* g_assert(sizeof(u) == 4 && sizeof(x) == 4 && sizeof(i) == 4); */
462 for (; count>0; count--,in++,out++) {
463 u = *in;
464 x = (u<<CASTU32(24)) + ((u<<CASTU32(8)) & CASTU32(0xFF0000)) +
465 ((u>>CASTU32(8)) & CASTU32(0xFF00)) + (u>>CASTU32(24));
466 i = (gint32)x;
467 *out = NORM32S(i);
468 }
469 }
470
C_PCM32UNE_FLOAT(guint32 * in,FTYPE * out,int count)471 static void C_PCM32UNE_FLOAT(guint32 *in, FTYPE *out, int count)
472 {
473 #ifdef FTYPE_IS_FLOAT
474 gint32 x;
475 for (; count>0; count--,in++,out++) {
476 x = (gint32)(*in ^ 0x80000000);
477 *out = NORM32S(x);
478 }
479 #else
480 for (; count>0; count--,in++,out++)
481 *out = NORM32U(*in);
482 #endif
483 }
484
C_PCM32UOE_FLOAT(guint32 * in,FTYPE * out,int count)485 static void C_PCM32UOE_FLOAT(guint32 *in, FTYPE *out, int count)
486 {
487 #ifdef FTYPE_IS_FLOAT
488 guint32 i,x;
489 gint32 xi;
490 for (; count>0; count--,in++,out++) {
491 i = *in;
492 x = (i<<CASTU32(24)) + ((i<<CASTU32(8)) & CASTU32(0xFF0000)) +
493 ((i>>CASTU32(8)) & CASTU32(0xFF00)) + (i>>CASTU32(24));
494 xi = (gint32)(x ^ 0x80000000);
495 *out = NORM32S(xi);
496 }
497 #else
498 guint32 i,x;
499 for (; count>0; count--,in++,out++) {
500 i = *in;
501 x = (i<<CASTU32(24)) + ((i<<CASTU32(8)) & CASTU32(0xFF0000)) +
502 ((i>>CASTU32(8)) & CASTU32(0xFF00)) + (i>>CASTU32(24));
503
504 *out = NORM32U(x);
505 }
506 #endif
507 }
508
C_PCM24SNEPM_FLOAT(guint32 * in,FTYPE * out,int count)509 static void C_PCM24SNEPM_FLOAT(guint32 *in, FTYPE *out, int count)
510 {
511 unsigned long l;
512 for (; count>0; count--,in++,out++) {
513 l = (*in >> 8) ^ 0x800000;
514 *out = NORM24U(l);
515 }
516 }
517
C_PCM24SOEPM_FLOAT(guint32 * in,FTYPE * out,int count)518 static void C_PCM24SOEPM_FLOAT(guint32 *in, FTYPE *out, int count)
519 {
520 guint32 i,x;
521 for (; count>0; count--,in++,out++) {
522 i = *in;
523 x = ((i << 16) & 0xFF0000) | (i & 0xFF00) | ((i >> 16) & 0xFF);
524 x ^= 0x800000;
525 *out = NORM24U(x);
526 }
527 }
528
C_PCM24UNEPM_FLOAT(guint32 * in,FTYPE * out,int count)529 static void C_PCM24UNEPM_FLOAT(guint32 *in, FTYPE *out, int count)
530 {
531 unsigned long l;
532 for (; count>0; count--,in++,out++) {
533 l = *in >> 8;
534 *out = NORM24U(l);
535 }
536 }
537
C_PCM24UOEPM_FLOAT(guint32 * in,FTYPE * out,int count)538 static void C_PCM24UOEPM_FLOAT(guint32 *in, FTYPE *out, int count)
539 {
540 guint32 i,x;
541 for (; count>0; count--,in++,out++) {
542 i = *in;
543 x = ((i << 16) & 0xFF0000) | (i & 0xFF00) | ((i >> 16) & 0xFF);
544 *out = NORM24U(x);
545 }
546 }
547
C_PCM24SNEPL_FLOAT(guint32 * in,FTYPE * out,int count)548 static void C_PCM24SNEPL_FLOAT(guint32 *in, FTYPE *out, int count)
549 {
550 unsigned long l;
551 for (; count>0; count--,in++,out++) {
552 l = (*in & 0xFFFFFF) ^ 0x800000;
553 *out = NORM24U(l);
554 }
555 }
556
C_PCM24SOEPL_FLOAT(guint32 * in,FTYPE * out,int count)557 static void C_PCM24SOEPL_FLOAT(guint32 *in, FTYPE *out, int count)
558 {
559 guint32 i,x;
560 for (; count>0; count--,in++,out++) {
561 i = *in;
562 x = ((i << 8) & 0xFF0000) | ((i >> 8) & 0xFF00) | ((i >> 24) & 0xFF);
563 x ^= 0x800000;
564 *out = NORM24U(x);
565 }
566 }
567
C_PCM24UNEPL_FLOAT(guint32 * in,FTYPE * out,int count)568 static void C_PCM24UNEPL_FLOAT(guint32 *in, FTYPE *out, int count)
569 {
570 unsigned long l;
571 for (; count>0; count--,in++,out++) {
572 l = *in & 0xFFFFFF;
573 *out = NORM24U(l);
574 }
575 }
576
C_PCM24UOEPL_FLOAT(guint32 * in,FTYPE * out,int count)577 static void C_PCM24UOEPL_FLOAT(guint32 *in, FTYPE *out, int count)
578 {
579 guint32 i,x;
580 for (; count>0; count--,in++,out++) {
581 i = *in;
582 x = ((i << 8) & 0xFF0000) | ((i >> 8) & 0xFF00) | ((i >> 24) & 0xFF);
583 *out = NORM24U(x);
584 }
585 }
586
C_FLOAT_PCM8S(FTYPE * in,signed char * out,int count)587 static int C_FLOAT_PCM8S(FTYPE *in, signed char *out, int count)
588 {
589 long int l;
590 int cc=0;
591 FTYPE f;
592 for (; count>0; count--,in++,out++) {
593 f = *in;
594 l = RINT(UNNORM8S(f));
595 if (l > 127 || f > 2.0) { l = 127; cc++; } else if (l < -128 || f < -2.0) { l = -128; cc++; }
596 *out = l;
597 }
598 return cc;
599 }
600
C_FLOAT_PCM8U(FTYPE * in,unsigned char * out,int count)601 static int C_FLOAT_PCM8U(FTYPE *in, unsigned char *out, int count)
602 {
603 long int l;
604 int cc=0;
605 FTYPE f;
606 for (; count>0; count--,in++,out++) {
607 f = *in;
608 l = RINT(UNNORM8U(f));
609 if (l > 255 || f > 2.0) { l = 255; cc++; } else if (l < 0 || f < -2.0) { l = 0; cc++; }
610 *out = l;
611 }
612 return cc;
613 }
614
C_FLOAT_PCM16SNE(FTYPE * in,signed short * out,int count)615 static int C_FLOAT_PCM16SNE(FTYPE *in, signed short *out, int count)
616 {
617 long int l;
618 int cc=0;
619 FTYPE f;
620 for (; count>0; count--,in++,out++) {
621 f = *in;
622 l = RINT(UNNORM16S(f));
623 if (l > 32767 || f > 2.0) { l = 32767; cc++; } else if (l < -32768 || f < -2.0) { l=-32768; cc++; }
624 *out = l;
625 }
626 return cc;
627 }
628
C_FLOAT_PCM16SOE(FTYPE * in,signed short * out,int count)629 static int C_FLOAT_PCM16SOE(FTYPE *in, signed short *out, int count)
630 {
631 int i;
632 i = C_FLOAT_PCM16SNE(in,out,count);
633 byteswap(out,2,count*2);
634 return i;
635 }
636
C_FLOAT_PCM16UNE(FTYPE * in,unsigned short * out,int count)637 static int C_FLOAT_PCM16UNE(FTYPE *in, unsigned short *out, int count)
638 {
639 long int l;
640 int cc=0;
641 FTYPE f;
642 for (; count>0; count--,in++,out++) {
643 f = *in;
644 l = RINT(UNNORM16U(f));
645 if (l > 65535 || f > 2.0) { l = 65535; cc++; } else if (l < 0 || f < -2.0) { l = 0; cc++; }
646 *out = l;
647 }
648 return cc;
649 }
650
C_FLOAT_PCM16UOE(FTYPE * in,unsigned short * out,int count)651 static int C_FLOAT_PCM16UOE(FTYPE *in, unsigned short *out, int count)
652 {
653 int i;
654 i = C_FLOAT_PCM16UNE(in,out,count);
655 byteswap(out,2,count*2);
656 return i;
657 }
658
C_FLOAT_PCM24SLE(FTYPE * in,unsigned char * out,int count)659 static int C_FLOAT_PCM24SLE(FTYPE *in, unsigned char *out, int count)
660 {
661 long int l;
662 int cc=0;
663 FTYPE f;
664 for (; count>0; count--,in++,out+=3) {
665 f = *in;
666 l = RINT(UNNORM24S(f));
667 if (l > 0x7FFFFF || f > 2.0) { l = 0x7FFFFF; cc++; }
668 else if (l < -0x800000 || f < -2.0) { l = -0x800000; cc++; }
669 out[0] = l & 0xFF;
670 out[1] = (l & 0xFF00) >> 8;
671 out[2] = (l & 0xFF0000) >> 16;
672 }
673 return cc;
674 }
675
C_FLOAT_PCM24SBE(FTYPE * in,unsigned char * out,int count)676 static int C_FLOAT_PCM24SBE(FTYPE *in, unsigned char *out, int count)
677 {
678 long int l;
679 int cc=0;
680 FTYPE f;
681 for (; count>0; count--,in++,out+=3) {
682 f = *in;
683 l = RINT(UNNORM24S(f));
684 if (l > 0x7FFFFF || f > 2.0) { l = 0x7FFFFF; cc++; }
685 else if (l < -0x800000 || f < -2.0) { l = -0x800000; cc++; }
686 out[0] = (l & 0xFF0000) >> 16;
687 out[1] = (l & 0xFF00) >> 8;
688 out[2] = l & 0xFF;
689 }
690 return cc;
691 }
692
C_FLOAT_PCM24ULE(FTYPE * in,unsigned char * out,int count)693 static int C_FLOAT_PCM24ULE(FTYPE *in, unsigned char *out, int count)
694 {
695 long int l;
696 int cc=0;
697 FTYPE f;
698 for (; count>0; count--,in++,out+=3) {
699 f = *in;
700 l = RINT(UNNORM24U(f));
701 if (l > 0xFFFFFF || f > 2.0) { l = 0xFFFFFF; cc++; } else if (l < 0 || f < -2.0) { l = 0; cc++; }
702 out[0] = l & 0xFF;
703 out[1] = (l & 0xFF00) >> 8;
704 out[2] = (l & 0xFF0000) >> 16;
705 }
706 return cc;
707 }
708
C_FLOAT_PCM24UBE(FTYPE * in,unsigned char * out,int count)709 static int C_FLOAT_PCM24UBE(FTYPE *in, unsigned char *out, int count)
710 {
711 long int l;
712 int cc=0;
713 FTYPE f;
714 for (; count>0; count--,in++,out+=3) {
715 f = *in;
716 l = RINT(UNNORM24U(f));
717 if (l > 0xFFFFFF || f > 2.0) { l = 0xFFFFFF; cc++; } else if (l < 0 || f < -2.0) { l = 0; cc++; }
718 out[0] = (l & 0xFF0000) >> 16;
719 out[1] = (l & 0xFF00) >> 8;
720 out[2] = l & 0xFF;
721 }
722 return cc;
723 }
724
C_FLOAT_PCM32SNE(FTYPE * in,gint32 * out,int count)725 static int C_FLOAT_PCM32SNE(FTYPE *in, gint32 *out, int count)
726 {
727 FTYPE f;
728 gint32 i;
729 int cc=0;
730 for (; count>0; count--,in++,out++) {
731 f = *in;
732 i = RINT(UNNORM32S(f));
733 if (f > 1.25 || (f >= 1.0 && i<0x7FFFFFFF)) { i = 0x7FFFFFFF; cc++; }
734 else if (f < -1.25 || (f <= -1.0 && i>-0x7FFFFFFF)) { i = -0x80000000; cc++; }
735 *out = i;
736 }
737 return cc;
738 }
739
C_FLOAT_PCM32SOE(FTYPE * in,gint32 * out,int count)740 static int C_FLOAT_PCM32SOE(FTYPE *in, gint32 *out, int count)
741 {
742 int i;
743 i = C_FLOAT_PCM32SNE(in,out,count);
744 byteswap(out,4,count*4);
745 return i;
746 }
747
C_FLOAT_PCM32UNE(FTYPE * in,guint32 * out,int count)748 static int C_FLOAT_PCM32UNE(FTYPE *in, guint32 *out, int count)
749 {
750 FTYPE f;
751 gint32 i;
752 int cc=0;
753 for (; count>0; count--,in++,out++) {
754 f = *in;
755 i = RINT(UNNORM32S(f));
756 if (f > 1.25 || (f >= 1.0 && i<0x7FFFFFFF)) { i = 0x7FFFFFFF; cc++; }
757 else if (f < -1.25 || (f <= -1.0 && i>-0x7FFFFFFF)) { i = -0x80000000; cc++; }
758 *out = (guint32)i ^ 0x80000000;
759 }
760 return cc;
761 }
762
C_FLOAT_PCM32UOE(FTYPE * in,guint32 * out,int count)763 static int C_FLOAT_PCM32UOE(FTYPE *in, guint32 *out, int count)
764 {
765 int i;
766 i = C_FLOAT_PCM32UNE(in,out,count);
767 byteswap(out,4,count*4);
768 return i;
769 }
770
C_FLOAT_PCM24SNEPM(FTYPE * in,guint32 * out,int count)771 static int C_FLOAT_PCM24SNEPM(FTYPE *in, guint32 *out, int count)
772 {
773 long l;
774 int cc=0;
775 FTYPE f;
776 for (; count>0; count--,in++,out++) {
777 f = *in;
778 l = RINT(UNNORM24S(f));
779 if (l > 0x7FFFFF || f > 2.0) { l = 0x7FFFFF; cc++; }
780 else if (l < -0x800000 || f < -2.0) { l = -0x800000; cc++; }
781 *out = l << 8;
782 }
783 return cc;
784 }
785
C_FLOAT_PCM24SOEPM(FTYPE * in,guint32 * out,int count)786 static int C_FLOAT_PCM24SOEPM(FTYPE *in, guint32 *out, int count)
787 {
788 int i;
789 i = C_FLOAT_PCM24SNEPM(in,out,count);
790 byteswap(out,4,count*4);
791 return i;
792 }
793
C_FLOAT_PCM24UNEPM(FTYPE * in,guint32 * out,int count)794 static int C_FLOAT_PCM24UNEPM(FTYPE *in, guint32 *out, int count)
795 {
796 unsigned long l;
797 int cc=0;
798 FTYPE f;
799 for (; count>0; count--,in++,out++) {
800 f = *in;
801 l = RINT(UNNORM24U(f));
802 if (l > 0xFFFFFF || f > 2.0) { l = 0xFFFFFF; cc++; } else if (l < 0 || f < -2.0) { l = 0; cc++; }
803 *out = l << 8;
804 }
805 return cc;
806 }
807
C_FLOAT_PCM24UOEPM(FTYPE * in,guint32 * out,int count)808 static int C_FLOAT_PCM24UOEPM(FTYPE *in, guint32 *out, int count)
809 {
810 int i;
811 i = C_FLOAT_PCM24UNEPM(in,out,count);
812 byteswap(out,4,count*4);
813 return i;
814 }
815
C_FLOAT_PCM24SNEPL(FTYPE * in,guint32 * out,int count)816 static int C_FLOAT_PCM24SNEPL(FTYPE *in, guint32 *out, int count)
817 {
818 long l;
819 int cc=0;
820 FTYPE f;
821 for (; count>0; count--,in++,out++) {
822 f = *in;
823 l = RINT(UNNORM24S(f));
824 if (l > 0x7FFFFF || f > 2.0) { l = 0x7FFFFF; cc++; }
825 else if (l < -0x800000 || f < -2.0) { l = -0x800000; cc++; }
826 *out = l;
827 }
828 return cc;
829 }
830
C_FLOAT_PCM24SOEPL(FTYPE * in,guint32 * out,int count)831 static int C_FLOAT_PCM24SOEPL(FTYPE *in, guint32 *out, int count)
832 {
833 int i;
834 i = C_FLOAT_PCM24SNEPL(in,out,count);
835 byteswap(out,4,count*4);
836 return i;
837 }
838
C_FLOAT_PCM24UNEPL(FTYPE * in,guint32 * out,int count)839 static int C_FLOAT_PCM24UNEPL(FTYPE *in, guint32 *out, int count)
840 {
841 unsigned long l;
842 int cc=0;
843 FTYPE f;
844 for (; count>0; count--,in++,out++) {
845 f = *in;
846 l = RINT(UNNORM24U(f));
847 if (l > 0xFFFFFF || f > 2.0) { l = 0xFFFFFF; cc++; } else if (l < 0 || f < -2.0) { l = 0; cc++; }
848 *out = l;
849 }
850 return cc;
851 }
852
C_FLOAT_PCM24UOEPL(FTYPE * in,guint32 * out,int count)853 static int C_FLOAT_PCM24UOEPL(FTYPE *in, guint32 *out, int count)
854 {
855 int i;
856 i = C_FLOAT_PCM24UNEPL(in,out,count);
857 byteswap(out,4,count*4);
858 return i;
859 }
860
861
862 /* Defined in this file. */
863 #undef C_PCM16SNE_FLOAT
864 #undef C_PCM16SOE_FLOAT
865 #undef C_PCM16UNE_FLOAT
866 #undef C_PCM16UOE_FLOAT
867 #undef C_PCM32SNE_FLOAT
868 #undef C_PCM32SOE_FLOAT
869 #undef C_PCM32UNE_FLOAT
870 #undef C_PCM32UOE_FLOAT
871 #undef C_PCM24SNEPM_FLOAT
872 #undef C_PCM24SOEPM_FLOAT
873 #undef C_PCM24UNEPM_FLOAT
874 #undef C_PCM24UOEPM_FLOAT
875 #undef C_PCM24SNEPL_FLOAT
876 #undef C_PCM24SOEPL_FLOAT
877 #undef C_PCM24UNEPL_FLOAT
878 #undef C_PCM24UOEPL_FLOAT
879 #undef C_FLOAT_PCM16SNE
880 #undef C_FLOAT_PCM16SOE
881 #undef C_FLOAT_PCM16UNE
882 #undef C_FLOAT_PCM16UOE
883 #undef C_FLOAT_PCM32SNE
884 #undef C_FLOAT_PCM32SOE
885 #undef C_FLOAT_PCM32UNE
886 #undef C_FLOAT_PCM32UOE
887 #undef C_FLOAT_PCM24SNEPM
888 #undef C_FLOAT_PCM24SOEPM
889 #undef C_FLOAT_PCM24UNEPM
890 #undef C_FLOAT_PCM24UOEPM
891 #undef C_FLOAT_PCM24SNEPL
892 #undef C_FLOAT_PCM24SOEPL
893 #undef C_FLOAT_PCM24UNEPL
894 #undef C_FLOAT_PCM24UOEPL
895 #undef MUL
896 #undef DIV
897 #undef MULADD
898 #undef SUBDIV
899 #undef NORM8U
900 #undef NORM8S
901 #undef UNNORM8U
902 #undef UNNORM8S
903 #undef NORM16U
904 #undef NORM16S
905 #undef UNNORM16U
906 #undef UNNORM16S
907 #undef NORM24U
908 #undef UNNORM24U
909 #undef UNNORM24S
910 #undef NORM32U
911 #undef NORM32S
912 #undef UNNORM32U
913 #undef UNNORM32S
914
915 /* Defined on the outside */
916 #undef FTYPE
917 #undef RINT
918 #undef C_PCM8S_FLOAT
919 #undef C_PCM8U_FLOAT
920 #undef C_PCM16SLE_FLOAT
921 #undef C_PCM16SBE_FLOAT
922 #undef C_PCM16ULE_FLOAT
923 #undef C_PCM16UBE_FLOAT
924 #undef C_PCM24SLE_FLOAT
925 #undef C_PCM24SBE_FLOAT
926 #undef C_PCM24ULE_FLOAT
927 #undef C_PCM24UBE_FLOAT
928 #undef C_PCM24SLEPM_FLOAT
929 #undef C_PCM24SBEPM_FLOAT
930 #undef C_PCM24ULEPM_FLOAT
931 #undef C_PCM24UBEPM_FLOAT
932 #undef C_PCM24SLEPL_FLOAT
933 #undef C_PCM24SBEPL_FLOAT
934 #undef C_PCM24ULEPL_FLOAT
935 #undef C_PCM24UBEPL_FLOAT
936 #undef C_PCM32SLE_FLOAT
937 #undef C_PCM32SBE_FLOAT
938 #undef C_PCM32ULE_FLOAT
939 #undef C_PCM32UBE_FLOAT
940 #undef C_FLOAT_PCM8S
941 #undef C_FLOAT_PCM8U
942 #undef C_FLOAT_PCM16SLE
943 #undef C_FLOAT_PCM16SBE
944 #undef C_FLOAT_PCM16ULE
945 #undef C_FLOAT_PCM16UBE
946 #undef C_FLOAT_PCM24SLE
947 #undef C_FLOAT_PCM24SBE
948 #undef C_FLOAT_PCM24ULE
949 #undef C_FLOAT_PCM24UBE
950 #undef C_FLOAT_PCM24SLEPM
951 #undef C_FLOAT_PCM24SBEPM
952 #undef C_FLOAT_PCM24ULEPM
953 #undef C_FLOAT_PCM24UBEPM
954 #undef C_FLOAT_PCM24SLEPL
955 #undef C_FLOAT_PCM24SBEPL
956 #undef C_FLOAT_PCM24ULEPL
957 #undef C_FLOAT_PCM24UBEPL
958 #undef C_FLOAT_PCM32SLE
959 #undef C_FLOAT_PCM32SBE
960 #undef C_FLOAT_PCM32ULE
961 #undef C_FLOAT_PCM32UBE
962