1 // SPDX-License-Identifier: LGPL-2.0+ 2 /* 3 * PCM Interface - misc routines 4 * Copyright (c) 1998 by Jaroslav Kysela <perex@perex.cz> 5 */ 6 7 #include <linux/time.h> 8 #include <linux/export.h> 9 #include <sound/core.h> 10 #include <sound/pcm.h> 11 12 #include "pcm_local.h" 13 14 #define SND_PCM_FORMAT_UNKNOWN (-1) 15 16 /* NOTE: "signed" prefix must be given below since the default char is 17 * unsigned on some architectures! 18 */ 19 struct pcm_format_data { 20 unsigned char width; /* bit width */ 21 unsigned char phys; /* physical bit width */ 22 signed char le; /* 0 = big-endian, 1 = little-endian, -1 = others */ 23 signed char signd; /* 0 = unsigned, 1 = signed, -1 = others */ 24 unsigned char silence[8]; /* silence data to fill */ 25 }; 26 27 static bool valid_format(snd_pcm_format_t format) 28 { 29 return format >= 0 && format <= SNDRV_PCM_FORMAT_LAST; 30 } 31 32 static const struct pcm_format_data pcm_formats[SNDRV_PCM_FORMAT_LAST+1] = { 33 [SNDRV_PCM_FORMAT_S8] = { 34 .width = 8, .phys = 8, .le = -1, .signd = 1, 35 .silence = {}, 36 }, 37 [SNDRV_PCM_FORMAT_U8] = { 38 .width = 8, .phys = 8, .le = -1, .signd = 0, 39 .silence = { 0x80 }, 40 }, 41 [SNDRV_PCM_FORMAT_S16_LE] = { 42 .width = 16, .phys = 16, .le = 1, .signd = 1, 43 .silence = {}, 44 }, 45 [SNDRV_PCM_FORMAT_S16_BE] = { 46 .width = 16, .phys = 16, .le = 0, .signd = 1, 47 .silence = {}, 48 }, 49 [SNDRV_PCM_FORMAT_U16_LE] = { 50 .width = 16, .phys = 16, .le = 1, .signd = 0, 51 .silence = { 0x00, 0x80 }, 52 }, 53 [SNDRV_PCM_FORMAT_U16_BE] = { 54 .width = 16, .phys = 16, .le = 0, .signd = 0, 55 .silence = { 0x80, 0x00 }, 56 }, 57 [SNDRV_PCM_FORMAT_S24_LE] = { 58 .width = 24, .phys = 32, .le = 1, .signd = 1, 59 .silence = {}, 60 }, 61 [SNDRV_PCM_FORMAT_S24_BE] = { 62 .width = 24, .phys = 32, .le = 0, .signd = 1, 63 .silence = {}, 64 }, 65 [SNDRV_PCM_FORMAT_U24_LE] = { 66 .width = 24, .phys = 32, .le = 1, .signd = 0, 67 .silence = { 0x00, 0x00, 0x80 }, 68 }, 69 [SNDRV_PCM_FORMAT_U24_BE] = { 70 .width = 24, .phys = 32, .le = 0, .signd = 0, 71 .silence = { 0x00, 0x80, 0x00, 0x00 }, 72 }, 73 [SNDRV_PCM_FORMAT_S32_LE] = { 74 .width = 32, .phys = 32, .le = 1, .signd = 1, 75 .silence = {}, 76 }, 77 [SNDRV_PCM_FORMAT_S32_BE] = { 78 .width = 32, .phys = 32, .le = 0, .signd = 1, 79 .silence = {}, 80 }, 81 [SNDRV_PCM_FORMAT_U32_LE] = { 82 .width = 32, .phys = 32, .le = 1, .signd = 0, 83 .silence = { 0x00, 0x00, 0x00, 0x80 }, 84 }, 85 [SNDRV_PCM_FORMAT_U32_BE] = { 86 .width = 32, .phys = 32, .le = 0, .signd = 0, 87 .silence = { 0x80, 0x00, 0x00, 0x00 }, 88 }, 89 [SNDRV_PCM_FORMAT_FLOAT_LE] = { 90 .width = 32, .phys = 32, .le = 1, .signd = -1, 91 .silence = {}, 92 }, 93 [SNDRV_PCM_FORMAT_FLOAT_BE] = { 94 .width = 32, .phys = 32, .le = 0, .signd = -1, 95 .silence = {}, 96 }, 97 [SNDRV_PCM_FORMAT_FLOAT64_LE] = { 98 .width = 64, .phys = 64, .le = 1, .signd = -1, 99 .silence = {}, 100 }, 101 [SNDRV_PCM_FORMAT_FLOAT64_BE] = { 102 .width = 64, .phys = 64, .le = 0, .signd = -1, 103 .silence = {}, 104 }, 105 [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE] = { 106 .width = 32, .phys = 32, .le = 1, .signd = -1, 107 .silence = {}, 108 }, 109 [SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE] = { 110 .width = 32, .phys = 32, .le = 0, .signd = -1, 111 .silence = {}, 112 }, 113 [SNDRV_PCM_FORMAT_MU_LAW] = { 114 .width = 8, .phys = 8, .le = -1, .signd = -1, 115 .silence = { 0x7f }, 116 }, 117 [SNDRV_PCM_FORMAT_A_LAW] = { 118 .width = 8, .phys = 8, .le = -1, .signd = -1, 119 .silence = { 0x55 }, 120 }, 121 [SNDRV_PCM_FORMAT_IMA_ADPCM] = { 122 .width = 4, .phys = 4, .le = -1, .signd = -1, 123 .silence = {}, 124 }, 125 [SNDRV_PCM_FORMAT_G723_24] = { 126 .width = 3, .phys = 3, .le = -1, .signd = -1, 127 .silence = {}, 128 }, 129 [SNDRV_PCM_FORMAT_G723_40] = { 130 .width = 5, .phys = 5, .le = -1, .signd = -1, 131 .silence = {}, 132 }, 133 [SNDRV_PCM_FORMAT_DSD_U8] = { 134 .width = 8, .phys = 8, .le = 1, .signd = 0, 135 .silence = { 0x69 }, 136 }, 137 [SNDRV_PCM_FORMAT_DSD_U16_LE] = { 138 .width = 16, .phys = 16, .le = 1, .signd = 0, 139 .silence = { 0x69, 0x69 }, 140 }, 141 [SNDRV_PCM_FORMAT_DSD_U32_LE] = { 142 .width = 32, .phys = 32, .le = 1, .signd = 0, 143 .silence = { 0x69, 0x69, 0x69, 0x69 }, 144 }, 145 [SNDRV_PCM_FORMAT_DSD_U16_BE] = { 146 .width = 16, .phys = 16, .le = 0, .signd = 0, 147 .silence = { 0x69, 0x69 }, 148 }, 149 [SNDRV_PCM_FORMAT_DSD_U32_BE] = { 150 .width = 32, .phys = 32, .le = 0, .signd = 0, 151 .silence = { 0x69, 0x69, 0x69, 0x69 }, 152 }, 153 /* FIXME: the following two formats are not defined properly yet */ 154 [SNDRV_PCM_FORMAT_MPEG] = { 155 .le = -1, .signd = -1, 156 }, 157 [SNDRV_PCM_FORMAT_GSM] = { 158 .le = -1, .signd = -1, 159 }, 160 [SNDRV_PCM_FORMAT_S20_LE] = { 161 .width = 20, .phys = 32, .le = 1, .signd = 1, 162 .silence = {}, 163 }, 164 [SNDRV_PCM_FORMAT_S20_BE] = { 165 .width = 20, .phys = 32, .le = 0, .signd = 1, 166 .silence = {}, 167 }, 168 [SNDRV_PCM_FORMAT_U20_LE] = { 169 .width = 20, .phys = 32, .le = 1, .signd = 0, 170 .silence = { 0x00, 0x00, 0x08, 0x00 }, 171 }, 172 [SNDRV_PCM_FORMAT_U20_BE] = { 173 .width = 20, .phys = 32, .le = 0, .signd = 0, 174 .silence = { 0x00, 0x08, 0x00, 0x00 }, 175 }, 176 /* FIXME: the following format is not defined properly yet */ 177 [SNDRV_PCM_FORMAT_SPECIAL] = { 178 .le = -1, .signd = -1, 179 }, 180 [SNDRV_PCM_FORMAT_S24_3LE] = { 181 .width = 24, .phys = 24, .le = 1, .signd = 1, 182 .silence = {}, 183 }, 184 [SNDRV_PCM_FORMAT_S24_3BE] = { 185 .width = 24, .phys = 24, .le = 0, .signd = 1, 186 .silence = {}, 187 }, 188 [SNDRV_PCM_FORMAT_U24_3LE] = { 189 .width = 24, .phys = 24, .le = 1, .signd = 0, 190 .silence = { 0x00, 0x00, 0x80 }, 191 }, 192 [SNDRV_PCM_FORMAT_U24_3BE] = { 193 .width = 24, .phys = 24, .le = 0, .signd = 0, 194 .silence = { 0x80, 0x00, 0x00 }, 195 }, 196 [SNDRV_PCM_FORMAT_S20_3LE] = { 197 .width = 20, .phys = 24, .le = 1, .signd = 1, 198 .silence = {}, 199 }, 200 [SNDRV_PCM_FORMAT_S20_3BE] = { 201 .width = 20, .phys = 24, .le = 0, .signd = 1, 202 .silence = {}, 203 }, 204 [SNDRV_PCM_FORMAT_U20_3LE] = { 205 .width = 20, .phys = 24, .le = 1, .signd = 0, 206 .silence = { 0x00, 0x00, 0x08 }, 207 }, 208 [SNDRV_PCM_FORMAT_U20_3BE] = { 209 .width = 20, .phys = 24, .le = 0, .signd = 0, 210 .silence = { 0x08, 0x00, 0x00 }, 211 }, 212 [SNDRV_PCM_FORMAT_S18_3LE] = { 213 .width = 18, .phys = 24, .le = 1, .signd = 1, 214 .silence = {}, 215 }, 216 [SNDRV_PCM_FORMAT_S18_3BE] = { 217 .width = 18, .phys = 24, .le = 0, .signd = 1, 218 .silence = {}, 219 }, 220 [SNDRV_PCM_FORMAT_U18_3LE] = { 221 .width = 18, .phys = 24, .le = 1, .signd = 0, 222 .silence = { 0x00, 0x00, 0x02 }, 223 }, 224 [SNDRV_PCM_FORMAT_U18_3BE] = { 225 .width = 18, .phys = 24, .le = 0, .signd = 0, 226 .silence = { 0x02, 0x00, 0x00 }, 227 }, 228 [SNDRV_PCM_FORMAT_G723_24_1B] = { 229 .width = 3, .phys = 8, .le = -1, .signd = -1, 230 .silence = {}, 231 }, 232 [SNDRV_PCM_FORMAT_G723_40_1B] = { 233 .width = 5, .phys = 8, .le = -1, .signd = -1, 234 .silence = {}, 235 }, 236 }; 237 238 239 /** 240 * snd_pcm_format_signed - Check the PCM format is signed linear 241 * @format: the format to check 242 * 243 * Return: 1 if the given PCM format is signed linear, 0 if unsigned 244 * linear, and a negative error code for non-linear formats. 245 */ 246 int snd_pcm_format_signed(snd_pcm_format_t format) 247 { 248 int val; 249 if (!valid_format(format)) 250 return -EINVAL; 251 val = pcm_formats[format].signd; 252 if (val < 0) 253 return -EINVAL; 254 return val; 255 } 256 EXPORT_SYMBOL(snd_pcm_format_signed); 257 258 /** 259 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear 260 * @format: the format to check 261 * 262 * Return: 1 if the given PCM format is unsigned linear, 0 if signed 263 * linear, and a negative error code for non-linear formats. 264 */ 265 int snd_pcm_format_unsigned(snd_pcm_format_t format) 266 { 267 int val; 268 269 val = snd_pcm_format_signed(format); 270 if (val < 0) 271 return val; 272 return !val; 273 } 274 EXPORT_SYMBOL(snd_pcm_format_unsigned); 275 276 /** 277 * snd_pcm_format_linear - Check the PCM format is linear 278 * @format: the format to check 279 * 280 * Return: 1 if the given PCM format is linear, 0 if not. 281 */ 282 int snd_pcm_format_linear(snd_pcm_format_t format) 283 { 284 return snd_pcm_format_signed(format) >= 0; 285 } 286 EXPORT_SYMBOL(snd_pcm_format_linear); 287 288 /** 289 * snd_pcm_format_little_endian - Check the PCM format is little-endian 290 * @format: the format to check 291 * 292 * Return: 1 if the given PCM format is little-endian, 0 if 293 * big-endian, or a negative error code if endian not specified. 294 */ 295 int snd_pcm_format_little_endian(snd_pcm_format_t format) 296 { 297 int val; 298 if (!valid_format(format)) 299 return -EINVAL; 300 val = pcm_formats[format].le; 301 if (val < 0) 302 return -EINVAL; 303 return val; 304 } 305 EXPORT_SYMBOL(snd_pcm_format_little_endian); 306 307 /** 308 * snd_pcm_format_big_endian - Check the PCM format is big-endian 309 * @format: the format to check 310 * 311 * Return: 1 if the given PCM format is big-endian, 0 if 312 * little-endian, or a negative error code if endian not specified. 313 */ 314 int snd_pcm_format_big_endian(snd_pcm_format_t format) 315 { 316 int val; 317 318 val = snd_pcm_format_little_endian(format); 319 if (val < 0) 320 return val; 321 return !val; 322 } 323 EXPORT_SYMBOL(snd_pcm_format_big_endian); 324 325 /** 326 * snd_pcm_format_width - return the bit-width of the format 327 * @format: the format to check 328 * 329 * Return: The bit-width of the format, or a negative error code 330 * if unknown format. 331 */ 332 int snd_pcm_format_width(snd_pcm_format_t format) 333 { 334 int val; 335 if (!valid_format(format)) 336 return -EINVAL; 337 val = pcm_formats[format].width; 338 if (!val) 339 return -EINVAL; 340 return val; 341 } 342 EXPORT_SYMBOL(snd_pcm_format_width); 343 344 /** 345 * snd_pcm_format_physical_width - return the physical bit-width of the format 346 * @format: the format to check 347 * 348 * Return: The physical bit-width of the format, or a negative error code 349 * if unknown format. 350 */ 351 int snd_pcm_format_physical_width(snd_pcm_format_t format) 352 { 353 int val; 354 if (!valid_format(format)) 355 return -EINVAL; 356 val = pcm_formats[format].phys; 357 if (!val) 358 return -EINVAL; 359 return val; 360 } 361 EXPORT_SYMBOL(snd_pcm_format_physical_width); 362 363 /** 364 * snd_pcm_format_size - return the byte size of samples on the given format 365 * @format: the format to check 366 * @samples: sampling rate 367 * 368 * Return: The byte size of the given samples for the format, or a 369 * negative error code if unknown format. 370 */ 371 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples) 372 { 373 int phys_width = snd_pcm_format_physical_width(format); 374 if (phys_width < 0) 375 return -EINVAL; 376 return samples * phys_width / 8; 377 } 378 EXPORT_SYMBOL(snd_pcm_format_size); 379 380 /** 381 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array 382 * @format: the format to check 383 * 384 * Return: The format pattern to fill or %NULL if error. 385 */ 386 const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) 387 { 388 if (!valid_format(format)) 389 return NULL; 390 if (! pcm_formats[format].phys) 391 return NULL; 392 return pcm_formats[format].silence; 393 } 394 EXPORT_SYMBOL(snd_pcm_format_silence_64); 395 396 /** 397 * snd_pcm_format_set_silence - set the silence data on the buffer 398 * @format: the PCM format 399 * @data: the buffer pointer 400 * @samples: the number of samples to set silence 401 * 402 * Sets the silence data on the buffer for the given samples. 403 * 404 * Return: Zero if successful, or a negative error code on failure. 405 */ 406 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples) 407 { 408 int width; 409 unsigned char *dst; 410 const unsigned char *pat; 411 412 if (!valid_format(format)) 413 return -EINVAL; 414 if (samples == 0) 415 return 0; 416 width = pcm_formats[format].phys; /* physical width */ 417 if (!width) 418 return -EINVAL; 419 pat = pcm_formats[format].silence; 420 /* signed or 1 byte data */ 421 if (pcm_formats[format].signd == 1 || width <= 8) { 422 unsigned int bytes = samples * width / 8; 423 memset(data, *pat, bytes); 424 return 0; 425 } 426 /* non-zero samples, fill using a loop */ 427 width /= 8; 428 dst = data; 429 #if 0 430 while (samples--) { 431 memcpy(dst, pat, width); 432 dst += width; 433 } 434 #else 435 /* a bit optimization for constant width */ 436 switch (width) { 437 case 2: 438 while (samples--) { 439 memcpy(dst, pat, 2); 440 dst += 2; 441 } 442 break; 443 case 3: 444 while (samples--) { 445 memcpy(dst, pat, 3); 446 dst += 3; 447 } 448 break; 449 case 4: 450 while (samples--) { 451 memcpy(dst, pat, 4); 452 dst += 4; 453 } 454 break; 455 case 8: 456 while (samples--) { 457 memcpy(dst, pat, 8); 458 dst += 8; 459 } 460 break; 461 } 462 #endif 463 return 0; 464 } 465 EXPORT_SYMBOL(snd_pcm_format_set_silence); 466 467 /** 468 * snd_pcm_hw_limit_rates - determine rate_min/rate_max fields 469 * @hw: the pcm hw instance 470 * 471 * Determines the rate_min and rate_max fields from the rates bits of 472 * the given hw. 473 * 474 * Return: Zero if successful. 475 */ 476 int snd_pcm_hw_limit_rates(struct snd_pcm_hardware *hw) 477 { 478 int i; 479 unsigned int rmin, rmax; 480 481 rmin = UINT_MAX; 482 rmax = 0; 483 for (i = 0; i < (int)snd_pcm_known_rates.count; i++) { 484 if (hw->rates & (1 << i)) { 485 rmin = min(rmin, snd_pcm_known_rates.list[i]); 486 rmax = max(rmax, snd_pcm_known_rates.list[i]); 487 } 488 } 489 if (rmin > rmax) 490 return -EINVAL; 491 hw->rate_min = rmin; 492 hw->rate_max = rmax; 493 return 0; 494 } 495 EXPORT_SYMBOL(snd_pcm_hw_limit_rates); 496 497 /** 498 * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit 499 * @rate: the sample rate to convert 500 * 501 * Return: The SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or 502 * SNDRV_PCM_RATE_KNOT for an unknown rate. 503 */ 504 unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate) 505 { 506 unsigned int i; 507 508 for (i = 0; i < snd_pcm_known_rates.count; i++) 509 if (snd_pcm_known_rates.list[i] == rate) 510 return 1u << i; 511 return SNDRV_PCM_RATE_KNOT; 512 } 513 EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); 514 515 /** 516 * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate 517 * @rate_bit: the rate bit to convert 518 * 519 * Return: The sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag 520 * or 0 for an unknown rate bit. 521 */ 522 unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) 523 { 524 unsigned int i; 525 526 for (i = 0; i < snd_pcm_known_rates.count; i++) 527 if ((1u << i) == rate_bit) 528 return snd_pcm_known_rates.list[i]; 529 return 0; 530 } 531 EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate); 532 533 static unsigned int snd_pcm_rate_mask_sanitize(unsigned int rates) 534 { 535 if (rates & SNDRV_PCM_RATE_CONTINUOUS) 536 return SNDRV_PCM_RATE_CONTINUOUS; 537 else if (rates & SNDRV_PCM_RATE_KNOT) 538 return SNDRV_PCM_RATE_KNOT; 539 return rates; 540 } 541 542 /** 543 * snd_pcm_rate_mask_intersect - computes the intersection between two rate masks 544 * @rates_a: The first rate mask 545 * @rates_b: The second rate mask 546 * 547 * This function computes the rates that are supported by both rate masks passed 548 * to the function. It will take care of the special handling of 549 * SNDRV_PCM_RATE_CONTINUOUS and SNDRV_PCM_RATE_KNOT. 550 * 551 * Return: A rate mask containing the rates that are supported by both rates_a 552 * and rates_b. 553 */ 554 unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, 555 unsigned int rates_b) 556 { 557 rates_a = snd_pcm_rate_mask_sanitize(rates_a); 558 rates_b = snd_pcm_rate_mask_sanitize(rates_b); 559 560 if (rates_a & SNDRV_PCM_RATE_CONTINUOUS) 561 return rates_b; 562 else if (rates_b & SNDRV_PCM_RATE_CONTINUOUS) 563 return rates_a; 564 else if (rates_a & SNDRV_PCM_RATE_KNOT) 565 return rates_b; 566 else if (rates_b & SNDRV_PCM_RATE_KNOT) 567 return rates_a; 568 return rates_a & rates_b; 569 } 570 EXPORT_SYMBOL_GPL(snd_pcm_rate_mask_intersect); 571