2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
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.
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.
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/>.
24 /* Despite the name of this file we implement S32 and S24 handling here, too. */
30 #include <pulsecore/sconv.h>
31 #include <pulsecore/macro.h>
32 #include <pulsecore/endianmacros.h>
34 #include "sconv-s16le.h"
37 #define INT16_FROM PA_INT16_FROM_LE
40 #define UINT16_FROM PA_UINT16_FROM_LE
44 #define INT16_TO PA_INT16_TO_LE
47 #define UINT16_TO PA_UINT16_TO_LE
51 #define INT32_FROM PA_INT32_FROM_LE
54 #define UINT32_FROM PA_UINT32_FROM_LE
58 #define INT32_TO PA_INT32_TO_LE
61 #define UINT32_TO PA_UINT32_TO_LE
65 #define READ24 PA_READ24LE
68 #define WRITE24 PA_WRITE24LE
72 #ifdef WORDS_BIGENDIAN
79 void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {
86 *(b++) = INT16_FROM(s) * (1.0f / (1 << 15));
90 *(b++) = *(a++) * (1.0f / (1 << 15));
94 void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {
101 *(b++) = INT32_FROM(s) * (1.0f / (1U << 31));
105 *(b++) = *(a++) * (1.0f / (1U << 31));
109 void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
116 float v = *(a++) * (1 << 15);
118 s = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF);
119 *(b++) = INT16_TO(s);
123 float v = *(a++) * (1 << 15);
125 *(b++) = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF);
130 void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
137 float v = *(a++) * (1U << 31);
139 s = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL);
140 *(b++) = INT32_TO(s);
144 float v = *(a++) * (1U << 31);
146 *(b++) = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL);
151 void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) {
157 float k = INT16_FROM(s) * (1.0f / (1 << 15));
158 PA_WRITE_FLOAT32RE(b++, k);
162 void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) {
168 float k = INT32_FROM(s) * (1.0f / (1U << 31));
169 PA_WRITE_FLOAT32RE(b++, k);
173 void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) {
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);
185 void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) {
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);
197 void pa_sconv_s32le_to_s16ne(unsigned n, const int32_t*a, int16_t *b) {
202 *b = (int16_t) (INT32_FROM(*a) >> 16);
208 void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) {
213 int16_t s = (int16_t) (INT32_FROM(*a) >> 16);
214 *b = PA_INT16_SWAP(s);
220 void pa_sconv_s32le_from_s16ne(unsigned n, const int16_t *a, int32_t *b) {
225 *b = INT32_TO(((int32_t) *a) << 16);
231 void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) {
236 int32_t s = ((int32_t) PA_INT16_SWAP(*a)) << 16;
243 void pa_sconv_s24le_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {
248 *b = (int16_t) (READ24(a) >> 8);
254 void pa_sconv_s24le_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {
259 WRITE24(b, ((uint32_t) *a) << 8);
265 void pa_sconv_s24le_to_s16re(unsigned n, const uint8_t *a, int16_t *b) {
270 int16_t s = (int16_t) (READ24(a) >> 8);
271 *b = PA_INT16_SWAP(s);
277 void pa_sconv_s24le_from_s16re(unsigned n, const int16_t *a, uint8_t *b) {
282 uint32_t s = ((uint32_t) PA_INT16_SWAP(*a)) << 8;
289 void pa_sconv_s24le_to_float32ne(unsigned n, const uint8_t *a, float *b) {
294 int32_t s = READ24(a) << 8;
295 *b = s * (1.0f / (1U << 31));
301 void pa_sconv_s24le_from_float32ne(unsigned n, const float *a, uint8_t *b) {
307 float v = *a * (1U << 31);
308 s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL);
309 WRITE24(b, ((uint32_t) s) >> 8);
315 void pa_sconv_s24le_to_float32re(unsigned n, const uint8_t *a, float *b) {
320 int32_t s = READ24(a) << 8;
321 float k = s * (1.0f / (1U << 31));
322 PA_WRITE_FLOAT32RE(b, k);
328 void pa_sconv_s24le_from_float32re(unsigned n, const float *a, uint8_t *b) {
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);
342 void pa_sconv_s24_32le_to_s16ne(unsigned n, const uint32_t *a, int16_t *b) {
347 *b = (int16_t) (((int32_t) (UINT32_FROM(*a) << 8)) >> 16);
353 void pa_sconv_s24_32le_to_s16re(unsigned n, const uint32_t *a, int16_t *b) {
358 int16_t s = (int16_t) ((int32_t) (UINT32_FROM(*a) << 8) >> 16);
359 *b = PA_INT16_SWAP(s);
365 void pa_sconv_s24_32le_from_s16ne(unsigned n, const int16_t *a, uint32_t *b) {
370 *b = UINT32_TO(((uint32_t) ((int32_t) *a << 16)) >> 8);
376 void pa_sconv_s24_32le_from_s16re(unsigned n, const int16_t *a, uint32_t *b) {
381 uint32_t s = ((uint32_t) ((int32_t) PA_INT16_SWAP(*a) << 16)) >> 8;
388 void pa_sconv_s24_32le_to_float32ne(unsigned n, const uint32_t *a, float *b) {
393 int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
394 *b = s * (1.0f / (1U << 31));
400 void pa_sconv_s24_32le_to_float32re(unsigned n, const uint32_t *a, float *b) {
405 int32_t s = (int32_t) (UINT32_FROM(*a) << 8);
406 float k = s * (1.0f / (1U << 31));
407 PA_WRITE_FLOAT32RE(b, k);
413 void pa_sconv_s24_32le_from_float32ne(unsigned n, const float *a, uint32_t *b) {
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);
427 void pa_sconv_s24_32le_from_float32re(unsigned n, const float *a, uint32_t *b) {
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);