core: always allow volume setting with single-channel pa_cvolume
[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 <pulsecore/sconv.h>
32 #include <pulsecore/macro.h>
33 #include <pulsecore/log.h>
34
35 #include "endianmacros.h"
36
37 #include "sconv-s16le.h"
38
39 #ifndef INT16_FROM
40 #define INT16_FROM PA_INT16_FROM_LE
41 #endif
42 #ifndef UINT16_FROM
43 #define UINT16_FROM PA_UINT16_FROM_LE
44 #endif
45
46 #ifndef INT16_TO
47 #define INT16_TO PA_INT16_TO_LE
48 #endif
49 #ifndef UINT16_TO
50 #define UINT16_TO PA_UINT16_TO_LE
51 #endif
52
53 #ifndef INT32_FROM
54 #define INT32_FROM PA_INT32_FROM_LE
55 #endif
56 #ifndef UINT32_FROM
57 #define UINT32_FROM PA_UINT32_FROM_LE
58 #endif
59
60 #ifndef INT32_TO
61 #define INT32_TO PA_INT32_TO_LE
62 #endif
63 #ifndef UINT32_TO
64 #define UINT32_TO PA_UINT32_TO_LE
65 #endif
66
67 #ifndef READ24
68 #define READ24 PA_READ24LE
69 #endif
70 #ifndef WRITE24
71 #define WRITE24 PA_WRITE24LE
72 #endif
73
74 #ifndef SWAP_WORDS
75 #ifdef WORDS_BIGENDIAN
76 #define SWAP_WORDS 1
77 #else
78 #define SWAP_WORDS 0
79 #endif
80 #endif
81
82 void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {
83     pa_assert(a);
84     pa_assert(b);
85
86 #if SWAP_WORDS == 1
87     for (; n > 0; n--) {
88         int16_t s = *(a++);
89         *(b++) = ((float) INT16_FROM(s))/(float) 0x7FFF;
90     }
91 #else
92     for (; n > 0; n--)
93         *(b++) = ((float) (*(a++)))/(float) 0x7FFF;
94 #endif
95 }
96
97 void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {
98     pa_assert(a);
99     pa_assert(b);
100
101 #if SWAP_WORDS == 1
102     for (; n > 0; n--) {
103         int32_t s = *(a++);
104         *(b++) = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
105     }
106 #else
107     for (; n > 0; n--)
108         *(b++) = (float) (((double) (*(a++)))/0x7FFFFFFF);
109 #endif
110 }
111
112 void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
113     pa_assert(a);
114     pa_assert(b);
115
116 #if SWAP_WORDS == 1
117     for (; n > 0; n--) {
118         int16_t s;
119         float v = *(a++);
120
121         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
122         s = (int16_t) lrintf(v * 0x7FFF);
123         *(b++) = INT16_TO(s);
124     }
125 #else
126     for (; n > 0; n--) {
127         float v = *(a++);
128
129         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
130         *(b++) = (int16_t) lrintf(v * 0x7FFF);
131     }
132 #endif
133 }
134
135 void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
136     pa_assert(a);
137     pa_assert(b);
138
139 #if SWAP_WORDS == 1
140     for (; n > 0; n--) {
141         int32_t s;
142         float v = *(a++);
143
144         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
145         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
146         *(b++) = INT32_TO(s);
147     }
148 #else
149     for (; n > 0; n--) {
150         float v = *(a++);
151
152         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
153         *(b++) = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
154     }
155 #endif
156 }
157
158 void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) {
159     pa_assert(a);
160     pa_assert(b);
161
162     for (; n > 0; n--) {
163         int16_t s = *(a++);
164         float k = ((float) INT16_FROM(s))/0x7FFF;
165         k = PA_FLOAT32_SWAP(k);
166         *(b++) = k;
167     }
168 }
169
170 void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) {
171     pa_assert(a);
172     pa_assert(b);
173
174     for (; n > 0; n--) {
175         int32_t s = *(a++);
176         float k = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
177         k = PA_FLOAT32_SWAP(k);
178         *(b++) = k;
179     }
180 }
181
182 void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) {
183     pa_assert(a);
184     pa_assert(b);
185
186     for (; n > 0; n--) {
187         int16_t s;
188         float v = *(a++);
189         v = PA_FLOAT32_SWAP(v);
190         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
191         s = (int16_t) lrintf(v * 0x7FFF);
192         *(b++) = INT16_TO(s);
193     }
194 }
195
196 void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) {
197     pa_assert(a);
198     pa_assert(b);
199
200     for (; n > 0; n--) {
201         int32_t s;
202         float v = *(a++);
203         v = PA_FLOAT32_SWAP(v);
204         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
205         s = (int32_t) lrint((double) v * 0x7FFFFFFF);
206         *(b++) = INT32_TO(s);
207     }
208 }
209
210 void pa_sconv_s32le_to_s16ne(unsigned n, const int32_t*a, int16_t *b) {
211     pa_assert(a);
212     pa_assert(b);
213
214     for (; n > 0; n--) {
215         *b = (int16_t) (INT32_FROM(*a) >> 16);
216         a++;
217         b++;
218     }
219 }
220
221 void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) {
222     pa_assert(a);
223     pa_assert(b);
224
225     for (; n > 0; n--) {
226         int16_t s = (int16_t) (INT32_FROM(*a) >> 16);
227         *b = PA_INT16_SWAP(s);
228         a++;
229         b++;
230     }
231 }
232
233 void pa_sconv_s32le_from_s16ne(unsigned n, const int16_t *a, int32_t *b) {
234     pa_assert(a);
235     pa_assert(b);
236
237     for (; n > 0; n--) {
238         *b = INT32_TO(((int32_t) *a) << 16);
239         a++;
240         b++;
241     }
242 }
243
244 void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) {
245     pa_assert(a);
246     pa_assert(b);
247
248     for (; n > 0; n--) {
249         int32_t s = ((int32_t) PA_INT16_SWAP(*a)) << 16;
250         *b = INT32_TO(s);
251         a++;
252         b++;
253     }
254 }
255
256 void pa_sconv_s24le_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {
257     pa_assert(a);
258     pa_assert(b);
259
260     for (; n > 0; n--) {
261         *b = (int16_t) (READ24(a) >> 8);
262         a += 3;
263         b++;
264     }
265 }
266
267 void pa_sconv_s24le_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {
268     pa_assert(a);
269     pa_assert(b);
270
271     for (; n > 0; n--) {
272         WRITE24(b, ((uint32_t) *a) << 8);
273         a++;
274         b += 3;
275     }
276 }
277
278 void pa_sconv_s24le_to_s16re(unsigned n, const uint8_t *a, int16_t *b) {
279     pa_assert(a);
280     pa_assert(b);
281
282     for (; n > 0; n--) {
283         int16_t s = (int16_t) (READ24(a) >> 8);
284         *b = PA_INT16_SWAP(s);
285         a += 3;
286         b++;
287     }
288 }
289
290 void pa_sconv_s24le_from_s16re(unsigned n, const int16_t *a, uint8_t *b) {
291     pa_assert(a);
292     pa_assert(b);
293
294     for (; n > 0; n--) {
295         uint32_t s = ((uint32_t) PA_INT16_SWAP(*a)) << 8;
296         WRITE24(b, s);
297         a++;
298         b += 3;
299     }
300 }
301
302 void pa_sconv_s24le_to_float32ne(unsigned n, const uint8_t *a, float *b) {
303     pa_assert(a);
304     pa_assert(b);
305
306     for (; n > 0; n--) {
307         int32_t s = READ24(a) << 8;
308         *b = ((float) s) / 0x7FFFFFFF;
309         a += 3;
310         b ++;
311     }
312 }
313
314 void pa_sconv_s24le_from_float32ne(unsigned n, const float *a, uint8_t *b) {
315     pa_assert(a);
316     pa_assert(b);
317
318     for (; n > 0; n--) {
319         int32_t s;
320         float v = *a;
321         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
322         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
323         WRITE24(b, ((uint32_t) s) >> 8);
324         a++;
325         b+=3;
326     }
327 }
328
329 void pa_sconv_s24le_to_float32re(unsigned n, const uint8_t *a, float *b) {
330     pa_assert(a);
331     pa_assert(b);
332
333     for (; n > 0; n--) {
334         int32_t s = READ24(a) << 8;
335         float k = ((float) s) / 0x7FFFFFFF;
336         *b = PA_FLOAT32_SWAP(k);
337         a += 3;
338         b ++;
339     }
340 }
341
342 void pa_sconv_s24le_from_float32re(unsigned n, const float *a, uint8_t *b) {
343     pa_assert(a);
344     pa_assert(b);
345
346     for (; n > 0; n--) {
347         int32_t s;
348         float v = *a;
349         v = PA_FLOAT32_SWAP(v);
350         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
351         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
352         WRITE24(b, ((uint32_t) s) >> 8);
353         a++;
354         b+=3;
355     }
356 }
357
358 void pa_sconv_s24_32le_to_s16ne(unsigned n, const uint32_t *a, int16_t *b) {
359     pa_assert(a);
360     pa_assert(b);
361
362     for (; n > 0; n--) {
363         *b = (int16_t) (((int32_t) (UINT32_FROM(*a) << 8)) >> 16);
364         a++;
365         b++;
366     }
367 }
368
369 void pa_sconv_s24_32le_to_s16re(unsigned n, const uint32_t *a, int16_t *b) {
370     pa_assert(a);
371     pa_assert(b);
372
373     for (; n > 0; n--) {
374         int16_t s = (int16_t) ((int32_t) (UINT32_FROM(*a) << 8) >> 16);
375         *b = PA_INT16_SWAP(s);
376         a++;
377         b++;
378     }
379 }
380
381 void pa_sconv_s24_32le_from_s16ne(unsigned n, const int16_t *a, uint32_t *b) {
382     pa_assert(a);
383     pa_assert(b);
384
385     for (; n > 0; n--) {
386         *b = UINT32_TO(((uint32_t) ((int32_t) *a << 16)) >> 8);
387         a++;
388         b++;
389     }
390 }
391
392 void pa_sconv_s24_32le_from_s16re(unsigned n, const int16_t *a, uint32_t *b) {
393     pa_assert(a);
394     pa_assert(b);
395
396     for (; n > 0; n--) {
397         uint32_t s = ((uint32_t) ((int32_t) PA_INT16_SWAP(*a) << 16)) >> 8;
398         *b = UINT32_TO(s);
399         a++;
400         b++;
401     }
402 }
403
404 void pa_sconv_s24_32le_to_float32ne(unsigned n, const uint32_t *a, float *b) {
405     pa_assert(a);
406     pa_assert(b);
407
408     for (; n > 0; n--) {
409         int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
410         *b = (float) s / (float) 0x7FFFFFFF;
411         a ++;
412         b ++;
413     }
414 }
415
416 void pa_sconv_s24_32le_to_float32re(unsigned n, const uint32_t *a, float *b) {
417     pa_assert(a);
418     pa_assert(b);
419
420     for (; n > 0; n--) {
421         int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
422         float k = (float) s / (float) 0x7FFFFFFF;
423         *b = PA_FLOAT32_SWAP(k);
424         a ++;
425         b ++;
426     }
427 }
428
429 void pa_sconv_s24_32le_from_float32ne(unsigned n, const float *a, uint32_t *b) {
430     pa_assert(a);
431     pa_assert(b);
432
433     for (; n > 0; n--) {
434         int32_t s;
435         float v = *a;
436         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
437         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
438         *b = UINT32_TO(((uint32_t) s) >> 8);
439         a++;
440         b++;
441     }
442 }
443
444 void pa_sconv_s24_32le_from_float32re(unsigned n, const float *a, uint32_t *b) {
445     pa_assert(a);
446     pa_assert(b);
447
448     for (; n > 0; n--) {
449         int32_t s;
450         float v = *a;
451         v = PA_FLOAT32_SWAP(v);
452         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
453         s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
454         *b = UINT32_TO(((uint32_t) s) >> 8);
455         a++;
456         b++;
457     }
458 }