patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / sound / core / pcm_misc.c
1 /*
2  *  PCM Interface - misc routines
3  *  Copyright (c) 1998 by Jaroslav Kysela <perex@suse.cz>
4  *
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21   
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)
32
33 /**
34  * snd_pcm_format_signed - Check the PCM format is signed linear
35  * @format: the format to check
36  *
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.
39  */
40 int snd_pcm_format_signed(snd_pcm_format_t format)
41 {
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:
56                 return 1;
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:
70                 return 0;
71         default:
72                 return -EINVAL;
73         }
74 }
75
76 /**
77  * snd_pcm_format_unsigned - Check the PCM format is unsigned linear
78  * @format: the format to check
79  *
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.
82  */
83 int snd_pcm_format_unsigned(snd_pcm_format_t format)
84 {
85         int val;
86
87         val = snd_pcm_format_signed(format);
88         if (val < 0)
89                 return val;
90         return !val;
91 }
92
93 /**
94  * snd_pcm_format_linear - Check the PCM format is linear
95  * @format: the format to check
96  *
97  * Returns 1 if the given PCM format is linear, 0 if not.
98  */
99 int snd_pcm_format_linear(snd_pcm_format_t format)
100 {
101         return snd_pcm_format_signed(format) >= 0;
102 }
103
104 /**
105  * snd_pcm_format_little_endian - Check the PCM format is little-endian
106  * @format: the format to check
107  *
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.
110  */
111 int snd_pcm_format_little_endian(snd_pcm_format_t format)
112 {
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:
129                 return 1;
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:
145                 return 0;
146         default:
147                 return -EINVAL;
148         }
149 }
150
151 /**
152  * snd_pcm_format_big_endian - Check the PCM format is big-endian
153  * @format: the format to check
154  *
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.
157  */
158 int snd_pcm_format_big_endian(snd_pcm_format_t format)
159 {
160         int val;
161
162         val = snd_pcm_format_little_endian(format);
163         if (val < 0)
164                 return val;
165         return !val;
166 }
167
168 /**
169  * snd_pcm_format_cpu_endian - Check the PCM format is CPU-endian
170  * @format: the format to check
171  *
172  * Returns 1 if the given PCM format is CPU-endian, 0 if
173  * opposite, or a negative error code if endian not specified.
174  */
175 int snd_pcm_format_cpu_endian(snd_pcm_format_t format)
176 {
177 #ifdef SNDRV_LITTLE_ENDIAN
178         return snd_pcm_format_little_endian(format);
179 #else
180         return snd_pcm_format_big_endian(format);
181 #endif
182 }
183
184 /**
185  * snd_pcm_format_width - return the bit-width of the format
186  * @format: the format to check
187  *
188  * Returns the bit-width of the format, or a negative error code
189  * if unknown format.
190  */
191 int snd_pcm_format_width(snd_pcm_format_t format)
192 {
193         switch (snd_enum_to_int(format)) {
194         case SNDRV_PCM_FORMAT_S8:
195         case SNDRV_PCM_FORMAT_U8:
196                 return 8;
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:
201                 return 16;
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:
206                 return 18;
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:
211                 return 20;
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:
220                 return 24;
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:
227                 return 32;
228         case SNDRV_PCM_FORMAT_FLOAT64_LE:
229         case SNDRV_PCM_FORMAT_FLOAT64_BE:
230                 return 64;
231         case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
232         case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
233                 return 32;
234         case SNDRV_PCM_FORMAT_MU_LAW:
235         case SNDRV_PCM_FORMAT_A_LAW:
236                 return 8;
237         case SNDRV_PCM_FORMAT_IMA_ADPCM:
238                 return 4;
239         default:
240                 return -EINVAL;
241         }
242 }
243
244 /**
245  * snd_pcm_format_physical_width - return the physical bit-width of the format
246  * @format: the format to check
247  *
248  * Returns the physical bit-width of the format, or a negative error code
249  * if unknown format.
250  */
251 int snd_pcm_format_physical_width(snd_pcm_format_t format)
252 {
253         switch (snd_enum_to_int(format)) {
254         case SNDRV_PCM_FORMAT_S8:
255         case SNDRV_PCM_FORMAT_U8:
256                 return 8;
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:
261                 return 16;
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:
274                 return 24;
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:
287                 return 32;
288         case SNDRV_PCM_FORMAT_FLOAT64_LE:
289         case SNDRV_PCM_FORMAT_FLOAT64_BE:
290                 return 64;
291         case SNDRV_PCM_FORMAT_MU_LAW:
292         case SNDRV_PCM_FORMAT_A_LAW:
293                 return 8;
294         case SNDRV_PCM_FORMAT_IMA_ADPCM:
295                 return 4;
296         default:
297                 return -EINVAL;
298         }
299 }
300
301 /**
302  * snd_pcm_format_size - return the byte size of samples on the given format
303  * @format: the format to check
304  *
305  * Returns the byte size of the given samples for the format, or a
306  * negative error code if unknown format.
307  */
308 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples)
309 {
310         switch (snd_enum_to_int(format)) {
311         case SNDRV_PCM_FORMAT_S8:
312         case SNDRV_PCM_FORMAT_U8:
313                 return samples;
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:
318                 return samples * 2;
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:
331                 return samples * 3;
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:
342                 return samples * 4;
343         case SNDRV_PCM_FORMAT_FLOAT64_LE:
344         case SNDRV_PCM_FORMAT_FLOAT64_BE:
345                 return samples * 8;
346         case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
347         case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
348                 return samples * 4;
349         case SNDRV_PCM_FORMAT_MU_LAW:
350         case SNDRV_PCM_FORMAT_A_LAW:
351                 return samples;
352         case SNDRV_PCM_FORMAT_IMA_ADPCM:
353                 if (samples & 1)
354                         return -EINVAL;
355                 return samples / 2;
356         default:
357                 return -EINVAL;
358         }
359 }
360
361 /**
362  * snd_pcm_format_silence_64 - return the silent data in 64bit integer
363  * @format: the format to check
364  *
365  * Returns the silent data in 64bit integer for the given format.
366  */
367 u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
368 {
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:
383                 return 0;
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;
411 #else
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;
436 #endif
437         case SNDRV_PCM_FORMAT_FLOAT_LE:
438         {
439                 union {
440                         float f;
441                         u_int32_t i;
442                 } u;
443                 u.f = 0.0;
444 #ifdef SNDRV_LITTLE_ENDIAN
445                 return u.i;
446 #else
447                 return bswap_32(u.i);
448 #endif
449         }
450         case SNDRV_PCM_FORMAT_FLOAT64_LE:
451         {
452                 union {
453                         double f;
454                         u_int64_t i;
455                 } u;
456                 u.f = 0.0;
457 #ifdef SNDRV_LITTLE_ENDIAN
458                 return u.i;
459 #else
460                 return bswap_64(u.i);
461 #endif
462         }
463         case SNDRV_PCM_FORMAT_FLOAT_BE:         
464         {
465                 union {
466                         float f;
467                         u_int32_t i;
468                 } u;
469                 u.f = 0.0;
470 #ifdef SNDRV_LITTLE_ENDIAN
471                 return bswap_32(u.i);
472 #else
473                 return u.i;
474 #endif
475         }
476         case SNDRV_PCM_FORMAT_FLOAT64_BE:
477         {
478                 union {
479                         double f;
480                         u_int64_t i;
481                 } u;
482                 u.f = 0.0;
483 #ifdef SNDRV_LITTLE_ENDIAN
484                 return bswap_64(u.i);
485 #else
486                 return u.i;
487 #endif
488         }
489         case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
490         case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE:
491                 return 0;       
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:
500                 return 0;
501         default:
502                 return -EINVAL;
503         }
504         return 0;
505 }
506
507 u_int32_t snd_pcm_format_silence_32(snd_pcm_format_t format)
508 {
509         return (u_int32_t)snd_pcm_format_silence_64(format);
510 }
511
512 u_int16_t snd_pcm_format_silence_16(snd_pcm_format_t format)
513 {
514         return (u_int16_t)snd_pcm_format_silence_64(format);
515 }
516
517 u_int8_t snd_pcm_format_silence(snd_pcm_format_t format)
518 {
519         return (u_int8_t)snd_pcm_format_silence_64(format);
520 }
521
522 /**
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
527  *
528  * Sets the silence data on the buffer for the given samples.
529  *
530  * Returns zero if successful, or a negative error code on failure.
531  */
532 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int samples)
533 {
534         if (samples == 0)
535                 return 0;
536         switch (snd_pcm_format_width(format)) {
537         case 4: {
538                 u_int8_t silence = snd_pcm_format_silence_64(format);
539                 unsigned int samples1;
540                 if (samples % 2 != 0)
541                         return -EINVAL;
542                 samples1 = samples / 2;
543                 memset(data, silence, samples1);
544                 break;
545         }
546         case 8: {
547                 u_int8_t silence = snd_pcm_format_silence_64(format);
548                 memset(data, silence, samples);
549                 break;
550         }
551         case 16: {
552                 u_int16_t silence = snd_pcm_format_silence_64(format);
553                 if (! silence)
554                         memset(data, 0, samples * 2);
555                 else {
556                         u_int16_t *data16 = data;
557                         while (samples-- > 0)
558                                 *data16++ = silence;
559                 }
560                 break;
561         }
562         case 24: {
563                 u_int32_t silence = snd_pcm_format_silence_64(format);
564                 if (! silence)
565                         memset(data, 0, samples * 3);
566                 else {
567                         while (samples-- > 0) {
568                                 u_int8_t *data8 = data;
569 #ifdef SNDRV_LITTLE_ENDIAN
570                                 *data8++ = silence >> 0;
571                                 *data8++ = silence >> 8;
572                                 *data8++ = silence >> 16;
573 #else
574                                 *data8++ = silence >> 16;
575                                 *data8++ = silence >> 8;
576                                 *data8++ = silence >> 0;
577 #endif
578                         }
579                 }
580                 break;
581         }
582         case 32: {
583                 u_int32_t silence = snd_pcm_format_silence_64(format);
584                 if (! silence)
585                         memset(data, 0, samples * 4);
586                 else {
587                         u_int32_t *data32 = data;
588                         while (samples-- > 0)
589                                 *data32++ = silence;
590                 }
591                 break;
592         }
593         case 64: {
594                 u_int64_t silence = snd_pcm_format_silence_64(format);
595                 if (! silence)
596                         memset(data, 0, samples * 8);
597                 else {
598                         u_int64_t *data64 = data;
599                         while (samples-- > 0)
600                                 *data64++ = silence;
601                 }
602                 break;
603         }
604         default:
605                 return -EINVAL;
606         }
607         return 0;
608 }
609
610 static int linear_formats[4*2*2] = {
611         SNDRV_PCM_FORMAT_S8,
612         SNDRV_PCM_FORMAT_S8,
613         SNDRV_PCM_FORMAT_U8,
614         SNDRV_PCM_FORMAT_U8,
615         SNDRV_PCM_FORMAT_S16_LE,
616         SNDRV_PCM_FORMAT_S16_BE,
617         SNDRV_PCM_FORMAT_U16_LE,
618         SNDRV_PCM_FORMAT_U16_BE,
619         SNDRV_PCM_FORMAT_S24_LE,
620         SNDRV_PCM_FORMAT_S24_BE,
621         SNDRV_PCM_FORMAT_U24_LE,
622         SNDRV_PCM_FORMAT_U24_BE,
623         SNDRV_PCM_FORMAT_S32_LE,
624         SNDRV_PCM_FORMAT_S32_BE,
625         SNDRV_PCM_FORMAT_U32_LE,
626         SNDRV_PCM_FORMAT_U32_BE
627 };
628
629 /**
630  * snd_pcm_build_linear_format - return the suitable linear format for the given condition
631  * @width: the bit-width
632  * @unsignd: 1 if unsigned, 0 if signed.
633  * @big_endian: 1 if big-endian, 0 if little-endian
634  *
635  * Returns the suitable linear format for the given condition.
636  */
637 snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian)
638 {
639         switch (width) {
640         case 8:
641                 width = 0;
642                 break;
643         case 16:
644                 width = 1;
645                 break;
646         case 24:
647                 width = 2;
648                 break;
649         case 32:
650                 width = 3;
651                 break;
652         default:
653                 return SND_PCM_FORMAT_UNKNOWN;
654         }
655         return snd_int_to_enum(((int(*)[2][2])linear_formats)[width][!!unsignd][!!big_endian]);
656 }
657
658 /**
659  * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
660  * @runtime: the runtime instance
661  *
662  * Determines the rate_min and rate_max fields from the rates bits of
663  * the given runtime->hw.
664  *
665  * Returns zero if successful.
666  */
667 int snd_pcm_limit_hw_rates(snd_pcm_runtime_t *runtime)
668 {
669         static unsigned rates[] = {
670                 /* ATTENTION: these values depend on the definition in pcm.h! */
671                 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
672                 64000, 88200, 96000, 176400, 192000
673         };
674         int i;
675         for (i = 0; i < (int)ARRAY_SIZE(rates); i++) {
676                 if (runtime->hw.rates & (1 << i)) {
677                         runtime->hw.rate_min = rates[i];
678                         break;
679                 }
680         }
681         for (i = (int)ARRAY_SIZE(rates) - 1; i >= 0; i--) {
682                 if (runtime->hw.rates & (1 << i)) {
683                         runtime->hw.rate_max = rates[i];
684                         break;
685                 }
686         }
687         return 0;
688 }