2 * PCM Interface - misc routines
3 * Copyright (c) 1998 by Jaroslav Kysela <perex@suse.cz>
6 * This library is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
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 Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser 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
27 #include "pcm_local.h"
31 * \brief Return sign info for a PCM sample linear format
32 * \param format Format
33 * \return 0 unsigned, 1 signed, a negative error code if format is not linear
35 int snd_pcm_format_signed(snd_pcm_format_t format)
38 case SNDRV_PCM_FORMAT_S8:
39 case SNDRV_PCM_FORMAT_S16_LE:
40 case SNDRV_PCM_FORMAT_S16_BE:
41 case SNDRV_PCM_FORMAT_S24_LE:
42 case SNDRV_PCM_FORMAT_S24_BE:
43 case SNDRV_PCM_FORMAT_S32_LE:
44 case SNDRV_PCM_FORMAT_S32_BE:
45 case SNDRV_PCM_FORMAT_S24_3LE:
46 case SNDRV_PCM_FORMAT_S24_3BE:
47 case SNDRV_PCM_FORMAT_S20_3LE:
48 case SNDRV_PCM_FORMAT_S20_3BE:
49 case SNDRV_PCM_FORMAT_S18_3LE:
50 case SNDRV_PCM_FORMAT_S18_3BE:
52 case SNDRV_PCM_FORMAT_U8:
53 case SNDRV_PCM_FORMAT_U16_LE:
54 case SNDRV_PCM_FORMAT_U16_BE:
55 case SNDRV_PCM_FORMAT_U24_LE:
56 case SNDRV_PCM_FORMAT_U24_BE:
57 case SNDRV_PCM_FORMAT_U32_LE:
58 case SNDRV_PCM_FORMAT_U32_BE:
59 case SNDRV_PCM_FORMAT_U24_3LE:
60 case SNDRV_PCM_FORMAT_U24_3BE:
61 case SNDRV_PCM_FORMAT_U20_3LE:
62 case SNDRV_PCM_FORMAT_U20_3BE:
63 case SNDRV_PCM_FORMAT_U18_3LE:
64 case SNDRV_PCM_FORMAT_U18_3BE:
72 * \brief Return sign info for a PCM sample linear format
73 * \param format Format
74 * \return 0 signed, 1 unsigned, a negative error code if format is not linear
76 int snd_pcm_format_unsigned(snd_pcm_format_t format)
80 val = snd_pcm_format_signed(format);
87 * \brief Return linear info for a PCM sample format
88 * \param format Format
89 * \return 0 non linear, 1 linear
91 int snd_pcm_format_linear(snd_pcm_format_t format)
93 return snd_pcm_format_signed(format) >= 0;
97 * \brief Return float info for a PCM sample format
98 * \param format Format
99 * \return 0 non float, 1 float
101 int snd_pcm_format_float(snd_pcm_format_t format)
104 case SNDRV_PCM_FORMAT_FLOAT_LE:
105 case SNDRV_PCM_FORMAT_FLOAT_BE:
106 case SNDRV_PCM_FORMAT_FLOAT64_LE:
107 case SNDRV_PCM_FORMAT_FLOAT64_BE:
115 * \brief Return endian info for a PCM sample format
116 * \param format Format
117 * \return 0 big endian, 1 little endian, a negative error code if endian independent
119 int snd_pcm_format_little_endian(snd_pcm_format_t format)
122 case SNDRV_PCM_FORMAT_S16_LE:
123 case SNDRV_PCM_FORMAT_U16_LE:
124 case SNDRV_PCM_FORMAT_S24_LE:
125 case SNDRV_PCM_FORMAT_U24_LE:
126 case SNDRV_PCM_FORMAT_S32_LE:
127 case SNDRV_PCM_FORMAT_U32_LE:
128 case SNDRV_PCM_FORMAT_FLOAT_LE:
129 case SNDRV_PCM_FORMAT_FLOAT64_LE:
130 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
131 case SNDRV_PCM_FORMAT_S24_3LE:
132 case SNDRV_PCM_FORMAT_S20_3LE:
133 case SNDRV_PCM_FORMAT_S18_3LE:
134 case SNDRV_PCM_FORMAT_U24_3LE:
135 case SNDRV_PCM_FORMAT_U20_3LE:
136 case SNDRV_PCM_FORMAT_U18_3LE:
138 case SNDRV_PCM_FORMAT_S16_BE:
139 case SNDRV_PCM_FORMAT_U16_BE:
140 case SNDRV_PCM_FORMAT_S24_BE:
141 case SNDRV_PCM_FORMAT_U24_BE:
142 case SNDRV_PCM_FORMAT_S32_BE:
143 case SNDRV_PCM_FORMAT_U32_BE:
144 case SNDRV_PCM_FORMAT_FLOAT_BE:
145 case SNDRV_PCM_FORMAT_FLOAT64_BE:
146 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
147 case SNDRV_PCM_FORMAT_S24_3BE:
148 case SNDRV_PCM_FORMAT_S20_3BE:
149 case SNDRV_PCM_FORMAT_S18_3BE:
150 case SNDRV_PCM_FORMAT_U24_3BE:
151 case SNDRV_PCM_FORMAT_U20_3BE:
152 case SNDRV_PCM_FORMAT_U18_3BE:
160 * \brief Return endian info for a PCM sample format
161 * \param format Format
162 * \return 0 little endian, 1 big endian, a negative error code if endian independent
164 int snd_pcm_format_big_endian(snd_pcm_format_t format)
168 val = snd_pcm_format_little_endian(format);
175 * \brief Return endian info for a PCM sample format
176 * \param format Format
177 * \return 0 swapped, 1 CPU endian, a negative error code if endian independent
179 int snd_pcm_format_cpu_endian(snd_pcm_format_t format)
181 #ifdef SNDRV_LITTLE_ENDIAN
182 return snd_pcm_format_little_endian(format);
184 return snd_pcm_format_big_endian(format);
189 * \brief Return nominal bits per a PCM sample
190 * \param format Sample format
191 * \return bits per sample, a negative error code if not applicable
193 int snd_pcm_format_width(snd_pcm_format_t format)
196 case SNDRV_PCM_FORMAT_S8:
197 case SNDRV_PCM_FORMAT_U8:
199 case SNDRV_PCM_FORMAT_S16_LE:
200 case SNDRV_PCM_FORMAT_S16_BE:
201 case SNDRV_PCM_FORMAT_U16_LE:
202 case SNDRV_PCM_FORMAT_U16_BE:
204 case SNDRV_PCM_FORMAT_S18_3LE:
205 case SNDRV_PCM_FORMAT_S18_3BE:
206 case SNDRV_PCM_FORMAT_U18_3LE:
207 case SNDRV_PCM_FORMAT_U18_3BE:
209 case SNDRV_PCM_FORMAT_S20_3LE:
210 case SNDRV_PCM_FORMAT_S20_3BE:
211 case SNDRV_PCM_FORMAT_U20_3LE:
212 case SNDRV_PCM_FORMAT_U20_3BE:
214 case SNDRV_PCM_FORMAT_S24_LE:
215 case SNDRV_PCM_FORMAT_S24_BE:
216 case SNDRV_PCM_FORMAT_U24_LE:
217 case SNDRV_PCM_FORMAT_U24_BE:
218 case SNDRV_PCM_FORMAT_S24_3LE:
219 case SNDRV_PCM_FORMAT_S24_3BE:
220 case SNDRV_PCM_FORMAT_U24_3LE:
221 case SNDRV_PCM_FORMAT_U24_3BE:
223 case SNDRV_PCM_FORMAT_S32_LE:
224 case SNDRV_PCM_FORMAT_S32_BE:
225 case SNDRV_PCM_FORMAT_U32_LE:
226 case SNDRV_PCM_FORMAT_U32_BE:
227 case SNDRV_PCM_FORMAT_FLOAT_LE:
228 case SNDRV_PCM_FORMAT_FLOAT_BE:
230 case SNDRV_PCM_FORMAT_FLOAT64_LE:
231 case SNDRV_PCM_FORMAT_FLOAT64_BE:
233 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
234 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
236 case SNDRV_PCM_FORMAT_MU_LAW:
237 case SNDRV_PCM_FORMAT_A_LAW:
239 case SNDRV_PCM_FORMAT_IMA_ADPCM:
247 * \brief Return bits needed to store a PCM sample
248 * \param format Sample format
249 * \return bits per sample, a negative error code if not applicable
251 int snd_pcm_format_physical_width(snd_pcm_format_t format)
254 case SNDRV_PCM_FORMAT_S8:
255 case SNDRV_PCM_FORMAT_U8:
257 case SNDRV_PCM_FORMAT_S16_LE:
258 case SNDRV_PCM_FORMAT_S16_BE:
259 case SNDRV_PCM_FORMAT_U16_LE:
260 case SNDRV_PCM_FORMAT_U16_BE:
262 case SNDRV_PCM_FORMAT_S18_3LE:
263 case SNDRV_PCM_FORMAT_S18_3BE:
264 case SNDRV_PCM_FORMAT_U18_3LE:
265 case SNDRV_PCM_FORMAT_U18_3BE:
266 case SNDRV_PCM_FORMAT_S20_3LE:
267 case SNDRV_PCM_FORMAT_S20_3BE:
268 case SNDRV_PCM_FORMAT_U20_3LE:
269 case SNDRV_PCM_FORMAT_U20_3BE:
270 case SNDRV_PCM_FORMAT_S24_3LE:
271 case SNDRV_PCM_FORMAT_S24_3BE:
272 case SNDRV_PCM_FORMAT_U24_3LE:
273 case SNDRV_PCM_FORMAT_U24_3BE:
275 case SNDRV_PCM_FORMAT_S24_LE:
276 case SNDRV_PCM_FORMAT_S24_BE:
277 case SNDRV_PCM_FORMAT_U24_LE:
278 case SNDRV_PCM_FORMAT_U24_BE:
279 case SNDRV_PCM_FORMAT_S32_LE:
280 case SNDRV_PCM_FORMAT_S32_BE:
281 case SNDRV_PCM_FORMAT_U32_LE:
282 case SNDRV_PCM_FORMAT_U32_BE:
283 case SNDRV_PCM_FORMAT_FLOAT_LE:
284 case SNDRV_PCM_FORMAT_FLOAT_BE:
285 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
286 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
288 case SNDRV_PCM_FORMAT_FLOAT64_LE:
289 case SNDRV_PCM_FORMAT_FLOAT64_BE:
291 case SNDRV_PCM_FORMAT_MU_LAW:
292 case SNDRV_PCM_FORMAT_A_LAW:
294 case SNDRV_PCM_FORMAT_IMA_ADPCM:
302 * \brief Return bytes needed to store a quantity of PCM sample
303 * \param format Sample format
304 * \param samples Samples count
305 * \return bytes needed, a negative error code if not integer or unknown
307 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
310 case SNDRV_PCM_FORMAT_S8:
311 case SNDRV_PCM_FORMAT_U8:
313 case SNDRV_PCM_FORMAT_S16_LE:
314 case SNDRV_PCM_FORMAT_S16_BE:
315 case SNDRV_PCM_FORMAT_U16_LE:
316 case SNDRV_PCM_FORMAT_U16_BE:
318 case SNDRV_PCM_FORMAT_S18_3LE:
319 case SNDRV_PCM_FORMAT_S18_3BE:
320 case SNDRV_PCM_FORMAT_U18_3LE:
321 case SNDRV_PCM_FORMAT_U18_3BE:
322 case SNDRV_PCM_FORMAT_S20_3LE:
323 case SNDRV_PCM_FORMAT_S20_3BE:
324 case SNDRV_PCM_FORMAT_U20_3LE:
325 case SNDRV_PCM_FORMAT_U20_3BE:
326 case SNDRV_PCM_FORMAT_S24_3LE:
327 case SNDRV_PCM_FORMAT_S24_3BE:
328 case SNDRV_PCM_FORMAT_U24_3LE:
329 case SNDRV_PCM_FORMAT_U24_3BE:
331 case SNDRV_PCM_FORMAT_S24_LE:
332 case SNDRV_PCM_FORMAT_S24_BE:
333 case SNDRV_PCM_FORMAT_U24_LE:
334 case SNDRV_PCM_FORMAT_U24_BE:
335 case SNDRV_PCM_FORMAT_S32_LE:
336 case SNDRV_PCM_FORMAT_S32_BE:
337 case SNDRV_PCM_FORMAT_U32_LE:
338 case SNDRV_PCM_FORMAT_U32_BE:
339 case SNDRV_PCM_FORMAT_FLOAT_LE:
340 case SNDRV_PCM_FORMAT_FLOAT_BE:
342 case SNDRV_PCM_FORMAT_FLOAT64_LE:
343 case SNDRV_PCM_FORMAT_FLOAT64_BE:
345 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
346 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
348 case SNDRV_PCM_FORMAT_MU_LAW:
349 case SNDRV_PCM_FORMAT_A_LAW:
351 case SNDRV_PCM_FORMAT_IMA_ADPCM:
362 * \brief Return 64 bit expressing silence for a PCM sample format
363 * \param format Sample format
364 * \return silence 64 bit word
366 u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
369 case SNDRV_PCM_FORMAT_S8:
370 case SNDRV_PCM_FORMAT_S16_LE:
371 case SNDRV_PCM_FORMAT_S16_BE:
372 case SNDRV_PCM_FORMAT_S24_LE:
373 case SNDRV_PCM_FORMAT_S24_BE:
374 case SNDRV_PCM_FORMAT_S32_LE:
375 case SNDRV_PCM_FORMAT_S32_BE:
376 case SNDRV_PCM_FORMAT_S24_3LE:
377 case SNDRV_PCM_FORMAT_S24_3BE:
378 case SNDRV_PCM_FORMAT_S20_3LE:
379 case SNDRV_PCM_FORMAT_S20_3BE:
380 case SNDRV_PCM_FORMAT_S18_3LE:
381 case SNDRV_PCM_FORMAT_S18_3BE:
383 case SNDRV_PCM_FORMAT_U8:
384 return 0x8080808080808080ULL;
385 #ifdef SNDRV_LITTLE_ENDIAN
386 case SNDRV_PCM_FORMAT_U16_LE:
387 return 0x8000800080008000ULL;
388 case SNDRV_PCM_FORMAT_U24_LE:
389 return 0x0080000000800000ULL;
390 case SNDRV_PCM_FORMAT_U32_LE:
391 return 0x8000000080000000ULL;
392 case SNDRV_PCM_FORMAT_U16_BE:
393 return 0x0080008000800080ULL;
394 case SNDRV_PCM_FORMAT_U24_BE:
395 return 0x0000800000008000ULL;
396 case SNDRV_PCM_FORMAT_U32_BE:
397 return 0x0000008000000080ULL;
398 case SNDRV_PCM_FORMAT_U24_3LE:
399 return 0x0000800000800000ULL;
400 case SNDRV_PCM_FORMAT_U24_3BE:
401 return 0x0080000080000080ULL;
402 case SNDRV_PCM_FORMAT_U20_3LE:
403 return 0x0000080000080000ULL;
404 case SNDRV_PCM_FORMAT_U20_3BE:
405 return 0x0008000008000008ULL;
406 case SNDRV_PCM_FORMAT_U18_3LE:
407 return 0x0000020000020000ULL;
408 case SNDRV_PCM_FORMAT_U18_3BE:
409 return 0x0002000002000002ULL;
411 case SNDRV_PCM_FORMAT_U16_LE:
412 return 0x0080008000800080ULL;
413 case SNDRV_PCM_FORMAT_U24_LE:
414 return 0x0000800000008000ULL;
415 case SNDRV_PCM_FORMAT_U32_LE:
416 return 0x0000008000000080ULL;
417 case SNDRV_PCM_FORMAT_U16_BE:
418 return 0x8000800080008000ULL;
419 case SNDRV_PCM_FORMAT_U24_BE:
420 return 0x0080000000800000ULL;
421 case SNDRV_PCM_FORMAT_U32_BE:
422 return 0x8000000080000000ULL;
423 case SNDRV_PCM_FORMAT_U24_3LE:
424 return 0x0080000080000080ULL;
425 case SNDRV_PCM_FORMAT_U24_3BE:
426 return 0x0000800000800000ULL;
427 case SNDRV_PCM_FORMAT_U20_3LE:
428 return 0x0008000008000008ULL;
429 case SNDRV_PCM_FORMAT_U20_3BE:
430 return 0x0000080000080000ULL;
431 case SNDRV_PCM_FORMAT_U18_3LE:
432 return 0x0002000002000002ULL;
433 case SNDRV_PCM_FORMAT_U18_3BE:
434 return 0x0000020000020000ULL;
436 case SNDRV_PCM_FORMAT_FLOAT_LE:
442 u.f[0] = u.f[1] = 0.0;
443 #ifdef SNDRV_LITTLE_ENDIAN
446 return bswap_64(u.i);
449 case SNDRV_PCM_FORMAT_FLOAT64_LE:
456 #ifdef SNDRV_LITTLE_ENDIAN
459 return bswap_64(u.i);
462 case SNDRV_PCM_FORMAT_FLOAT_BE:
468 u.f[0] = u.f[1] = 0.0;
469 #ifdef SNDRV_LITTLE_ENDIAN
470 return bswap_64(u.i);
475 case SNDRV_PCM_FORMAT_FLOAT64_BE:
482 #ifdef SNDRV_LITTLE_ENDIAN
483 return bswap_64(u.i);
488 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
489 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
491 case SNDRV_PCM_FORMAT_MU_LAW:
492 return 0x7f7f7f7f7f7f7f7fULL;
493 case SNDRV_PCM_FORMAT_A_LAW:
494 return 0x5555555555555555ULL;
495 case SNDRV_PCM_FORMAT_IMA_ADPCM: /* special case */
496 case SNDRV_PCM_FORMAT_MPEG:
497 case SNDRV_PCM_FORMAT_GSM:
498 case SNDRV_PCM_FORMAT_SPECIAL:
508 * \brief Return 32 bit expressing silence for a PCM sample format
509 * \param format Sample format
510 * \return silence 32 bit word
512 u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format)
514 assert(snd_pcm_format_physical_width(format) <= 32);
515 return (u_int32_t)snd_pcm_format_silence_64(format);
519 * \brief Return 16 bit expressing silence for a PCM sample format
520 * \param format Sample format
521 * \return silence 16 bit word
523 u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format)
525 assert(snd_pcm_format_physical_width(format) <= 16);
526 return (u_int16_t)snd_pcm_format_silence_64(format);
530 * \brief Return 8 bit expressing silence for a PCM sample format
531 * \param format Sample format
532 * \return silence 8 bit word
534 u_int8_t snd_pcm_format_silence(snd_pcm_format_t format)
536 assert(snd_pcm_format_physical_width(format) <= 8);
537 return (u_int8_t)snd_pcm_format_silence_64(format);
541 * \brief Silence a PCM samples buffer
542 * \param format Sample format
544 * \return samples Samples count
546 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
550 switch (snd_pcm_format_physical_width(format)) {
552 u_int8_t silence = snd_pcm_format_silence_64(format);
553 unsigned int samples1;
554 if (samples % 2 != 0)
556 samples1 = samples / 2;
557 memset(data, silence, samples1);
561 u_int8_t silence = snd_pcm_format_silence_64(format);
562 memset(data, silence, samples);
566 u_int16_t silence = snd_pcm_format_silence_64(format);
567 u_int16_t *pdata = (u_int16_t *)data;
569 memset(data, 0, samples * 2);
571 while (samples-- > 0)
577 u_int32_t silence = snd_pcm_format_silence_64(format);
578 u_int8_t *pdata = (u_int8_t *)data;
580 memset(data, 0, samples * 3);
582 while (samples-- > 0) {
583 #ifdef SNDRV_LITTLE_ENDIAN
584 *pdata++ = silence >> 0;
585 *pdata++ = silence >> 8;
586 *pdata++ = silence >> 16;
588 *pdata++ = silence >> 16;
589 *pdata++ = silence >> 8;
590 *pdata++ = silence >> 0;
597 u_int32_t silence = snd_pcm_format_silence_64(format);
598 u_int32_t *pdata = (u_int32_t *)data;
600 memset(data, 0, samples * 4);
602 while (samples-- > 0)
608 u_int64_t silence = snd_pcm_format_silence_64(format);
609 u_int64_t *pdata = (u_int64_t *)data;
611 memset(data, 0, samples * 8);
613 while (samples-- > 0)
625 static int linear_formats[4*2*2] = {
630 SNDRV_PCM_FORMAT_S16_LE,
631 SNDRV_PCM_FORMAT_S16_BE,
632 SNDRV_PCM_FORMAT_U16_LE,
633 SNDRV_PCM_FORMAT_U16_BE,
634 SNDRV_PCM_FORMAT_S24_LE,
635 SNDRV_PCM_FORMAT_S24_BE,
636 SNDRV_PCM_FORMAT_U24_LE,
637 SNDRV_PCM_FORMAT_U24_BE,
638 SNDRV_PCM_FORMAT_S32_LE,
639 SNDRV_PCM_FORMAT_S32_BE,
640 SNDRV_PCM_FORMAT_U32_LE,
641 SNDRV_PCM_FORMAT_U32_BE
644 static int linear24_formats[3*2*2] = {
645 SNDRV_PCM_FORMAT_S24_3LE,
646 SNDRV_PCM_FORMAT_S24_3BE,
647 SNDRV_PCM_FORMAT_U24_3LE,
648 SNDRV_PCM_FORMAT_U24_3BE,
649 SNDRV_PCM_FORMAT_S20_3LE,
650 SNDRV_PCM_FORMAT_S20_3BE,
651 SNDRV_PCM_FORMAT_U20_3LE,
652 SNDRV_PCM_FORMAT_U20_3BE,
653 SNDRV_PCM_FORMAT_S18_3LE,
654 SNDRV_PCM_FORMAT_S18_3BE,
655 SNDRV_PCM_FORMAT_U18_3LE,
656 SNDRV_PCM_FORMAT_U18_3BE,
660 * \brief Compose a PCM sample linear format
661 * \param width Nominal bits per sample
662 * \param pwidth Physical bit width of the format
663 * \param unsignd Sign: 0 signed, 1 unsigned
664 * \return big_endian Endian: 0 little endian, 1 big endian
666 snd_pcm_format_t snd_pcm_build_linear_format(int width, int pwidth, int unsignd, int big_endian)
680 return SND_PCM_FORMAT_UNKNOWN;
682 return ((int(*)[2][2])linear24_formats)[width][!!unsignd][!!big_endian];
698 return SND_PCM_FORMAT_UNKNOWN;
700 return ((int(*)[2][2])linear_formats)[width][!!unsignd][!!big_endian];