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 79void 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 94void 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 109void 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 130void 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 151void 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 162void 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 173void 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 185void 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 197void 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 208void 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 220void 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 231void 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 243void 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 254void 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 265void 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 277void 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 289void 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 301void 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 315void 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 328void 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 342void 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 353void 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 365void 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 376void 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 388void 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 400void 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 413void 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 427void 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