diff options
Diffstat (limited to 'src/pulsecore/sconv-s16le.c')
-rw-r--r-- | src/pulsecore/sconv-s16le.c | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c new file mode 100644 index 0000000..c503e0e --- /dev/null +++ b/src/pulsecore/sconv-s16le.c @@ -0,0 +1,439 @@ +/*** + This file is part of PulseAudio. + + Copyright 2004-2006 Lennart Poettering + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +/* Despite the name of this file we implement S32 and S24 handling here, too. */ + +#include <inttypes.h> +#include <stdio.h> +#include <math.h> + +#include <pulsecore/sconv.h> +#include <pulsecore/macro.h> +#include <pulsecore/endianmacros.h> + +#include "sconv-s16le.h" + +#ifndef INT16_FROM +#define INT16_FROM PA_INT16_FROM_LE +#endif +#ifndef UINT16_FROM +#define UINT16_FROM PA_UINT16_FROM_LE +#endif + +#ifndef INT16_TO +#define INT16_TO PA_INT16_TO_LE +#endif +#ifndef UINT16_TO +#define UINT16_TO PA_UINT16_TO_LE +#endif + +#ifndef INT32_FROM +#define INT32_FROM PA_INT32_FROM_LE +#endif +#ifndef UINT32_FROM +#define UINT32_FROM PA_UINT32_FROM_LE +#endif + +#ifndef INT32_TO +#define INT32_TO PA_INT32_TO_LE +#endif +#ifndef UINT32_TO +#define UINT32_TO PA_UINT32_TO_LE +#endif + +#ifndef READ24 +#define READ24 PA_READ24LE +#endif +#ifndef WRITE24 +#define WRITE24 PA_WRITE24LE +#endif + +#ifndef SWAP_WORDS +#ifdef WORDS_BIGENDIAN +#define SWAP_WORDS 1 +#else +#define SWAP_WORDS 0 +#endif +#endif + +void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) { + pa_assert(a); + pa_assert(b); + +#if SWAP_WORDS == 1 + for (; n > 0; n--) { + int16_t s = *(a++); + *(b++) = INT16_FROM(s) * (1.0f / (1 << 15)); + } +#else + for (; n > 0; n--) + *(b++) = *(a++) * (1.0f / (1 << 15)); +#endif +} + +void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) { + pa_assert(a); + pa_assert(b); + +#if SWAP_WORDS == 1 + for (; n > 0; n--) { + int32_t s = *(a++); + *(b++) = INT32_FROM(s) * (1.0f / (1U << 31)); + } +#else + for (; n > 0; n--) + *(b++) = *(a++) * (1.0f / (1U << 31)); +#endif +} + +void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + +#if SWAP_WORDS == 1 + for (; n > 0; n--) { + int16_t s; + float v = *(a++) * (1 << 15); + + s = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF); + *(b++) = INT16_TO(s); + } +#else + for (; n > 0; n--) { + float v = *(a++) * (1 << 15); + + *(b++) = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF); + } +#endif +} + +void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) { + pa_assert(a); + pa_assert(b); + +#if SWAP_WORDS == 1 + for (; n > 0; n--) { + int32_t s; + float v = *(a++) * (1U << 31); + + s = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL); + *(b++) = INT32_TO(s); + } +#else + for (; n > 0; n--) { + float v = *(a++) * (1U << 31); + + *(b++) = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL); + } +#endif +} + +void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int16_t s = *(a++); + float k = INT16_FROM(s) * (1.0f / (1 << 15)); + PA_WRITE_FLOAT32RE(b++, k); + } +} + +void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s = *(a++); + float k = INT32_FROM(s) * (1.0f / (1U << 31)); + PA_WRITE_FLOAT32RE(b++, k); + } +} + +void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int16_t s; + float v = PA_READ_FLOAT32RE(a++) * (1 << 15); + s = (int16_t) PA_CLAMP_UNLIKELY(lrintf(v), -0x8000, 0x7FFF); + *(b++) = INT16_TO(s); + } +} + +void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s; + float v = PA_READ_FLOAT32RE(a++) * (1U << 31); + s = (int32_t) PA_CLAMP_UNLIKELY(llrintf(v), -0x80000000LL, 0x7FFFFFFFLL); + *(b++) = INT32_TO(s); + } +} + +void pa_sconv_s32le_to_s16ne(unsigned n, const int32_t*a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + *b = (int16_t) (INT32_FROM(*a) >> 16); + a++; + b++; + } +} + +void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int16_t s = (int16_t) (INT32_FROM(*a) >> 16); + *b = PA_INT16_SWAP(s); + a++; + b++; + } +} + +void pa_sconv_s32le_from_s16ne(unsigned n, const int16_t *a, int32_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + *b = INT32_TO(((int32_t) *a) << 16); + a++; + b++; + } +} + +void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s = ((int32_t) PA_INT16_SWAP(*a)) << 16; + *b = INT32_TO(s); + a++; + b++; + } +} + +void pa_sconv_s24le_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + *b = (int16_t) (READ24(a) >> 8); + a += 3; + b++; + } +} + +void pa_sconv_s24le_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + WRITE24(b, ((uint32_t) *a) << 8); + a++; + b += 3; + } +} + +void pa_sconv_s24le_to_s16re(unsigned n, const uint8_t *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int16_t s = (int16_t) (READ24(a) >> 8); + *b = PA_INT16_SWAP(s); + a += 3; + b++; + } +} + +void pa_sconv_s24le_from_s16re(unsigned n, const int16_t *a, uint8_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + uint32_t s = ((uint32_t) PA_INT16_SWAP(*a)) << 8; + WRITE24(b, s); + a++; + b += 3; + } +} + +void pa_sconv_s24le_to_float32ne(unsigned n, const uint8_t *a, float *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s = READ24(a) << 8; + *b = s * (1.0f / (1U << 31)); + a += 3; + b++; + } +} + +void pa_sconv_s24le_from_float32ne(unsigned n, const float *a, uint8_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s; + float v = *a * (1U << 31); + s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL); + WRITE24(b, ((uint32_t) s) >> 8); + a++; + b += 3; + } +} + +void pa_sconv_s24le_to_float32re(unsigned n, const uint8_t *a, float *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s = READ24(a) << 8; + float k = s * (1.0f / (1U << 31)); + PA_WRITE_FLOAT32RE(b, k); + a += 3; + b++; + } +} + +void pa_sconv_s24le_from_float32re(unsigned n, const float *a, uint8_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s; + float v = PA_READ_FLOAT32RE(a) * (1U << 31); + s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL); + WRITE24(b, ((uint32_t) s) >> 8); + a++; + b+=3; + } +} + +void pa_sconv_s24_32le_to_s16ne(unsigned n, const uint32_t *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + *b = (int16_t) (((int32_t) (UINT32_FROM(*a) << 8)) >> 16); + a++; + b++; + } +} + +void pa_sconv_s24_32le_to_s16re(unsigned n, const uint32_t *a, int16_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int16_t s = (int16_t) ((int32_t) (UINT32_FROM(*a) << 8) >> 16); + *b = PA_INT16_SWAP(s); + a++; + b++; + } +} + +void pa_sconv_s24_32le_from_s16ne(unsigned n, const int16_t *a, uint32_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + *b = UINT32_TO(((uint32_t) ((int32_t) *a << 16)) >> 8); + a++; + b++; + } +} + +void pa_sconv_s24_32le_from_s16re(unsigned n, const int16_t *a, uint32_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + uint32_t s = ((uint32_t) ((int32_t) PA_INT16_SWAP(*a) << 16)) >> 8; + *b = UINT32_TO(s); + a++; + b++; + } +} + +void pa_sconv_s24_32le_to_float32ne(unsigned n, const uint32_t *a, float *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s = (int32_t) (UINT32_FROM(*a) << 8); + *b = s * (1.0f / (1U << 31)); + a++; + b++; + } +} + +void pa_sconv_s24_32le_to_float32re(unsigned n, const uint32_t *a, float *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s = (int32_t) (UINT32_FROM(*a) << 8); + float k = s * (1.0f / (1U << 31)); + PA_WRITE_FLOAT32RE(b, k); + a++; + b++; + } +} + +void pa_sconv_s24_32le_from_float32ne(unsigned n, const float *a, uint32_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s; + float v = *a * (1U << 31); + s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL); + *b = UINT32_TO(((uint32_t) s) >> 8); + a++; + b++; + } +} + +void pa_sconv_s24_32le_from_float32re(unsigned n, const float *a, uint32_t *b) { + pa_assert(a); + pa_assert(b); + + for (; n > 0; n--) { + int32_t s; + float v = PA_READ_FLOAT32RE(a) * (1U << 31); + s = (int32_t) PA_CLAMP_UNLIKELY(llrint(v), -0x80000000LL, 0x7FFFFFFFLL); + *b = UINT32_TO(((uint32_t) s) >> 8); + a++; + b++; + } +} |