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.
23 #include "../include/driver.h"
24 #include "../include/pcm.h"
25 #include "../include/pcm_plugin.h"
35 #include "pcm_local.h"
38 int snd_pcm_format_signed(int format)
42 case SND_PCM_SFMT_S16_LE:
43 case SND_PCM_SFMT_S16_BE:
44 case SND_PCM_SFMT_S24_LE:
45 case SND_PCM_SFMT_S24_BE:
46 case SND_PCM_SFMT_S32_LE:
47 case SND_PCM_SFMT_S32_BE:
50 case SND_PCM_SFMT_U16_LE:
51 case SND_PCM_SFMT_U16_BE:
52 case SND_PCM_SFMT_U24_LE:
53 case SND_PCM_SFMT_U24_BE:
54 case SND_PCM_SFMT_U32_LE:
55 case SND_PCM_SFMT_U32_BE:
62 int snd_pcm_format_unsigned(int format)
66 val = snd_pcm_format_signed(format);
72 int snd_pcm_format_linear(int format)
74 return snd_pcm_format_signed(format) >= 0;
77 int snd_pcm_format_little_endian(int format)
80 case SND_PCM_SFMT_S16_LE:
81 case SND_PCM_SFMT_U16_LE:
82 case SND_PCM_SFMT_S24_LE:
83 case SND_PCM_SFMT_U24_LE:
84 case SND_PCM_SFMT_S32_LE:
85 case SND_PCM_SFMT_U32_LE:
86 case SND_PCM_SFMT_FLOAT_LE:
87 case SND_PCM_SFMT_FLOAT64_LE:
88 case SND_PCM_SFMT_IEC958_SUBFRAME_LE:
90 case SND_PCM_SFMT_S16_BE:
91 case SND_PCM_SFMT_U16_BE:
92 case SND_PCM_SFMT_S24_BE:
93 case SND_PCM_SFMT_U24_BE:
94 case SND_PCM_SFMT_S32_BE:
95 case SND_PCM_SFMT_U32_BE:
96 case SND_PCM_SFMT_FLOAT_BE:
97 case SND_PCM_SFMT_FLOAT64_BE:
98 case SND_PCM_SFMT_IEC958_SUBFRAME_BE:
105 int snd_pcm_format_big_endian(int format)
109 val = snd_pcm_format_little_endian(format);
115 int snd_pcm_format_width(int format)
118 case SND_PCM_SFMT_S8:
119 case SND_PCM_SFMT_U8:
121 case SND_PCM_SFMT_S16_LE:
122 case SND_PCM_SFMT_S16_BE:
123 case SND_PCM_SFMT_U16_LE:
124 case SND_PCM_SFMT_U16_BE:
126 case SND_PCM_SFMT_S24_LE:
127 case SND_PCM_SFMT_S24_BE:
128 case SND_PCM_SFMT_U24_LE:
129 case SND_PCM_SFMT_U24_BE:
131 case SND_PCM_SFMT_S32_LE:
132 case SND_PCM_SFMT_S32_BE:
133 case SND_PCM_SFMT_U32_LE:
134 case SND_PCM_SFMT_U32_BE:
135 case SND_PCM_SFMT_FLOAT_LE:
136 case SND_PCM_SFMT_FLOAT_BE:
138 case SND_PCM_SFMT_FLOAT64_LE:
139 case SND_PCM_SFMT_FLOAT64_BE:
141 case SND_PCM_SFMT_IEC958_SUBFRAME_LE:
142 case SND_PCM_SFMT_IEC958_SUBFRAME_BE:
144 case SND_PCM_SFMT_MU_LAW:
145 case SND_PCM_SFMT_A_LAW:
147 case SND_PCM_SFMT_IMA_ADPCM:
154 int snd_pcm_format_physical_width(int format)
157 case SND_PCM_SFMT_S8:
158 case SND_PCM_SFMT_U8:
160 case SND_PCM_SFMT_S16_LE:
161 case SND_PCM_SFMT_S16_BE:
162 case SND_PCM_SFMT_U16_LE:
163 case SND_PCM_SFMT_U16_BE:
165 case SND_PCM_SFMT_S24_LE:
166 case SND_PCM_SFMT_S24_BE:
167 case SND_PCM_SFMT_U24_LE:
168 case SND_PCM_SFMT_U24_BE:
169 case SND_PCM_SFMT_S32_LE:
170 case SND_PCM_SFMT_S32_BE:
171 case SND_PCM_SFMT_U32_LE:
172 case SND_PCM_SFMT_U32_BE:
173 case SND_PCM_SFMT_FLOAT_LE:
174 case SND_PCM_SFMT_FLOAT_BE:
175 case SND_PCM_SFMT_IEC958_SUBFRAME_LE:
176 case SND_PCM_SFMT_IEC958_SUBFRAME_BE:
178 case SND_PCM_SFMT_FLOAT64_LE:
179 case SND_PCM_SFMT_FLOAT64_BE:
181 case SND_PCM_SFMT_MU_LAW:
182 case SND_PCM_SFMT_A_LAW:
184 case SND_PCM_SFMT_IMA_ADPCM:
191 ssize_t snd_pcm_format_size(int format, size_t samples)
194 case SND_PCM_SFMT_S8:
195 case SND_PCM_SFMT_U8:
197 case SND_PCM_SFMT_S16_LE:
198 case SND_PCM_SFMT_S16_BE:
199 case SND_PCM_SFMT_U16_LE:
200 case SND_PCM_SFMT_U16_BE:
202 case SND_PCM_SFMT_S24_LE:
203 case SND_PCM_SFMT_S24_BE:
204 case SND_PCM_SFMT_U24_LE:
205 case SND_PCM_SFMT_U24_BE:
206 case SND_PCM_SFMT_S32_LE:
207 case SND_PCM_SFMT_S32_BE:
208 case SND_PCM_SFMT_U32_LE:
209 case SND_PCM_SFMT_U32_BE:
210 case SND_PCM_SFMT_FLOAT_LE:
211 case SND_PCM_SFMT_FLOAT_BE:
213 case SND_PCM_SFMT_FLOAT64_LE:
214 case SND_PCM_SFMT_FLOAT64_BE:
216 case SND_PCM_SFMT_IEC958_SUBFRAME_LE:
217 case SND_PCM_SFMT_IEC958_SUBFRAME_BE:
219 case SND_PCM_SFMT_MU_LAW:
220 case SND_PCM_SFMT_A_LAW:
222 case SND_PCM_SFMT_IMA_ADPCM:
231 ssize_t snd_pcm_format_bytes_per_second(snd_pcm_format_t *format)
233 return snd_pcm_format_size(format->format, format->voices * format->rate);
236 const char *snd_pcm_get_format_name(int format)
238 static char *formats[] = {
241 "Signed 16-bit Little Endian",
242 "Signed 16-bit Big Endian",
243 "Unsigned 16-bit Little Endian",
244 "Unsigned 16-bit Big Endian",
245 "Signed 24-bit Little Endian",
246 "Signed 24-bit Big Endian",
247 "Unsigned 24-bit Little Endian",
248 "Unsigned 24-bit Big Endian",
249 "Signed 32-bit Little Endian",
250 "Signed 32-bit Big Endian",
251 "Unsigned 32-bit Little Endian",
252 "Unsigned 32-bit Big Endian",
253 "Float Little Endian",
255 "Float64 Little Endian",
256 "Float64 Big Endian",
257 "IEC-958 Little Endian",
258 "IEC-958 Big Endian",
265 if (format == SND_PCM_SFMT_SPECIAL)
267 if (format < 0 || format > SND_PCM_SFMT_GSM)
269 return formats[format];
272 u_int64_t snd_pcm_format_silence_64(int format)
275 case SND_PCM_SFMT_S8:
276 case SND_PCM_SFMT_S16_LE:
277 case SND_PCM_SFMT_S16_BE:
278 case SND_PCM_SFMT_S24_LE:
279 case SND_PCM_SFMT_S24_BE:
280 case SND_PCM_SFMT_S32_LE:
281 case SND_PCM_SFMT_S32_BE:
283 case SND_PCM_SFMT_U8:
284 return 0x8080808080808080UL;
285 case SND_PCM_SFMT_U16_LE:
286 case SND_PCM_SFMT_U24_LE:
287 case SND_PCM_SFMT_U32_LE:
288 #if defined(LITTLE_ENDIAN)
289 return 0x8000800080008000UL;
290 #elif defined(BIG_ENDIAN)
291 return 0x0080008000800080UL;
295 case SND_PCM_SFMT_U16_BE:
296 case SND_PCM_SFMT_U24_BE:
297 case SND_PCM_SFMT_U32_BE:
298 #if defined(LITTLE_ENDIAN)
299 return 0x0000008000000080UL;
300 #elif defined(BIG_ENDIAN)
301 return 0x8000000080000000UL;
305 case SND_PCM_SFMT_FLOAT_LE:
306 #if defined(LITTLE_ENDIAN)
308 #elif defined(BIG_ENDIAN)
309 return bswap_32((u_int32_t)((float)0.0));
313 case SND_PCM_SFMT_FLOAT64_LE:
314 #if defined(LITTLE_ENDIAN)
316 #elif defined(BIG_ENDIAN)
317 return bswap_64((u_int64_t)((double)0.0));
321 case SND_PCM_SFMT_FLOAT_BE:
322 #if defined(LITTLE_ENDIAN)
323 return bswap_32((u_int32_t)((float)0.0));
324 #elif defined(BIG_ENDIAN)
329 case SND_PCM_SFMT_FLOAT64_BE:
330 #if defined(LITTLE_ENDIAN)
331 return bswap_64((u_int64_t)((double)0.0));
332 #elif defined(BIG_ENDIAN)
337 case SND_PCM_SFMT_IEC958_SUBFRAME_LE:
338 case SND_PCM_SFMT_IEC958_SUBFRAME_BE:
340 case SND_PCM_SFMT_MU_LAW:
341 return 0x7f7f7f7f7f7f7f7fUL;
342 case SND_PCM_SFMT_A_LAW:
343 return 0x5555555555555555UL;
344 case SND_PCM_SFMT_IMA_ADPCM: /* special case */
345 case SND_PCM_SFMT_MPEG:
346 case SND_PCM_SFMT_GSM:
352 u_int32_t snd_pcm_format_silence_32(int format)
354 return (u_int32_t)snd_pcm_format_silence_64(format);
357 u_int16_t snd_pcm_format_silence_16(int format)
359 return (u_int16_t)snd_pcm_format_silence_64(format);
362 u_int8_t snd_pcm_format_silence(int format)
364 return (u_int8_t)snd_pcm_format_silence_64(format);
367 ssize_t snd_pcm_format_set_silence(int format, void *data, size_t count)
373 switch (snd_pcm_format_width(format)) {
376 u_int8_t silence = snd_pcm_format_silence_64(format);
377 memset(data, silence, count);
381 u_int16_t silence = snd_pcm_format_silence_64(format);
386 *((u_int16_t *)data)++ = silence;
390 u_int32_t silence = snd_pcm_format_silence_64(format);
395 *((u_int32_t *)data)++ = silence;
399 u_int64_t silence = snd_pcm_format_silence_64(format);
404 *((u_int64_t *)data)++ = silence;
412 static int linear_formats[4*2*2] = {
431 int snd_pcm_build_linear_format(int width, int unsignd, int big_endian)
449 return ((int(*)[2][2])linear_formats)[width][!!unsignd][!!big_endian];