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:
46 case SNDRV_PCM_FORMAT_U8:
47 case SNDRV_PCM_FORMAT_U16_LE:
48 case SNDRV_PCM_FORMAT_U16_BE:
49 case SNDRV_PCM_FORMAT_U24_LE:
50 case SNDRV_PCM_FORMAT_U24_BE:
51 case SNDRV_PCM_FORMAT_U32_LE:
52 case SNDRV_PCM_FORMAT_U32_BE:
60 * \brief Return sign info for a PCM sample linear format
61 * \param format Format
62 * \return 0 signed, 1 unsigned, a negative error code if format is not linear
64 int snd_pcm_format_unsigned(snd_pcm_format_t format)
68 val = snd_pcm_format_signed(format);
75 * \brief Return linear info for a PCM sample format
76 * \param format Format
77 * \return 0 non linear, 1 linear
79 int snd_pcm_format_linear(snd_pcm_format_t format)
81 return snd_pcm_format_signed(format) >= 0;
85 * \brief Return float info for a PCM sample format
86 * \param format Format
87 * \return 0 non float, 1 float
89 int snd_pcm_format_float(snd_pcm_format_t format)
92 case SNDRV_PCM_FORMAT_FLOAT_LE:
93 case SNDRV_PCM_FORMAT_FLOAT_BE:
94 case SNDRV_PCM_FORMAT_FLOAT64_LE:
95 case SNDRV_PCM_FORMAT_FLOAT64_BE:
103 * \brief Return endian info for a PCM sample format
104 * \param format Format
105 * \return 0 big endian, 1 little endian, a negative error code if endian independent
107 int snd_pcm_format_little_endian(snd_pcm_format_t format)
110 case SNDRV_PCM_FORMAT_S16_LE:
111 case SNDRV_PCM_FORMAT_U16_LE:
112 case SNDRV_PCM_FORMAT_S24_LE:
113 case SNDRV_PCM_FORMAT_U24_LE:
114 case SNDRV_PCM_FORMAT_S32_LE:
115 case SNDRV_PCM_FORMAT_U32_LE:
116 case SNDRV_PCM_FORMAT_FLOAT_LE:
117 case SNDRV_PCM_FORMAT_FLOAT64_LE:
118 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
120 case SNDRV_PCM_FORMAT_S16_BE:
121 case SNDRV_PCM_FORMAT_U16_BE:
122 case SNDRV_PCM_FORMAT_S24_BE:
123 case SNDRV_PCM_FORMAT_U24_BE:
124 case SNDRV_PCM_FORMAT_S32_BE:
125 case SNDRV_PCM_FORMAT_U32_BE:
126 case SNDRV_PCM_FORMAT_FLOAT_BE:
127 case SNDRV_PCM_FORMAT_FLOAT64_BE:
128 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
136 * \brief Return endian info for a PCM sample format
137 * \param format Format
138 * \return 0 little endian, 1 big endian, a negative error code if endian independent
140 int snd_pcm_format_big_endian(snd_pcm_format_t format)
144 val = snd_pcm_format_little_endian(format);
151 * \brief Return endian info for a PCM sample format
152 * \param format Format
153 * \return 0 swapped, 1 CPU endian, a negative error code if endian independent
155 int snd_pcm_format_cpu_endian(snd_pcm_format_t format)
157 #ifdef SNDRV_LITTLE_ENDIAN
158 return snd_pcm_format_little_endian(format);
160 return snd_pcm_format_big_endian(format);
165 * \brief Return nominal bits per a PCM sample
166 * \param format Sample format
167 * \return bits per sample, a negative error code if not applicable
169 int snd_pcm_format_width(snd_pcm_format_t format)
172 case SNDRV_PCM_FORMAT_S8:
173 case SNDRV_PCM_FORMAT_U8:
175 case SNDRV_PCM_FORMAT_S16_LE:
176 case SNDRV_PCM_FORMAT_S16_BE:
177 case SNDRV_PCM_FORMAT_U16_LE:
178 case SNDRV_PCM_FORMAT_U16_BE:
180 case SNDRV_PCM_FORMAT_S24_LE:
181 case SNDRV_PCM_FORMAT_S24_BE:
182 case SNDRV_PCM_FORMAT_U24_LE:
183 case SNDRV_PCM_FORMAT_U24_BE:
185 case SNDRV_PCM_FORMAT_S32_LE:
186 case SNDRV_PCM_FORMAT_S32_BE:
187 case SNDRV_PCM_FORMAT_U32_LE:
188 case SNDRV_PCM_FORMAT_U32_BE:
189 case SNDRV_PCM_FORMAT_FLOAT_LE:
190 case SNDRV_PCM_FORMAT_FLOAT_BE:
192 case SNDRV_PCM_FORMAT_FLOAT64_LE:
193 case SNDRV_PCM_FORMAT_FLOAT64_BE:
195 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
196 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
198 case SNDRV_PCM_FORMAT_MU_LAW:
199 case SNDRV_PCM_FORMAT_A_LAW:
201 case SNDRV_PCM_FORMAT_IMA_ADPCM:
209 * \brief Return bits needed to store a PCM sample
210 * \param format Sample format
211 * \return bits per sample, a negative error code if not applicable
213 int snd_pcm_format_physical_width(snd_pcm_format_t format)
216 case SNDRV_PCM_FORMAT_S8:
217 case SNDRV_PCM_FORMAT_U8:
219 case SNDRV_PCM_FORMAT_S16_LE:
220 case SNDRV_PCM_FORMAT_S16_BE:
221 case SNDRV_PCM_FORMAT_U16_LE:
222 case SNDRV_PCM_FORMAT_U16_BE:
224 case SNDRV_PCM_FORMAT_S24_LE:
225 case SNDRV_PCM_FORMAT_S24_BE:
226 case SNDRV_PCM_FORMAT_U24_LE:
227 case SNDRV_PCM_FORMAT_U24_BE:
228 case SNDRV_PCM_FORMAT_S32_LE:
229 case SNDRV_PCM_FORMAT_S32_BE:
230 case SNDRV_PCM_FORMAT_U32_LE:
231 case SNDRV_PCM_FORMAT_U32_BE:
232 case SNDRV_PCM_FORMAT_FLOAT_LE:
233 case SNDRV_PCM_FORMAT_FLOAT_BE:
234 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
235 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
237 case SNDRV_PCM_FORMAT_FLOAT64_LE:
238 case SNDRV_PCM_FORMAT_FLOAT64_BE:
240 case SNDRV_PCM_FORMAT_MU_LAW:
241 case SNDRV_PCM_FORMAT_A_LAW:
243 case SNDRV_PCM_FORMAT_IMA_ADPCM:
251 * \brief Return bytes needed to store a quantity of PCM sample
252 * \param format Sample format
253 * \param samples Samples count
254 * \return bytes needed, a negative error code if not integer or unknown
256 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
259 case SNDRV_PCM_FORMAT_S8:
260 case SNDRV_PCM_FORMAT_U8:
262 case SNDRV_PCM_FORMAT_S16_LE:
263 case SNDRV_PCM_FORMAT_S16_BE:
264 case SNDRV_PCM_FORMAT_U16_LE:
265 case SNDRV_PCM_FORMAT_U16_BE:
267 case SNDRV_PCM_FORMAT_S24_LE:
268 case SNDRV_PCM_FORMAT_S24_BE:
269 case SNDRV_PCM_FORMAT_U24_LE:
270 case SNDRV_PCM_FORMAT_U24_BE:
271 case SNDRV_PCM_FORMAT_S32_LE:
272 case SNDRV_PCM_FORMAT_S32_BE:
273 case SNDRV_PCM_FORMAT_U32_LE:
274 case SNDRV_PCM_FORMAT_U32_BE:
275 case SNDRV_PCM_FORMAT_FLOAT_LE:
276 case SNDRV_PCM_FORMAT_FLOAT_BE:
278 case SNDRV_PCM_FORMAT_FLOAT64_LE:
279 case SNDRV_PCM_FORMAT_FLOAT64_BE:
281 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
282 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
284 case SNDRV_PCM_FORMAT_MU_LAW:
285 case SNDRV_PCM_FORMAT_A_LAW:
287 case SNDRV_PCM_FORMAT_IMA_ADPCM:
298 * \brief Return 64 bit expressing silence for a PCM sample format
299 * \param format Sample format
300 * \return silence 64 bit word
302 u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
305 case SNDRV_PCM_FORMAT_S8:
306 case SNDRV_PCM_FORMAT_S16_LE:
307 case SNDRV_PCM_FORMAT_S16_BE:
308 case SNDRV_PCM_FORMAT_S24_LE:
309 case SNDRV_PCM_FORMAT_S24_BE:
310 case SNDRV_PCM_FORMAT_S32_LE:
311 case SNDRV_PCM_FORMAT_S32_BE:
313 case SNDRV_PCM_FORMAT_U8:
314 return 0x8080808080808080ULL;
315 #ifdef SNDRV_LITTLE_ENDIAN
316 case SNDRV_PCM_FORMAT_U16_LE:
317 return 0x8000800080008000ULL;
318 case SNDRV_PCM_FORMAT_U24_LE:
319 return 0x0080000000800000ULL;
320 case SNDRV_PCM_FORMAT_U32_LE:
321 return 0x8000000080000000ULL;
322 case SNDRV_PCM_FORMAT_U16_BE:
323 return 0x0080008000800080ULL;
324 case SNDRV_PCM_FORMAT_U24_BE:
325 return 0x0000800000008000ULL;
326 case SNDRV_PCM_FORMAT_U32_BE:
327 return 0x0000008000000080ULL;
329 case SNDRV_PCM_FORMAT_U16_LE:
330 return 0x0080008000800080ULL;
331 case SNDRV_PCM_FORMAT_U24_LE:
332 return 0x0000800000008000ULL;
333 case SNDRV_PCM_FORMAT_U32_LE:
334 return 0x0000008000000080ULL;
335 case SNDRV_PCM_FORMAT_U16_BE:
336 return 0x8000800080008000ULL;
337 case SNDRV_PCM_FORMAT_U24_BE:
338 return 0x0080000000800000ULL;
339 case SNDRV_PCM_FORMAT_U32_BE:
340 return 0x8000000080000000ULL;
342 case SNDRV_PCM_FORMAT_FLOAT_LE:
349 #ifdef SNDRV_LITTLE_ENDIAN
352 return bswap_32(u.i);
355 case SNDRV_PCM_FORMAT_FLOAT64_LE:
362 #ifdef SNDRV_LITTLE_ENDIAN
365 return bswap_64(u.i);
368 case SNDRV_PCM_FORMAT_FLOAT_BE:
375 #ifdef SNDRV_LITTLE_ENDIAN
376 return bswap_32(u.i);
381 case SNDRV_PCM_FORMAT_FLOAT64_BE:
388 #ifdef SNDRV_LITTLE_ENDIAN
389 return bswap_64(u.i);
394 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
395 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
397 case SNDRV_PCM_FORMAT_MU_LAW:
398 return 0x7f7f7f7f7f7f7f7fULL;
399 case SNDRV_PCM_FORMAT_A_LAW:
400 return 0x5555555555555555ULL;
401 case SNDRV_PCM_FORMAT_IMA_ADPCM: /* special case */
402 case SNDRV_PCM_FORMAT_MPEG:
403 case SNDRV_PCM_FORMAT_GSM:
404 case SNDRV_PCM_FORMAT_SPECIAL:
414 * \brief Return 32 bit expressing silence for a PCM sample format
415 * \param format Sample format
416 * \return silence 32 bit word
418 u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format)
420 assert(snd_pcm_format_physical_width(format) <= 32);
421 return (u_int32_t)snd_pcm_format_silence_64(format);
425 * \brief Return 16 bit expressing silence for a PCM sample format
426 * \param format Sample format
427 * \return silence 16 bit word
429 u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format)
431 assert(snd_pcm_format_physical_width(format) <= 16);
432 return (u_int16_t)snd_pcm_format_silence_64(format);
436 * \brief Return 8 bit expressing silence for a PCM sample format
437 * \param format Sample format
438 * \return silence 8 bit word
440 u_int8_t snd_pcm_format_silence(snd_pcm_format_t format)
442 assert(snd_pcm_format_physical_width(format) <= 8);
443 return (u_int8_t)snd_pcm_format_silence_64(format);
447 * \brief Silence a PCM samples buffer
448 * \param format Sample format
450 * \return samples Samples count
452 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
456 switch (snd_pcm_format_physical_width(format)) {
458 u_int8_t silence = snd_pcm_format_silence_64(format);
459 unsigned int samples1;
460 if (samples % 2 != 0)
462 samples1 = samples / 2;
463 memset(data, silence, samples1);
467 u_int8_t silence = snd_pcm_format_silence_64(format);
468 memset(data, silence, samples);
472 u_int16_t silence = snd_pcm_format_silence_64(format);
473 while (samples-- > 0)
474 *((u_int16_t *)data)++ = silence;
478 u_int32_t silence = snd_pcm_format_silence_64(format);
479 while (samples-- > 0)
480 *((u_int32_t *)data)++ = silence;
484 u_int64_t silence = snd_pcm_format_silence_64(format);
485 while (samples-- > 0)
486 *((u_int64_t *)data)++ = silence;
496 static int linear_formats[4*2*2] = {
501 SNDRV_PCM_FORMAT_S16_LE,
502 SNDRV_PCM_FORMAT_S16_BE,
503 SNDRV_PCM_FORMAT_U16_LE,
504 SNDRV_PCM_FORMAT_U16_BE,
505 SNDRV_PCM_FORMAT_S24_LE,
506 SNDRV_PCM_FORMAT_S24_BE,
507 SNDRV_PCM_FORMAT_U24_LE,
508 SNDRV_PCM_FORMAT_U24_BE,
509 SNDRV_PCM_FORMAT_S32_LE,
510 SNDRV_PCM_FORMAT_S32_BE,
511 SNDRV_PCM_FORMAT_U32_LE,
512 SNDRV_PCM_FORMAT_U32_BE
516 * \brief Compose a PCM sample linear format
517 * \param width Nominal bits per sample
518 * \param unsignd Sign: 0 signed, 1 unsigned
519 * \return big_endian Endian: 0 little endian, 1 big endian
521 snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian)
537 return SND_PCM_FORMAT_UNKNOWN;
539 return ((int(*)[2][2])linear_formats)[width][!!unsignd][!!big_endian];