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 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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, 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 endian info for a PCM sample format
86 * \param format Format
87 * \return 0 big endian, 1 little endian, a negative error code if endian independent
89 int snd_pcm_format_little_endian(snd_pcm_format_t format)
92 case SNDRV_PCM_FORMAT_S16_LE:
93 case SNDRV_PCM_FORMAT_U16_LE:
94 case SNDRV_PCM_FORMAT_S24_LE:
95 case SNDRV_PCM_FORMAT_U24_LE:
96 case SNDRV_PCM_FORMAT_S32_LE:
97 case SNDRV_PCM_FORMAT_U32_LE:
98 case SNDRV_PCM_FORMAT_FLOAT_LE:
99 case SNDRV_PCM_FORMAT_FLOAT64_LE:
100 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
102 case SNDRV_PCM_FORMAT_S16_BE:
103 case SNDRV_PCM_FORMAT_U16_BE:
104 case SNDRV_PCM_FORMAT_S24_BE:
105 case SNDRV_PCM_FORMAT_U24_BE:
106 case SNDRV_PCM_FORMAT_S32_BE:
107 case SNDRV_PCM_FORMAT_U32_BE:
108 case SNDRV_PCM_FORMAT_FLOAT_BE:
109 case SNDRV_PCM_FORMAT_FLOAT64_BE:
110 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
118 * \brief Return endian info for a PCM sample format
119 * \param format Format
120 * \return 0 little endian, 1 big endian, a negative error code if endian independent
122 int snd_pcm_format_big_endian(snd_pcm_format_t format)
126 val = snd_pcm_format_little_endian(format);
133 * \brief Return endian info for a PCM sample format
134 * \param format Format
135 * \return 0 swapped, 1 CPU endian, a negative error code if endian independent
137 int snd_pcm_format_cpu_endian(snd_pcm_format_t format)
139 #ifdef SNDRV_LITTLE_ENDIAN
140 return snd_pcm_format_little_endian(format);
142 return snd_pcm_format_big_endian(format);
147 * \brief Return nominal bits per a PCM sample
148 * \param format Sample format
149 * \return bits per sample, a negative error code if not applicable
151 int snd_pcm_format_width(snd_pcm_format_t format)
154 case SNDRV_PCM_FORMAT_S8:
155 case SNDRV_PCM_FORMAT_U8:
157 case SNDRV_PCM_FORMAT_S16_LE:
158 case SNDRV_PCM_FORMAT_S16_BE:
159 case SNDRV_PCM_FORMAT_U16_LE:
160 case SNDRV_PCM_FORMAT_U16_BE:
162 case SNDRV_PCM_FORMAT_S24_LE:
163 case SNDRV_PCM_FORMAT_S24_BE:
164 case SNDRV_PCM_FORMAT_U24_LE:
165 case SNDRV_PCM_FORMAT_U24_BE:
167 case SNDRV_PCM_FORMAT_S32_LE:
168 case SNDRV_PCM_FORMAT_S32_BE:
169 case SNDRV_PCM_FORMAT_U32_LE:
170 case SNDRV_PCM_FORMAT_U32_BE:
171 case SNDRV_PCM_FORMAT_FLOAT_LE:
172 case SNDRV_PCM_FORMAT_FLOAT_BE:
174 case SNDRV_PCM_FORMAT_FLOAT64_LE:
175 case SNDRV_PCM_FORMAT_FLOAT64_BE:
177 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
178 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
180 case SNDRV_PCM_FORMAT_MU_LAW:
181 case SNDRV_PCM_FORMAT_A_LAW:
183 case SNDRV_PCM_FORMAT_IMA_ADPCM:
191 * \brief Return bits needed to store a PCM sample
192 * \param format Sample format
193 * \return bits per sample, a negative error code if not applicable
195 int snd_pcm_format_physical_width(snd_pcm_format_t format)
198 case SNDRV_PCM_FORMAT_S8:
199 case SNDRV_PCM_FORMAT_U8:
201 case SNDRV_PCM_FORMAT_S16_LE:
202 case SNDRV_PCM_FORMAT_S16_BE:
203 case SNDRV_PCM_FORMAT_U16_LE:
204 case SNDRV_PCM_FORMAT_U16_BE:
206 case SNDRV_PCM_FORMAT_S24_LE:
207 case SNDRV_PCM_FORMAT_S24_BE:
208 case SNDRV_PCM_FORMAT_U24_LE:
209 case SNDRV_PCM_FORMAT_U24_BE:
210 case SNDRV_PCM_FORMAT_S32_LE:
211 case SNDRV_PCM_FORMAT_S32_BE:
212 case SNDRV_PCM_FORMAT_U32_LE:
213 case SNDRV_PCM_FORMAT_U32_BE:
214 case SNDRV_PCM_FORMAT_FLOAT_LE:
215 case SNDRV_PCM_FORMAT_FLOAT_BE:
216 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
217 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
219 case SNDRV_PCM_FORMAT_FLOAT64_LE:
220 case SNDRV_PCM_FORMAT_FLOAT64_BE:
222 case SNDRV_PCM_FORMAT_MU_LAW:
223 case SNDRV_PCM_FORMAT_A_LAW:
225 case SNDRV_PCM_FORMAT_IMA_ADPCM:
233 * \brief Return bytes needed to store a quantity of PCM sample
234 * \param format Sample format
235 * \param samples Samples count
236 * \return bytes needed, a negative error code if not integer or unknown
238 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
241 case SNDRV_PCM_FORMAT_S8:
242 case SNDRV_PCM_FORMAT_U8:
244 case SNDRV_PCM_FORMAT_S16_LE:
245 case SNDRV_PCM_FORMAT_S16_BE:
246 case SNDRV_PCM_FORMAT_U16_LE:
247 case SNDRV_PCM_FORMAT_U16_BE:
249 case SNDRV_PCM_FORMAT_S24_LE:
250 case SNDRV_PCM_FORMAT_S24_BE:
251 case SNDRV_PCM_FORMAT_U24_LE:
252 case SNDRV_PCM_FORMAT_U24_BE:
253 case SNDRV_PCM_FORMAT_S32_LE:
254 case SNDRV_PCM_FORMAT_S32_BE:
255 case SNDRV_PCM_FORMAT_U32_LE:
256 case SNDRV_PCM_FORMAT_U32_BE:
257 case SNDRV_PCM_FORMAT_FLOAT_LE:
258 case SNDRV_PCM_FORMAT_FLOAT_BE:
260 case SNDRV_PCM_FORMAT_FLOAT64_LE:
261 case SNDRV_PCM_FORMAT_FLOAT64_BE:
263 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
264 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
266 case SNDRV_PCM_FORMAT_MU_LAW:
267 case SNDRV_PCM_FORMAT_A_LAW:
269 case SNDRV_PCM_FORMAT_IMA_ADPCM:
280 * \brief Return 64 bit expressing silence for a PCM sample format
281 * \param format Sample format
282 * \return silence 64 bit word
284 u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
287 case SNDRV_PCM_FORMAT_S8:
288 case SNDRV_PCM_FORMAT_S16_LE:
289 case SNDRV_PCM_FORMAT_S16_BE:
290 case SNDRV_PCM_FORMAT_S24_LE:
291 case SNDRV_PCM_FORMAT_S24_BE:
292 case SNDRV_PCM_FORMAT_S32_LE:
293 case SNDRV_PCM_FORMAT_S32_BE:
295 case SNDRV_PCM_FORMAT_U8:
296 return 0x8080808080808080ULL;
297 #ifdef SNDRV_LITTLE_ENDIAN
298 case SNDRV_PCM_FORMAT_U16_LE:
299 return 0x8000800080008000ULL;
300 case SNDRV_PCM_FORMAT_U24_LE:
301 return 0x0080000000800000ULL;
302 case SNDRV_PCM_FORMAT_U32_LE:
303 return 0x8000000080000000ULL;
304 case SNDRV_PCM_FORMAT_U16_BE:
305 return 0x0080008000800080ULL;
306 case SNDRV_PCM_FORMAT_U24_BE:
307 return 0x0000800000008000ULL;
308 case SNDRV_PCM_FORMAT_U32_BE:
309 return 0x0000008000000080ULL;
311 case SNDRV_PCM_FORMAT_U16_LE:
312 return 0x0080008000800080ULL;
313 case SNDRV_PCM_FORMAT_U24_LE:
314 return 0x0000800000008000ULL;
315 case SNDRV_PCM_FORMAT_U32_LE:
316 return 0x0000008000000080ULL;
317 case SNDRV_PCM_FORMAT_U16_BE:
318 return 0x8000800080008000ULL;
319 case SNDRV_PCM_FORMAT_U24_BE:
320 return 0x0080000000800000ULL;
321 case SNDRV_PCM_FORMAT_U32_BE:
322 return 0x8000000080000000ULL;
324 case SNDRV_PCM_FORMAT_FLOAT_LE:
331 #ifdef SNDRV_LITTLE_ENDIAN
334 return bswap_32(u.i);
337 case SNDRV_PCM_FORMAT_FLOAT64_LE:
344 #ifdef SNDRV_LITTLE_ENDIAN
347 return bswap_64(u.i);
350 case SNDRV_PCM_FORMAT_FLOAT_BE:
357 #ifdef SNDRV_LITTLE_ENDIAN
358 return bswap_32(u.i);
363 case SNDRV_PCM_FORMAT_FLOAT64_BE:
370 #ifdef SNDRV_LITTLE_ENDIAN
371 return bswap_64(u.i);
376 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
377 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
379 case SNDRV_PCM_FORMAT_MU_LAW:
380 return 0x7f7f7f7f7f7f7f7fULL;
381 case SNDRV_PCM_FORMAT_A_LAW:
382 return 0x5555555555555555ULL;
383 case SNDRV_PCM_FORMAT_IMA_ADPCM: /* special case */
384 case SNDRV_PCM_FORMAT_MPEG:
385 case SNDRV_PCM_FORMAT_GSM:
386 case SNDRV_PCM_FORMAT_SPECIAL:
396 * \brief Return 32 bit expressing silence for a PCM sample format
397 * \param format Sample format
398 * \return silence 32 bit word
400 u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format)
402 assert(snd_pcm_format_physical_width(format) <= 32);
403 return (u_int32_t)snd_pcm_format_silence_64(format);
407 * \brief Return 16 bit expressing silence for a PCM sample format
408 * \param format Sample format
409 * \return silence 16 bit word
411 u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format)
413 assert(snd_pcm_format_physical_width(format) <= 16);
414 return (u_int16_t)snd_pcm_format_silence_64(format);
418 * \brief Return 8 bit expressing silence for a PCM sample format
419 * \param format Sample format
420 * \return silence 8 bit word
422 u_int8_t snd_pcm_format_silence(snd_pcm_format_t format)
424 assert(snd_pcm_format_physical_width(format) <= 8);
425 return (u_int8_t)snd_pcm_format_silence_64(format);
429 * \brief Silence a PCM samples buufer
430 * \param format Sample format
432 * \return samples Samples count
434 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
438 switch (snd_pcm_format_physical_width(format)) {
440 u_int8_t silence = snd_pcm_format_silence_64(format);
441 unsigned int samples1;
442 if (samples % 2 != 0)
444 samples1 = samples / 2;
445 memset(data, silence, samples1);
449 u_int8_t silence = snd_pcm_format_silence_64(format);
450 memset(data, silence, samples);
454 u_int16_t silence = snd_pcm_format_silence_64(format);
455 while (samples-- > 0)
456 *((u_int16_t *)data)++ = silence;
460 u_int32_t silence = snd_pcm_format_silence_64(format);
461 while (samples-- > 0)
462 *((u_int32_t *)data)++ = silence;
466 u_int64_t silence = snd_pcm_format_silence_64(format);
467 while (samples-- > 0)
468 *((u_int64_t *)data)++ = silence;
478 static int linear_formats[4*2*2] = {
483 SNDRV_PCM_FORMAT_S16_LE,
484 SNDRV_PCM_FORMAT_S16_BE,
485 SNDRV_PCM_FORMAT_U16_LE,
486 SNDRV_PCM_FORMAT_U16_BE,
487 SNDRV_PCM_FORMAT_S24_LE,
488 SNDRV_PCM_FORMAT_S24_BE,
489 SNDRV_PCM_FORMAT_U24_LE,
490 SNDRV_PCM_FORMAT_U24_BE,
491 SNDRV_PCM_FORMAT_S32_LE,
492 SNDRV_PCM_FORMAT_S32_BE,
493 SNDRV_PCM_FORMAT_U32_LE,
494 SNDRV_PCM_FORMAT_U32_BE
498 * \brief Compose a PCM sample linear format
499 * \param width Nominal bits per sample
500 * \param unsignd Sign: 0 signed, 1 unsigned
501 * \return big_endian Endianness: 0 little endian, 1 big endian
503 snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian)
519 return SND_PCM_FORMAT_UNKNOWN;
521 return ((int(*)[2][2])linear_formats)[width][!!unsignd][!!big_endian];