1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2006-2009 Ariff Abdullah <ariff@FreeBSD.org> 5 * All rights reserved. 6 * Copyright (c) 2024-2025 The FreeBSD Foundation 7 * 8 * Portions of this software were developed by Christos Margiolis 9 * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef _SND_PCM_H_ 34 #define _SND_PCM_H_ 35 36 #include <sys/param.h> 37 38 #include <dev/sound/pcm/g711.h> 39 40 #ifndef _KERNEL 41 #include <assert.h> /* for __assert_unreachable() */ 42 #endif 43 44 /* 45 * Automatically turn on 64bit arithmetic on suitable archs 46 * (amd64 64bit, etc..) for wider 32bit samples / integer processing. 47 */ 48 #if LONG_BIT >= 64 49 #undef SND_PCM_64 50 #define SND_PCM_64 1 51 #endif 52 53 typedef int32_t intpcm_t; 54 55 typedef int32_t intpcm8_t; 56 typedef int32_t intpcm16_t; 57 typedef int32_t intpcm24_t; 58 59 typedef uint32_t uintpcm_t; 60 61 typedef uint32_t uintpcm8_t; 62 typedef uint32_t uintpcm16_t; 63 typedef uint32_t uintpcm24_t; 64 65 #ifdef SND_PCM_64 66 typedef int64_t intpcm32_t; 67 typedef uint64_t uintpcm32_t; 68 #else 69 typedef int32_t intpcm32_t; 70 typedef uint32_t uintpcm32_t; 71 #endif 72 73 typedef int64_t intpcm64_t; 74 typedef uint64_t uintpcm64_t; 75 76 /* 32bit fixed point shift */ 77 #define PCM_FXSHIFT 8 78 79 #define PCM_S8_MAX 0x7f 80 #define PCM_S8_MIN -0x80 81 #define PCM_S16_MAX 0x7fff 82 #define PCM_S16_MIN -0x8000 83 #define PCM_S24_MAX 0x7fffff 84 #define PCM_S24_MIN -0x800000 85 #ifdef SND_PCM_64 86 #if LONG_BIT >= 64 87 #define PCM_S32_MAX 0x7fffffffL 88 #define PCM_S32_MIN -0x80000000L 89 #else 90 #define PCM_S32_MAX 0x7fffffffLL 91 #define PCM_S32_MIN -0x80000000LL 92 #endif 93 #else 94 #define PCM_S32_MAX 0x7fffffff 95 #define PCM_S32_MIN (-0x7fffffff - 1) 96 #endif 97 98 /* Bytes-per-sample definition */ 99 #define PCM_8_BPS 1 100 #define PCM_16_BPS 2 101 #define PCM_24_BPS 3 102 #define PCM_32_BPS 4 103 104 #define INTPCM_T(v) ((intpcm_t)(v)) 105 #define INTPCM8_T(v) ((intpcm8_t)(v)) 106 #define INTPCM16_T(v) ((intpcm16_t)(v)) 107 #define INTPCM24_T(v) ((intpcm24_t)(v)) 108 #define INTPCM32_T(v) ((intpcm32_t)(v)) 109 110 static const struct { 111 const uint8_t ulaw_to_u8[G711_TABLE_SIZE]; 112 const uint8_t alaw_to_u8[G711_TABLE_SIZE]; 113 const uint8_t u8_to_ulaw[G711_TABLE_SIZE]; 114 const uint8_t u8_to_alaw[G711_TABLE_SIZE]; 115 } xlaw_conv_tables = { 116 ULAW_TO_U8, 117 ALAW_TO_U8, 118 U8_TO_ULAW, 119 U8_TO_ALAW 120 }; 121 122 /* 123 * Functions for reading/writing PCM integer sample values from bytes array. 124 * Since every process is done using signed integer (and to make our life less 125 * miserable), unsigned sample will be converted to its signed counterpart and 126 * restored during writing back. 127 */ 128 static __always_inline __unused intpcm_t 129 pcm_sample_read(const uint8_t *src, uint32_t fmt) 130 { 131 intpcm_t v, e, m; 132 bool s; 133 134 fmt = AFMT_ENCODING(fmt); 135 136 switch (fmt) { 137 case AFMT_AC3: 138 v = 0; 139 break; 140 case AFMT_MU_LAW: 141 v = _G711_TO_INTPCM(xlaw_conv_tables.ulaw_to_u8, *src); 142 break; 143 case AFMT_A_LAW: 144 v = _G711_TO_INTPCM(xlaw_conv_tables.alaw_to_u8, *src); 145 break; 146 case AFMT_S8: 147 v = INTPCM_T((int8_t)*src); 148 break; 149 case AFMT_U8: 150 v = INTPCM_T((int8_t)(*src ^ 0x80)); 151 break; 152 case AFMT_S16_LE: 153 v = INTPCM_T(src[0] | (int8_t)src[1] << 8); 154 break; 155 case AFMT_S16_BE: 156 v = INTPCM_T(src[1] | (int8_t)src[0] << 8); 157 break; 158 case AFMT_U16_LE: 159 v = INTPCM_T(src[0] | (int8_t)(src[1] ^ 0x80) << 8); 160 break; 161 case AFMT_U16_BE: 162 v = INTPCM_T(src[1] | (int8_t)(src[0] ^ 0x80) << 8); 163 break; 164 case AFMT_S24_LE: 165 v = INTPCM_T(src[0] | src[1] << 8 | (int8_t)src[2] << 16); 166 break; 167 case AFMT_S24_BE: 168 v = INTPCM_T(src[2] | src[1] << 8 | (int8_t)src[0] << 16); 169 break; 170 case AFMT_U24_LE: 171 v = INTPCM_T(src[0] | src[1] << 8 | 172 (int8_t)(src[2] ^ 0x80) << 16); 173 break; 174 case AFMT_U24_BE: 175 v = INTPCM_T(src[2] | src[1] << 8 | 176 (int8_t)(src[0] ^ 0x80) << 16); 177 break; 178 case AFMT_S32_LE: 179 v = INTPCM_T(src[0] | src[1] << 8 | src[2] << 16 | 180 (int8_t)src[3] << 24); 181 break; 182 case AFMT_S32_BE: 183 v = INTPCM_T(src[3] | src[2] << 8 | src[1] << 16 | 184 (int8_t)src[0] << 24); 185 break; 186 case AFMT_U32_LE: 187 v = INTPCM_T(src[0] | src[1] << 8 | src[2] << 16 | 188 (int8_t)(src[3] ^ 0x80) << 24); 189 break; 190 case AFMT_U32_BE: 191 v = INTPCM_T(src[3] | src[2] << 8 | src[1] << 16 | 192 (int8_t)(src[0] ^ 0x80) << 24); 193 break; 194 case AFMT_F32_LE: /* FALLTHROUGH */ 195 case AFMT_F32_BE: 196 if (fmt == AFMT_F32_LE) { 197 v = INTPCM_T(src[0] | src[1] << 8 | src[2] << 16 | 198 (int8_t)src[3] << 24); 199 } else { 200 v = INTPCM_T(src[3] | src[2] << 8 | src[1] << 16 | 201 (int8_t)src[0] << 24); 202 } 203 e = (v >> 23) & 0xff; 204 /* NaN, +/- Inf or too small */ 205 if (e == 0xff || e < 96) { 206 v = INTPCM_T(0); 207 break; 208 } 209 s = v & 0x80000000U; 210 if (e > 126) { 211 v = INTPCM_T((s == 0) ? PCM_S32_MAX : PCM_S32_MIN); 212 break; 213 } 214 m = 0x800000 | (v & 0x7fffff); 215 e += 8 - 127; 216 if (e < 0) 217 m >>= -e; 218 else 219 m <<= e; 220 v = INTPCM_T((s == 0) ? m : -m); 221 break; 222 default: 223 v = 0; 224 printf("%s(): unknown format: 0x%08x\n", __func__, fmt); 225 __assert_unreachable(); 226 } 227 228 return (v); 229 } 230 231 /* 232 * Read sample and normalize to 32-bit magnitude. 233 */ 234 static __always_inline __unused intpcm_t 235 pcm_sample_read_norm(const uint8_t *src, uint32_t fmt) 236 { 237 return (pcm_sample_read(src, fmt) << (32 - AFMT_BIT(fmt))); 238 } 239 240 /* 241 * Read sample and restrict magnitude to 24 bits. 242 */ 243 static __always_inline __unused intpcm_t 244 pcm_sample_read_calc(const uint8_t *src, uint32_t fmt) 245 { 246 intpcm_t v; 247 248 v = pcm_sample_read(src, fmt); 249 250 #ifndef SND_PCM_64 251 /* 252 * Dynamic range for humans: ~140db. 253 * 254 * 16bit = 96db (close enough) 255 * 24bit = 144db (perfect) 256 * 32bit = 196db (way too much) 257 * 258 * 24bit is pretty much sufficient for our signed integer processing. 259 * Also, to avoid overflow, we truncate 32bit (and only 32bit) samples 260 * down to 24bit (see below for the reason), unless SND_PCM_64 is 261 * defined. 262 */ 263 if (fmt & AFMT_32BIT) 264 v >>= PCM_FXSHIFT; 265 #endif 266 267 return (v); 268 } 269 270 static __always_inline __unused void 271 pcm_sample_write(uint8_t *dst, intpcm_t v, uint32_t fmt) 272 { 273 intpcm_t r, e; 274 275 fmt = AFMT_ENCODING(fmt); 276 277 if (fmt & (AFMT_F32_LE | AFMT_F32_BE)) { 278 if (v == 0) 279 r = 0; 280 else if (v == PCM_S32_MAX) 281 r = 0x3f800000; 282 else if (v == PCM_S32_MIN) 283 r = 0x80000000U | 0x3f800000; 284 else { 285 r = 0; 286 if (v < 0) { 287 r |= 0x80000000U; 288 v = -v; 289 } 290 e = 127 - 8; 291 while ((v & 0x7f000000) != 0) { 292 v >>= 1; 293 e++; 294 } 295 while ((v & 0x7f800000) == 0) { 296 v <<= 1; 297 e--; 298 } 299 r |= (e & 0xff) << 23; 300 r |= v & 0x7fffff; 301 } 302 v = r; 303 } 304 305 switch (fmt) { 306 case AFMT_AC3: 307 *(int16_t *)dst = 0; 308 break; 309 case AFMT_MU_LAW: 310 *dst = _INTPCM_TO_G711(xlaw_conv_tables.u8_to_ulaw, v); 311 break; 312 case AFMT_A_LAW: 313 *dst = _INTPCM_TO_G711(xlaw_conv_tables.u8_to_alaw, v); 314 break; 315 case AFMT_S8: 316 *(int8_t *)dst = v; 317 break; 318 case AFMT_U8: 319 *(int8_t *)dst = v ^ 0x80; 320 break; 321 case AFMT_S16_LE: 322 dst[0] = v; 323 dst[1] = v >> 8; 324 break; 325 case AFMT_S16_BE: 326 dst[1] = v; 327 dst[0] = v >> 8; 328 break; 329 case AFMT_U16_LE: 330 dst[0] = v; 331 dst[1] = (v >> 8) ^ 0x80; 332 break; 333 case AFMT_U16_BE: 334 dst[1] = v; 335 dst[0] = (v >> 8) ^ 0x80; 336 break; 337 case AFMT_S24_LE: 338 dst[0] = v; 339 dst[1] = v >> 8; 340 dst[2] = v >> 16; 341 break; 342 case AFMT_S24_BE: 343 dst[2] = v; 344 dst[1] = v >> 8; 345 dst[0] = v >> 16; 346 break; 347 case AFMT_U24_LE: 348 dst[0] = v; 349 dst[1] = v >> 8; 350 dst[2] = (v >> 16) ^ 0x80; 351 break; 352 case AFMT_U24_BE: 353 dst[2] = v; 354 dst[1] = v >> 8; 355 dst[0] = (v >> 16) ^ 0x80; 356 break; 357 case AFMT_S32_LE: /* FALLTHROUGH */ 358 case AFMT_F32_LE: 359 dst[0] = v; 360 dst[1] = v >> 8; 361 dst[2] = v >> 16; 362 dst[3] = v >> 24; 363 break; 364 case AFMT_S32_BE: /* FALLTHROUGH */ 365 case AFMT_F32_BE: 366 dst[3] = v; 367 dst[2] = v >> 8; 368 dst[1] = v >> 16; 369 dst[0] = v >> 24; 370 break; 371 case AFMT_U32_LE: 372 dst[0] = v; 373 dst[1] = v >> 8; 374 dst[2] = v >> 16; 375 dst[3] = (v >> 24) ^ 0x80; 376 break; 377 case AFMT_U32_BE: 378 dst[3] = v; 379 dst[2] = v >> 8; 380 dst[1] = v >> 16; 381 dst[0] = (v >> 24) ^ 0x80; 382 break; 383 default: 384 printf("%s(): unknown format: 0x%08x\n", __func__, fmt); 385 __assert_unreachable(); 386 } 387 } 388 389 /* 390 * Write sample and normalize to original magnitude. 391 */ 392 static __always_inline __unused void 393 pcm_sample_write_norm(uint8_t *dst, intpcm_t v, uint32_t fmt) 394 { 395 pcm_sample_write(dst, v >> (32 - AFMT_BIT(fmt)), fmt); 396 } 397 398 /* 399 * To be used with pcm_sample_read_calc(). 400 */ 401 static __always_inline __unused void 402 pcm_sample_write_calc(uint8_t *dst, intpcm_t v, uint32_t fmt) 403 { 404 #ifndef SND_PCM_64 405 /* Shift back to 32-bit magnitude. */ 406 if (fmt & AFMT_32BIT) 407 v <<= PCM_FXSHIFT; 408 #endif 409 pcm_sample_write(dst, v, fmt); 410 } 411 412 static __always_inline __unused intpcm_t 413 pcm_clamp(intpcm32_t sample, uint32_t fmt) 414 { 415 fmt = AFMT_ENCODING(fmt); 416 417 switch (AFMT_BIT(fmt)) { 418 case 8: 419 return ((sample > PCM_S8_MAX) ? PCM_S8_MAX : 420 ((sample < PCM_S8_MIN) ? PCM_S8_MIN : sample)); 421 case 16: 422 return ((sample > PCM_S16_MAX) ? PCM_S16_MAX : 423 ((sample < PCM_S16_MIN) ? PCM_S16_MIN : sample)); 424 case 24: 425 return ((sample > PCM_S24_MAX) ? PCM_S24_MAX : 426 ((sample < PCM_S24_MIN) ? PCM_S24_MIN : sample)); 427 case 32: 428 return ((sample > PCM_S32_MAX) ? PCM_S32_MAX : 429 ((sample < PCM_S32_MIN) ? PCM_S32_MIN : sample)); 430 default: 431 printf("%s(): unknown format: 0x%08x\n", __func__, fmt); 432 __assert_unreachable(); 433 } 434 } 435 436 static __always_inline __unused intpcm_t 437 pcm_clamp_calc(intpcm32_t sample, uint32_t fmt) 438 { 439 #ifndef SND_PCM_64 440 if (fmt & AFMT_32BIT) { 441 return ((sample > PCM_S24_MAX) ? PCM_S32_MAX : 442 ((sample < PCM_S24_MIN) ? PCM_S32_MIN : 443 sample << PCM_FXSHIFT)); 444 } 445 #endif 446 447 return (pcm_clamp(sample, fmt)); 448 } 449 450 #endif /* !_SND_PCM_H_ */ 451