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