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