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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <sound/driver.h>
23 #include <linux/time.h>
24 #include <sound/core.h>
25 #include <sound/pcm.h>
26 #define bswap_16 swab16
27 #define bswap_32 swab32
28 #define bswap_64 swab64
29 #define SND_PCM_FORMAT_UNKNOWN (-1)
30 #define snd_enum_to_int(v) (v)
31 #define snd_int_to_enum(v) (v)
34 * snd_pcm_format_signed - Check the PCM format is signed linear
35 * @format: the format to check
37 * Returns 1 if the given PCM format is signed linear, 0 if unsigned
38 * linear, and a negative error code for non-linear formats.
40 int snd_pcm_format_signed(snd_pcm_format_t format
)
42 switch (snd_enum_to_int(format
)) {
43 case SNDRV_PCM_FORMAT_S8
:
44 case SNDRV_PCM_FORMAT_S16_LE
:
45 case SNDRV_PCM_FORMAT_S16_BE
:
46 case SNDRV_PCM_FORMAT_S24_LE
:
47 case SNDRV_PCM_FORMAT_S24_BE
:
48 case SNDRV_PCM_FORMAT_S32_LE
:
49 case SNDRV_PCM_FORMAT_S32_BE
:
50 case SNDRV_PCM_FORMAT_S24_3LE
:
51 case SNDRV_PCM_FORMAT_S24_3BE
:
52 case SNDRV_PCM_FORMAT_S20_3LE
:
53 case SNDRV_PCM_FORMAT_S20_3BE
:
54 case SNDRV_PCM_FORMAT_S18_3LE
:
55 case SNDRV_PCM_FORMAT_S18_3BE
:
57 case SNDRV_PCM_FORMAT_U8
:
58 case SNDRV_PCM_FORMAT_U16_LE
:
59 case SNDRV_PCM_FORMAT_U16_BE
:
60 case SNDRV_PCM_FORMAT_U24_LE
:
61 case SNDRV_PCM_FORMAT_U24_BE
:
62 case SNDRV_PCM_FORMAT_U32_LE
:
63 case SNDRV_PCM_FORMAT_U32_BE
:
64 case SNDRV_PCM_FORMAT_U24_3LE
:
65 case SNDRV_PCM_FORMAT_U24_3BE
:
66 case SNDRV_PCM_FORMAT_U20_3LE
:
67 case SNDRV_PCM_FORMAT_U20_3BE
:
68 case SNDRV_PCM_FORMAT_U18_3LE
:
69 case SNDRV_PCM_FORMAT_U18_3BE
:
77 * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
78 * @format: the format to check
80 * Returns 1 if the given PCM format is unsigned linear, 0 if signed
81 * linear, and a negative error code for non-linear formats.
83 int snd_pcm_format_unsigned(snd_pcm_format_t format
)
87 val
= snd_pcm_format_signed(format
);
94 * snd_pcm_format_linear - Check the PCM format is linear
95 * @format: the format to check
97 * Returns 1 if the given PCM format is linear, 0 if not.
99 int snd_pcm_format_linear(snd_pcm_format_t format
)
101 return snd_pcm_format_signed(format
) >= 0;
105 * snd_pcm_format_little_endian - Check the PCM format is little-endian
106 * @format: the format to check
108 * Returns 1 if the given PCM format is little-endian, 0 if
109 * big-endian, or a negative error code if endian not specified.
111 int snd_pcm_format_little_endian(snd_pcm_format_t format
)
113 switch (snd_enum_to_int(format
)) {
114 case SNDRV_PCM_FORMAT_S16_LE
:
115 case SNDRV_PCM_FORMAT_U16_LE
:
116 case SNDRV_PCM_FORMAT_S24_LE
:
117 case SNDRV_PCM_FORMAT_U24_LE
:
118 case SNDRV_PCM_FORMAT_S32_LE
:
119 case SNDRV_PCM_FORMAT_U32_LE
:
120 case SNDRV_PCM_FORMAT_FLOAT_LE
:
121 case SNDRV_PCM_FORMAT_FLOAT64_LE
:
122 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
:
123 case SNDRV_PCM_FORMAT_S24_3LE
:
124 case SNDRV_PCM_FORMAT_S20_3LE
:
125 case SNDRV_PCM_FORMAT_S18_3LE
:
126 case SNDRV_PCM_FORMAT_U24_3LE
:
127 case SNDRV_PCM_FORMAT_U20_3LE
:
128 case SNDRV_PCM_FORMAT_U18_3LE
:
130 case SNDRV_PCM_FORMAT_S16_BE
:
131 case SNDRV_PCM_FORMAT_U16_BE
:
132 case SNDRV_PCM_FORMAT_S24_BE
:
133 case SNDRV_PCM_FORMAT_U24_BE
:
134 case SNDRV_PCM_FORMAT_S32_BE
:
135 case SNDRV_PCM_FORMAT_U32_BE
:
136 case SNDRV_PCM_FORMAT_FLOAT_BE
:
137 case SNDRV_PCM_FORMAT_FLOAT64_BE
:
138 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
:
139 case SNDRV_PCM_FORMAT_S24_3BE
:
140 case SNDRV_PCM_FORMAT_S20_3BE
:
141 case SNDRV_PCM_FORMAT_S18_3BE
:
142 case SNDRV_PCM_FORMAT_U24_3BE
:
143 case SNDRV_PCM_FORMAT_U20_3BE
:
144 case SNDRV_PCM_FORMAT_U18_3BE
:
152 * snd_pcm_format_big_endian - Check the PCM format is big-endian
153 * @format: the format to check
155 * Returns 1 if the given PCM format is big-endian, 0 if
156 * little-endian, or a negative error code if endian not specified.
158 int snd_pcm_format_big_endian(snd_pcm_format_t format
)
162 val
= snd_pcm_format_little_endian(format
);
169 * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
170 * @format: the format to check
172 * Returns 1 if the given PCM format is CPU-endian, 0 if
173 * opposite, or a negative error code if endian not specified.
175 int snd_pcm_format_cpu_endian(snd_pcm_format_t format
)
177 #ifdef SNDRV_LITTLE_ENDIAN
178 return snd_pcm_format_little_endian(format
);
180 return snd_pcm_format_big_endian(format
);
185 * snd_pcm_format_width - return the bit-width of the format
186 * @format: the format to check
188 * Returns the bit-width of the format, or a negative error code
191 int snd_pcm_format_width(snd_pcm_format_t format
)
193 switch (snd_enum_to_int(format
)) {
194 case SNDRV_PCM_FORMAT_S8
:
195 case SNDRV_PCM_FORMAT_U8
:
197 case SNDRV_PCM_FORMAT_S16_LE
:
198 case SNDRV_PCM_FORMAT_S16_BE
:
199 case SNDRV_PCM_FORMAT_U16_LE
:
200 case SNDRV_PCM_FORMAT_U16_BE
:
202 case SNDRV_PCM_FORMAT_S18_3LE
:
203 case SNDRV_PCM_FORMAT_S18_3BE
:
204 case SNDRV_PCM_FORMAT_U18_3LE
:
205 case SNDRV_PCM_FORMAT_U18_3BE
:
207 case SNDRV_PCM_FORMAT_S20_3LE
:
208 case SNDRV_PCM_FORMAT_S20_3BE
:
209 case SNDRV_PCM_FORMAT_U20_3LE
:
210 case SNDRV_PCM_FORMAT_U20_3BE
:
212 case SNDRV_PCM_FORMAT_S24_LE
:
213 case SNDRV_PCM_FORMAT_S24_BE
:
214 case SNDRV_PCM_FORMAT_U24_LE
:
215 case SNDRV_PCM_FORMAT_U24_BE
:
216 case SNDRV_PCM_FORMAT_S24_3LE
:
217 case SNDRV_PCM_FORMAT_S24_3BE
:
218 case SNDRV_PCM_FORMAT_U24_3LE
:
219 case SNDRV_PCM_FORMAT_U24_3BE
:
221 case SNDRV_PCM_FORMAT_S32_LE
:
222 case SNDRV_PCM_FORMAT_S32_BE
:
223 case SNDRV_PCM_FORMAT_U32_LE
:
224 case SNDRV_PCM_FORMAT_U32_BE
:
225 case SNDRV_PCM_FORMAT_FLOAT_LE
:
226 case SNDRV_PCM_FORMAT_FLOAT_BE
:
228 case SNDRV_PCM_FORMAT_FLOAT64_LE
:
229 case SNDRV_PCM_FORMAT_FLOAT64_BE
:
231 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
:
232 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
:
234 case SNDRV_PCM_FORMAT_MU_LAW
:
235 case SNDRV_PCM_FORMAT_A_LAW
:
237 case SNDRV_PCM_FORMAT_IMA_ADPCM
:
245 * snd_pcm_format_physical_width - return the physical bit-width of the format
246 * @format: the format to check
248 * Returns the physical bit-width of the format, or a negative error code
251 int snd_pcm_format_physical_width(snd_pcm_format_t format
)
253 switch (snd_enum_to_int(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 * snd_pcm_format_size - return the byte size of samples on the given format
303 * @format: the format to check
305 * Returns the byte size of the given samples for the format, or a
306 * negative error code if unknown format.
308 ssize_t
snd_pcm_format_size(snd_pcm_format_t format
, size_t samples
)
310 switch (snd_enum_to_int(format
)) {
311 case SNDRV_PCM_FORMAT_S8
:
312 case SNDRV_PCM_FORMAT_U8
:
314 case SNDRV_PCM_FORMAT_S16_LE
:
315 case SNDRV_PCM_FORMAT_S16_BE
:
316 case SNDRV_PCM_FORMAT_U16_LE
:
317 case SNDRV_PCM_FORMAT_U16_BE
:
319 case SNDRV_PCM_FORMAT_S18_3LE
:
320 case SNDRV_PCM_FORMAT_S18_3BE
:
321 case SNDRV_PCM_FORMAT_U18_3LE
:
322 case SNDRV_PCM_FORMAT_U18_3BE
:
323 case SNDRV_PCM_FORMAT_S20_3LE
:
324 case SNDRV_PCM_FORMAT_S20_3BE
:
325 case SNDRV_PCM_FORMAT_U20_3LE
:
326 case SNDRV_PCM_FORMAT_U20_3BE
:
327 case SNDRV_PCM_FORMAT_S24_3LE
:
328 case SNDRV_PCM_FORMAT_S24_3BE
:
329 case SNDRV_PCM_FORMAT_U24_3LE
:
330 case SNDRV_PCM_FORMAT_U24_3BE
:
332 case SNDRV_PCM_FORMAT_S24_LE
:
333 case SNDRV_PCM_FORMAT_S24_BE
:
334 case SNDRV_PCM_FORMAT_U24_LE
:
335 case SNDRV_PCM_FORMAT_U24_BE
:
336 case SNDRV_PCM_FORMAT_S32_LE
:
337 case SNDRV_PCM_FORMAT_S32_BE
:
338 case SNDRV_PCM_FORMAT_U32_LE
:
339 case SNDRV_PCM_FORMAT_U32_BE
:
340 case SNDRV_PCM_FORMAT_FLOAT_LE
:
341 case SNDRV_PCM_FORMAT_FLOAT_BE
:
343 case SNDRV_PCM_FORMAT_FLOAT64_LE
:
344 case SNDRV_PCM_FORMAT_FLOAT64_BE
:
346 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
:
347 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
:
349 case SNDRV_PCM_FORMAT_MU_LAW
:
350 case SNDRV_PCM_FORMAT_A_LAW
:
352 case SNDRV_PCM_FORMAT_IMA_ADPCM
:
362 * snd_pcm_format_silence_64 - return the silent data in 64bit integer
363 * @format: the format to check
365 * Returns the silent data in 64bit integer for the given format.
367 u_int64_t
snd_pcm_format_silence_64(snd_pcm_format_t format
)
369 switch (snd_enum_to_int(format
)) {
370 case SNDRV_PCM_FORMAT_S8
:
371 case SNDRV_PCM_FORMAT_S16_LE
:
372 case SNDRV_PCM_FORMAT_S16_BE
:
373 case SNDRV_PCM_FORMAT_S24_LE
:
374 case SNDRV_PCM_FORMAT_S24_BE
:
375 case SNDRV_PCM_FORMAT_S32_LE
:
376 case SNDRV_PCM_FORMAT_S32_BE
:
377 case SNDRV_PCM_FORMAT_S24_3LE
:
378 case SNDRV_PCM_FORMAT_S24_3BE
:
379 case SNDRV_PCM_FORMAT_S20_3LE
:
380 case SNDRV_PCM_FORMAT_S20_3BE
:
381 case SNDRV_PCM_FORMAT_S18_3LE
:
382 case SNDRV_PCM_FORMAT_S18_3BE
:
384 case SNDRV_PCM_FORMAT_U8
:
385 return 0x8080808080808080ULL
;
386 #ifdef SNDRV_LITTLE_ENDIAN
387 case SNDRV_PCM_FORMAT_U16_LE
:
388 return 0x8000800080008000ULL
;
389 case SNDRV_PCM_FORMAT_U24_LE
:
390 return 0x0080000000800000ULL
;
391 case SNDRV_PCM_FORMAT_U32_LE
:
392 return 0x8000000080000000ULL
;
393 case SNDRV_PCM_FORMAT_U16_BE
:
394 return 0x0080008000800080ULL
;
395 case SNDRV_PCM_FORMAT_U24_BE
:
396 return 0x0000800000008000ULL
;
397 case SNDRV_PCM_FORMAT_U32_BE
:
398 return 0x0000008000000080ULL
;
399 case SNDRV_PCM_FORMAT_U24_3LE
:
400 return 0x0000800000800000ULL
;
401 case SNDRV_PCM_FORMAT_U24_3BE
:
402 return 0x0080000080000080ULL
;
403 case SNDRV_PCM_FORMAT_U20_3LE
:
404 return 0x0000080000080000ULL
;
405 case SNDRV_PCM_FORMAT_U20_3BE
:
406 return 0x0008000008000008ULL
;
407 case SNDRV_PCM_FORMAT_U18_3LE
:
408 return 0x0000020000020000ULL
;
409 case SNDRV_PCM_FORMAT_U18_3BE
:
410 return 0x0002000002000002ULL
;
412 case SNDRV_PCM_FORMAT_U16_LE
:
413 return 0x0080008000800080ULL
;
414 case SNDRV_PCM_FORMAT_U24_LE
:
415 return 0x0000800000008000ULL
;
416 case SNDRV_PCM_FORMAT_U32_LE
:
417 return 0x0000008000000080ULL
;
418 case SNDRV_PCM_FORMAT_U16_BE
:
419 return 0x8000800080008000ULL
;
420 case SNDRV_PCM_FORMAT_U24_BE
:
421 return 0x0080000000800000ULL
;
422 case SNDRV_PCM_FORMAT_U32_BE
:
423 return 0x8000000080000000ULL
;
424 case SNDRV_PCM_FORMAT_U24_3LE
:
425 return 0x0080000080000080ULL
;
426 case SNDRV_PCM_FORMAT_U24_3BE
:
427 return 0x0000800000800000ULL
;
428 case SNDRV_PCM_FORMAT_U20_3LE
:
429 return 0x0008000008000008ULL
;
430 case SNDRV_PCM_FORMAT_U20_3BE
:
431 return 0x0000080000080000ULL
;
432 case SNDRV_PCM_FORMAT_U18_3LE
:
433 return 0x0002000002000002ULL
;
434 case SNDRV_PCM_FORMAT_U18_3BE
:
435 return 0x0000020000020000ULL
;
437 case SNDRV_PCM_FORMAT_FLOAT_LE
:
444 #ifdef SNDRV_LITTLE_ENDIAN
447 return bswap_32(u
.i
);
450 case SNDRV_PCM_FORMAT_FLOAT64_LE
:
457 #ifdef SNDRV_LITTLE_ENDIAN
460 return bswap_64(u
.i
);
463 case SNDRV_PCM_FORMAT_FLOAT_BE
:
470 #ifdef SNDRV_LITTLE_ENDIAN
471 return bswap_32(u
.i
);
476 case SNDRV_PCM_FORMAT_FLOAT64_BE
:
483 #ifdef SNDRV_LITTLE_ENDIAN
484 return bswap_64(u
.i
);
489 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
:
490 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
:
492 case SNDRV_PCM_FORMAT_MU_LAW
:
493 return 0x7f7f7f7f7f7f7f7fULL
;
494 case SNDRV_PCM_FORMAT_A_LAW
:
495 return 0x5555555555555555ULL
;
496 case SNDRV_PCM_FORMAT_IMA_ADPCM
: /* special case */
497 case SNDRV_PCM_FORMAT_MPEG
:
498 case SNDRV_PCM_FORMAT_GSM
:
499 case SNDRV_PCM_FORMAT_SPECIAL
:
507 u_int32_t
snd_pcm_format_silence_32(snd_pcm_format_t format
)
509 return (u_int32_t
)snd_pcm_format_silence_64(format
);
512 u_int16_t
snd_pcm_format_silence_16(snd_pcm_format_t format
)
514 return (u_int16_t
)snd_pcm_format_silence_64(format
);
517 u_int8_t
snd_pcm_format_silence(snd_pcm_format_t format
)
519 return (u_int8_t
)snd_pcm_format_silence_64(format
);
523 * snd_pcm_format_set_silence - set the silence data on the buffer
524 * @format: the PCM format
525 * @data: the buffer pointer
526 * @samples: the number of samples to set silence
528 * Sets the silence data on the buffer for the given samples.
530 * Returns zero if successful, or a negative error code on failure.
532 int snd_pcm_format_set_silence(snd_pcm_format_t format
, void *data
, unsigned int samples
)
536 switch (snd_pcm_format_width(format
)) {
538 u_int8_t silence
= snd_pcm_format_silence_64(format
);
539 unsigned int samples1
;
540 if (samples
% 2 != 0)
542 samples1
= samples
/ 2;
543 memset(data
, silence
, samples1
);
547 u_int8_t silence
= snd_pcm_format_silence_64(format
);
548 memset(data
, silence
, samples
);
552 u_int16_t silence
= snd_pcm_format_silence_64(format
);
554 memset(data
, 0, samples
* 2);
556 while (samples
-- > 0)
557 *((u_int16_t
*)data
)++ = silence
;
562 u_int32_t silence
= snd_pcm_format_silence_64(format
);
564 memset(data
, 0, samples
* 3);
566 while (samples
-- > 0) {
567 #ifdef SNDRV_LITTLE_ENDIAN
568 *((u_int8_t
*)data
)++ = silence
>> 0;
569 *((u_int8_t
*)data
)++ = silence
>> 8;
570 *((u_int8_t
*)data
)++ = silence
>> 16;
572 *((u_int8_t
*)data
)++ = silence
>> 16;
573 *((u_int8_t
*)data
)++ = silence
>> 8;
574 *((u_int8_t
*)data
)++ = silence
>> 0;
581 u_int32_t silence
= snd_pcm_format_silence_64(format
);
583 memset(data
, 0, samples
* 4);
585 while (samples
-- > 0)
586 *((u_int32_t
*)data
)++ = silence
;
591 u_int64_t silence
= snd_pcm_format_silence_64(format
);
593 memset(data
, 0, samples
* 8);
595 while (samples
-- > 0)
596 *((u_int64_t
*)data
)++ = silence
;
606 static int linear_formats
[4*2*2] = {
611 SNDRV_PCM_FORMAT_S16_LE
,
612 SNDRV_PCM_FORMAT_S16_BE
,
613 SNDRV_PCM_FORMAT_U16_LE
,
614 SNDRV_PCM_FORMAT_U16_BE
,
615 SNDRV_PCM_FORMAT_S24_LE
,
616 SNDRV_PCM_FORMAT_S24_BE
,
617 SNDRV_PCM_FORMAT_U24_LE
,
618 SNDRV_PCM_FORMAT_U24_BE
,
619 SNDRV_PCM_FORMAT_S32_LE
,
620 SNDRV_PCM_FORMAT_S32_BE
,
621 SNDRV_PCM_FORMAT_U32_LE
,
622 SNDRV_PCM_FORMAT_U32_BE
626 * snd_pcm_build_linear_format - return the suitable linear format for the given condition
627 * @width: the bit-width
628 * @unsignd: 1 if unsigned, 0 if signed.
629 * @big_endian: 1 if big-endian, 0 if little-endian
631 * Returns the suitable linear format for the given condition.
633 snd_pcm_format_t
snd_pcm_build_linear_format(int width
, int unsignd
, int big_endian
)
649 return SND_PCM_FORMAT_UNKNOWN
;
651 return snd_int_to_enum(((int(*)[2][2])linear_formats
)[width
][!!unsignd
][!!big_endian
]);