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