Merge commit 'origin/master-tx'
[platform/upstream/pulseaudio.git] / src / pulsecore / sconv-s16le.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2004-2006 Lennart Poettering
5
6   PulseAudio is free software; you can redistribute it and/or modify
7   it under the terms of the GNU Lesser General Public License as published
8   by the Free Software Foundation; either version 2.1 of the License,
9   or (at your option) any later version.
10
11   PulseAudio is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with PulseAudio; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 /* Despite the name of this file we implement S32 and S24 handling here, too. */
27
28 #include <inttypes.h>
29 #include <stdio.h>
30
31 #include <liboil/liboilfuncs.h>
32
33 #include <pulsecore/sconv.h>
34 #include <pulsecore/macro.h>
35 #include <pulsecore/log.h>
36
37 #include "endianmacros.h"
38
39 #include "sconv-s16le.h"
40
41 #ifndef INT16_FROM
42 #define INT16_FROM PA_INT16_FROM_LE
43 #endif
44 #ifndef UINT16_FROM
45 #define UINT16_FROM PA_UINT16_FROM_LE
46 #endif
47
48 #ifndef INT16_TO
49 #define INT16_TO PA_INT16_TO_LE
50 #endif
51 #ifndef UINT16_TO
52 #define UINT16_TO PA_UINT16_TO_LE
53 #endif
54
55 #ifndef INT32_FROM
56 #define INT32_FROM PA_INT32_FROM_LE
57 #endif
58 #ifndef UINT32_FROM
59 #define UINT32_FROM PA_UINT32_FROM_LE
60 #endif
61
62 #ifndef INT32_TO
63 #define INT32_TO PA_INT32_TO_LE
64 #endif
65 #ifndef UINT32_TO
66 #define UINT32_TO PA_UINT32_TO_LE
67 #endif
68
69 #ifndef READ24
70 #define READ24 PA_READ24LE
71 #endif
72 #ifndef WRITE24
73 #define WRITE24 PA_WRITE24LE
74 #endif
75
76 #ifndef SWAP_WORDS
77 #ifdef WORDS_BIGENDIAN
78 #define SWAP_WORDS 1
79 #else
80 #define SWAP_WORDS 0
81 #endif
82 #endif
83
84 void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {
85     pa_assert(a);
86     pa_assert(b);
87
88 #if SWAP_WORDS == 1
89
90     for (; n > 0; n--) {
91         int16_t s = *(a++);
92         *(b++) = ((float) INT16_FROM(s))/(float) 0x7FFF;
93     }
94
95 #else
96 {
97     static const double add = 0, factor = 1.0/0x7FFF;
98     oil_scaleconv_f32_s16(b, a, (int) n, &add, &factor);
99 }
100 #endif
101 }
102
103 void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {
104     pa_assert(a);
105     pa_assert(b);
106
107 #if SWAP_WORDS == 1
108
109     for (; n > 0; n--) {
110         int32_t s = *(a++);
111         *(b++) = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
112     }
113
114 #else
115 {
116     static const double add = 0, factor = 1.0/0x7FFFFFFF;
117     oil_scaleconv_f32_s32(b, a, (int) n, &add, &factor);
118 }
119 #endif
120 }
121
122 void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
123     pa_assert(a);
124     pa_assert(b);
125
126 #if SWAP_WORDS == 1
127
128     for (; n > 0; n--) {
129         int16_t s;
130         float v = *(a++);
131
132         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
133         s = (int16_t) lrintf(v * 0x7FFF);
134         *(b++) = INT16_TO(s);
135     }
136
137 #else
138 {
139     static const double add = 0, factor = 0x7FFF;
140     oil_scaleconv_s16_f32(b, a, (int) n, &add, &factor);
141 }
142 #endif
143 }
144
145 void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
146     pa_assert(a);
147     pa_assert(b);
148
149 #if SWAP_WORDS == 1
150
151     for (; n > 0; n--) {
152         int32_t s;
153         float v = *(a++);
154
155         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
156         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
157         *(b++) = INT32_TO(s);
158     }
159
160 #else
161 {
162     static const double add = 0, factor = 0x7FFFFFFF;
163     oil_scaleconv_s32_f32(b, a, (int) n, &add, &factor);
164 }
165 #endif
166 }
167
168 void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) {
169     pa_assert(a);
170     pa_assert(b);
171
172     for (; n > 0; n--) {
173         int16_t s = *(a++);
174         float k = ((float) INT16_FROM(s))/0x7FFF;
175         k = PA_FLOAT32_SWAP(k);
176         *(b++) = k;
177     }
178 }
179
180 void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) {
181     pa_assert(a);
182     pa_assert(b);
183
184     for (; n > 0; n--) {
185         int32_t s = *(a++);
186         float k = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
187         k = PA_FLOAT32_SWAP(k);
188         *(b++) = k;
189     }
190 }
191
192 void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) {
193     pa_assert(a);
194     pa_assert(b);
195
196     for (; n > 0; n--) {
197         int16_t s;
198         float v = *(a++);
199         v = PA_FLOAT32_SWAP(v);
200         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
201         s = (int16_t) lrintf(v * 0x7FFF);
202         *(b++) = INT16_TO(s);
203     }
204 }
205
206 void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) {
207     pa_assert(a);
208     pa_assert(b);
209
210     for (; n > 0; n--) {
211         int32_t s;
212         float v = *(a++);
213         v = PA_FLOAT32_SWAP(v);
214         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
215         s = (int32_t) lrint((double) v * 0x7FFFFFFF);
216         *(b++) = INT32_TO(s);
217     }
218 }
219
220 void pa_sconv_s32le_to_s16ne(unsigned n, const int32_t*a, int16_t *b) {
221     pa_assert(a);
222     pa_assert(b);
223
224     for (; n > 0; n--) {
225         *b = (int16_t) (INT32_FROM(*a) >> 16);
226         a++;
227         b++;
228     }
229 }
230
231 void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) {
232     pa_assert(a);
233     pa_assert(b);
234
235     for (; n > 0; n--) {
236         int16_t s = (int16_t) (INT32_FROM(*a) >> 16);
237         *b = PA_INT16_SWAP(s);
238         a++;
239         b++;
240     }
241 }
242
243 void pa_sconv_s32le_from_s16ne(unsigned n, const int16_t *a, int32_t *b) {
244     pa_assert(a);
245     pa_assert(b);
246
247     for (; n > 0; n--) {
248         *b = INT32_TO(((int32_t) *a) << 16);
249         a++;
250         b++;
251     }
252 }
253
254 void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) {
255     pa_assert(a);
256     pa_assert(b);
257
258     for (; n > 0; n--) {
259         int32_t s = ((int32_t) PA_INT16_SWAP(*a)) << 16;
260         *b = INT32_TO(s);
261         a++;
262         b++;
263     }
264 }
265
266 void pa_sconv_s24le_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {
267     pa_assert(a);
268     pa_assert(b);
269
270     for (; n > 0; n--) {
271         *b = (int16_t) (READ24(a) >> 8);
272         a += 3;
273         b++;
274     }
275 }
276
277 void pa_sconv_s24le_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {
278     pa_assert(a);
279     pa_assert(b);
280
281     for (; n > 0; n--) {
282         WRITE24(b, ((uint32_t) *a) << 8);
283         a++;
284         b += 3;
285     }
286 }
287
288 void pa_sconv_s24le_to_s16re(unsigned n, const uint8_t *a, int16_t *b) {
289     pa_assert(a);
290     pa_assert(b);
291
292     for (; n > 0; n--) {
293         int16_t s = (int16_t) (READ24(a) >> 8);
294         *b = PA_INT16_SWAP(s);
295         a += 3;
296         b++;
297     }
298 }
299
300 void pa_sconv_s24le_from_s16re(unsigned n, const int16_t *a, uint8_t *b) {
301     pa_assert(a);
302     pa_assert(b);
303
304     for (; n > 0; n--) {
305         uint32_t s = ((uint32_t) PA_INT16_SWAP(*a)) << 8;
306         WRITE24(b, s);
307         a++;
308         b += 3;
309     }
310 }
311
312 void pa_sconv_s24le_to_float32ne(unsigned n, const uint8_t *a, float *b) {
313     pa_assert(a);
314     pa_assert(b);
315
316     for (; n > 0; n--) {
317         int32_t s = READ24(a) << 8;
318         *b = ((float) s) / 0x7FFFFFFF;
319         a += 3;
320         b ++;
321     }
322 }
323
324 void pa_sconv_s24le_from_float32ne(unsigned n, const float *a, uint8_t *b) {
325     pa_assert(a);
326     pa_assert(b);
327
328     for (; n > 0; n--) {
329         int32_t s;
330         float v = *a;
331         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
332         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
333         WRITE24(b, ((uint32_t) s) >> 8);
334         a++;
335         b+=3;
336     }
337 }
338
339 void pa_sconv_s24le_to_float32re(unsigned n, const uint8_t *a, float *b) {
340     pa_assert(a);
341     pa_assert(b);
342
343     for (; n > 0; n--) {
344         int32_t s = READ24(a) << 8;
345         float k = ((float) s) / 0x7FFFFFFF;
346         *b = PA_FLOAT32_SWAP(k);
347         a += 3;
348         b ++;
349     }
350 }
351
352 void pa_sconv_s24le_from_float32re(unsigned n, const float *a, uint8_t *b) {
353     pa_assert(a);
354     pa_assert(b);
355
356     for (; n > 0; n--) {
357         int32_t s;
358         float v = *a;
359         v = PA_FLOAT32_SWAP(v);
360         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
361         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
362         WRITE24(b, ((uint32_t) s) >> 8);
363         a++;
364         b+=3;
365     }
366 }
367
368 void pa_sconv_s24_32le_to_s16ne(unsigned n, const uint32_t *a, int16_t *b) {
369     pa_assert(a);
370     pa_assert(b);
371
372     for (; n > 0; n--) {
373         *b = (int16_t) (((int32_t) (UINT32_FROM(*a) << 8)) >> 16);
374         a++;
375         b++;
376     }
377 }
378
379 void pa_sconv_s24_32le_to_s16re(unsigned n, const uint32_t *a, int16_t *b) {
380     pa_assert(a);
381     pa_assert(b);
382
383     for (; n > 0; n--) {
384         int16_t s = (int16_t) ((int32_t) (UINT32_FROM(*a) << 8) >> 16);
385         *b = PA_INT16_SWAP(s);
386         a++;
387         b++;
388     }
389 }
390
391 void pa_sconv_s24_32le_from_s16ne(unsigned n, const int16_t *a, uint32_t *b) {
392     pa_assert(a);
393     pa_assert(b);
394
395     for (; n > 0; n--) {
396         *b = UINT32_TO(((uint32_t) ((int32_t) *a << 16)) >> 8);
397         a++;
398         b++;
399     }
400 }
401
402 void pa_sconv_s24_32le_from_s16re(unsigned n, const int16_t *a, uint32_t *b) {
403     pa_assert(a);
404     pa_assert(b);
405
406     for (; n > 0; n--) {
407         uint32_t s = ((uint32_t) ((int32_t) PA_INT16_SWAP(*a) << 16)) >> 8;
408         *b = UINT32_TO(s);
409         a++;
410         b++;
411     }
412 }
413
414 void pa_sconv_s24_32le_to_float32ne(unsigned n, const uint32_t *a, float *b) {
415     pa_assert(a);
416     pa_assert(b);
417
418     for (; n > 0; n--) {
419         int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
420         *b = (float) s / (float) 0x7FFFFFFF;
421         a ++;
422         b ++;
423     }
424 }
425
426 void pa_sconv_s24_32le_to_float32re(unsigned n, const uint32_t *a, float *b) {
427     pa_assert(a);
428     pa_assert(b);
429
430     for (; n > 0; n--) {
431         int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
432         float k = (float) s / (float) 0x7FFFFFFF;
433         *b = PA_FLOAT32_SWAP(k);
434         a ++;
435         b ++;
436     }
437 }
438
439 void pa_sconv_s24_32le_from_float32ne(unsigned n, const float *a, uint32_t *b) {
440     pa_assert(a);
441     pa_assert(b);
442
443     for (; n > 0; n--) {
444         int32_t s;
445         float v = *a;
446         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
447         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
448         *b = UINT32_TO(((uint32_t) s) >> 8);
449         a++;
450         b++;
451     }
452 }
453
454 void pa_sconv_s24_32le_from_float32re(unsigned n, const float *a, uint32_t *b) {
455     pa_assert(a);
456     pa_assert(b);
457
458     for (; n > 0; n--) {
459         int32_t s;
460         float v = *a;
461         v = PA_FLOAT32_SWAP(v);
462         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
463         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
464         *b = UINT32_TO(((uint32_t) s) >> 8);
465         a++;
466         b++;
467     }
468 }