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 /* FIXME: the following three formats are not defined properly yet */ 144 [SNDRV_PCM_FORMAT_MPEG] = { 145 .le = -1, .signd = -1, 146 }, 147 [SNDRV_PCM_FORMAT_GSM] = { 148 .le = -1, .signd = -1, 149 }, 150 [SNDRV_PCM_FORMAT_SPECIAL] = { 151 .le = -1, .signd = -1, 152 }, 153 [SNDRV_PCM_FORMAT_S24_3LE] = { 154 .width = 24, .phys = 24, .le = 1, .signd = 1, 155 .silence = {}, 156 }, 157 [SNDRV_PCM_FORMAT_S24_3BE] = { 158 .width = 24, .phys = 24, .le = 0, .signd = 1, 159 .silence = {}, 160 }, 161 [SNDRV_PCM_FORMAT_U24_3LE] = { 162 .width = 24, .phys = 24, .le = 1, .signd = 0, 163 .silence = { 0x00, 0x00, 0x80 }, 164 }, 165 [SNDRV_PCM_FORMAT_U24_3BE] = { 166 .width = 24, .phys = 24, .le = 0, .signd = 0, 167 .silence = { 0x80, 0x00, 0x00 }, 168 }, 169 [SNDRV_PCM_FORMAT_S20_3LE] = { 170 .width = 20, .phys = 24, .le = 1, .signd = 1, 171 .silence = {}, 172 }, 173 [SNDRV_PCM_FORMAT_S20_3BE] = { 174 .width = 20, .phys = 24, .le = 0, .signd = 1, 175 .silence = {}, 176 }, 177 [SNDRV_PCM_FORMAT_U20_3LE] = { 178 .width = 20, .phys = 24, .le = 1, .signd = 0, 179 .silence = { 0x00, 0x00, 0x08 }, 180 }, 181 [SNDRV_PCM_FORMAT_U20_3BE] = { 182 .width = 20, .phys = 24, .le = 0, .signd = 0, 183 .silence = { 0x08, 0x00, 0x00 }, 184 }, 185 [SNDRV_PCM_FORMAT_S18_3LE] = { 186 .width = 18, .phys = 24, .le = 1, .signd = 1, 187 .silence = {}, 188 }, 189 [SNDRV_PCM_FORMAT_S18_3BE] = { 190 .width = 18, .phys = 24, .le = 0, .signd = 1, 191 .silence = {}, 192 }, 193 [SNDRV_PCM_FORMAT_U18_3LE] = { 194 .width = 18, .phys = 24, .le = 1, .signd = 0, 195 .silence = { 0x00, 0x00, 0x02 }, 196 }, 197 [SNDRV_PCM_FORMAT_U18_3BE] = { 198 .width = 18, .phys = 24, .le = 0, .signd = 0, 199 .silence = { 0x02, 0x00, 0x00 }, 200 }, 201 [SNDRV_PCM_FORMAT_G723_24_1B] = { 202 .width = 3, .phys = 8, .le = -1, .signd = -1, 203 .silence = {}, 204 }, 205 [SNDRV_PCM_FORMAT_G723_40_1B] = { 206 .width = 5, .phys = 8, .le = -1, .signd = -1, 207 .silence = {}, 208 }, 209 }; 210 211 212 /** 213 * snd_pcm_format_signed - Check the PCM format is signed linear 214 * @format: the format to check 215 * 216 * Returns 1 if the given PCM format is signed linear, 0 if unsigned 217 * linear, and a negative error code for non-linear formats. 218 */ 219 int snd_pcm_format_signed(snd_pcm_format_t format) 220 { 221 int val; 222 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 223 return -EINVAL; 224 if ((val = pcm_formats[(INT)format].signd) < 0) 225 return -EINVAL; 226 return val; 227 } 228 229 EXPORT_SYMBOL(snd_pcm_format_signed); 230 231 /** 232 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear 233 * @format: the format to check 234 * 235 * Returns 1 if the given PCM format is unsigned linear, 0 if signed 236 * linear, and a negative error code for non-linear formats. 237 */ 238 int snd_pcm_format_unsigned(snd_pcm_format_t format) 239 { 240 int val; 241 242 val = snd_pcm_format_signed(format); 243 if (val < 0) 244 return val; 245 return !val; 246 } 247 248 EXPORT_SYMBOL(snd_pcm_format_unsigned); 249 250 /** 251 * snd_pcm_format_linear - Check the PCM format is linear 252 * @format: the format to check 253 * 254 * Returns 1 if the given PCM format is linear, 0 if not. 255 */ 256 int snd_pcm_format_linear(snd_pcm_format_t format) 257 { 258 return snd_pcm_format_signed(format) >= 0; 259 } 260 261 EXPORT_SYMBOL(snd_pcm_format_linear); 262 263 /** 264 * snd_pcm_format_little_endian - Check the PCM format is little-endian 265 * @format: the format to check 266 * 267 * Returns 1 if the given PCM format is little-endian, 0 if 268 * big-endian, or a negative error code if endian not specified. 269 */ 270 int snd_pcm_format_little_endian(snd_pcm_format_t format) 271 { 272 int val; 273 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 274 return -EINVAL; 275 if ((val = pcm_formats[(INT)format].le) < 0) 276 return -EINVAL; 277 return val; 278 } 279 280 EXPORT_SYMBOL(snd_pcm_format_little_endian); 281 282 /** 283 * snd_pcm_format_big_endian - Check the PCM format is big-endian 284 * @format: the format to check 285 * 286 * Returns 1 if the given PCM format is big-endian, 0 if 287 * little-endian, or a negative error code if endian not specified. 288 */ 289 int snd_pcm_format_big_endian(snd_pcm_format_t format) 290 { 291 int val; 292 293 val = snd_pcm_format_little_endian(format); 294 if (val < 0) 295 return val; 296 return !val; 297 } 298 299 EXPORT_SYMBOL(snd_pcm_format_big_endian); 300 301 /** 302 * snd_pcm_format_width - return the bit-width of the format 303 * @format: the format to check 304 * 305 * Returns the bit-width of the format, or a negative error code 306 * if unknown format. 307 */ 308 int snd_pcm_format_width(snd_pcm_format_t format) 309 { 310 int val; 311 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 312 return -EINVAL; 313 if ((val = pcm_formats[(INT)format].width) == 0) 314 return -EINVAL; 315 return val; 316 } 317 318 EXPORT_SYMBOL(snd_pcm_format_width); 319 320 /** 321 * snd_pcm_format_physical_width - return the physical bit-width of the format 322 * @format: the format to check 323 * 324 * Returns the physical bit-width of the format, or a negative error code 325 * if unknown format. 326 */ 327 int snd_pcm_format_physical_width(snd_pcm_format_t format) 328 { 329 int val; 330 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 331 return -EINVAL; 332 if ((val = pcm_formats[(INT)format].phys) == 0) 333 return -EINVAL; 334 return val; 335 } 336 337 EXPORT_SYMBOL(snd_pcm_format_physical_width); 338 339 /** 340 * snd_pcm_format_size - return the byte size of samples on the given format 341 * @format: the format to check 342 * @samples: sampling rate 343 * 344 * Returns the byte size of the given samples for the format, or a 345 * negative error code if unknown format. 346 */ 347 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples) 348 { 349 int phys_width = snd_pcm_format_physical_width(format); 350 if (phys_width < 0) 351 return -EINVAL; 352 return samples * phys_width / 8; 353 } 354 355 EXPORT_SYMBOL(snd_pcm_format_size); 356 357 /** 358 * snd_pcm_format_silence_64 - return the silent data in 8 bytes array 359 * @format: the format to check 360 * 361 * Returns the format pattern to fill or NULL if error. 362 */ 363 const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format) 364 { 365 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 366 return NULL; 367 if (! pcm_formats[(INT)format].phys) 368 return NULL; 369 return pcm_formats[(INT)format].silence; 370 } 371 372 EXPORT_SYMBOL(snd_pcm_format_silence_64); 373 374 /** 375 * snd_pcm_format_set_silence - set the silence data on the buffer 376 * @format: the PCM format 377 * @data: the buffer pointer 378 * @samples: the number of samples to set silence 379 * 380 * Sets the silence data on the buffer for the given samples. 381 * 382 * Returns zero if successful, or a negative error code on failure. 383 */ 384 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples) 385 { 386 int width; 387 unsigned char *dst, *pat; 388 389 if ((INT)format < 0 || (INT)format > (INT)SNDRV_PCM_FORMAT_LAST) 390 return -EINVAL; 391 if (samples == 0) 392 return 0; 393 width = pcm_formats[(INT)format].phys; /* physical width */ 394 pat = pcm_formats[(INT)format].silence; 395 if (! width) 396 return -EINVAL; 397 /* signed or 1 byte data */ 398 if (pcm_formats[(INT)format].signd == 1 || width <= 8) { 399 unsigned int bytes = samples * width / 8; 400 memset(data, *pat, bytes); 401 return 0; 402 } 403 /* non-zero samples, fill using a loop */ 404 width /= 8; 405 dst = data; 406 #if 0 407 while (samples--) { 408 memcpy(dst, pat, width); 409 dst += width; 410 } 411 #else 412 /* a bit optimization for constant width */ 413 switch (width) { 414 case 2: 415 while (samples--) { 416 memcpy(dst, pat, 2); 417 dst += 2; 418 } 419 break; 420 case 3: 421 while (samples--) { 422 memcpy(dst, pat, 3); 423 dst += 3; 424 } 425 break; 426 case 4: 427 while (samples--) { 428 memcpy(dst, pat, 4); 429 dst += 4; 430 } 431 break; 432 case 8: 433 while (samples--) { 434 memcpy(dst, pat, 8); 435 dst += 8; 436 } 437 break; 438 } 439 #endif 440 return 0; 441 } 442 443 EXPORT_SYMBOL(snd_pcm_format_set_silence); 444 445 /** 446 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields 447 * @runtime: the runtime instance 448 * 449 * Determines the rate_min and rate_max fields from the rates bits of 450 * the given runtime->hw. 451 * 452 * Returns zero if successful. 453 */ 454 int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime) 455 { 456 int i; 457 for (i = 0; i < (int)snd_pcm_known_rates.count; i++) { 458 if (runtime->hw.rates & (1 << i)) { 459 runtime->hw.rate_min = snd_pcm_known_rates.list[i]; 460 break; 461 } 462 } 463 for (i = (int)snd_pcm_known_rates.count - 1; i >= 0; i--) { 464 if (runtime->hw.rates & (1 << i)) { 465 runtime->hw.rate_max = snd_pcm_known_rates.list[i]; 466 break; 467 } 468 } 469 return 0; 470 } 471 472 EXPORT_SYMBOL(snd_pcm_limit_hw_rates); 473 474 /** 475 * snd_pcm_rate_to_rate_bit - converts sample rate to SNDRV_PCM_RATE_xxx bit 476 * @rate: the sample rate to convert 477 * 478 * Returns the SNDRV_PCM_RATE_xxx flag that corresponds to the given rate, or 479 * SNDRV_PCM_RATE_KNOT for an unknown rate. 480 */ 481 unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate) 482 { 483 unsigned int i; 484 485 for (i = 0; i < snd_pcm_known_rates.count; i++) 486 if (snd_pcm_known_rates.list[i] == rate) 487 return 1u << i; 488 return SNDRV_PCM_RATE_KNOT; 489 } 490 EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); 491 492 /** 493 * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate 494 * @rate_bit: the rate bit to convert 495 * 496 * Returns the sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag 497 * or 0 for an unknown rate bit 498 */ 499 unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) 500 { 501 unsigned int i; 502 503 for (i = 0; i < snd_pcm_known_rates.count; i++) 504 if ((1u << i) == rate_bit) 505 return snd_pcm_known_rates.list[i]; 506 return 0; 507 } 508 EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate); 509