diff options
author | Takashi Iwai <tiwai@suse.de> | 2007-08-08 10:49:08 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-16 09:58:31 -0400 |
commit | 64d27f96cb719cf8b5dae634c4c548049d4ae6bf (patch) | |
tree | f10c68d67e15711d48a92ed258c93ca9018e5584 | |
parent | 9390ec85c0ab98444140190f936a37fa4eb945a2 (diff) |
[ALSA] Support 3-bytes 24bit format in PCM OSS emulation
Add the support of 3-bytes 24bit formats in PCM OSS emulation.
Also removed snd_pcm_build_linear_format() function. It's exported
just for OSS emulation, and now the code was changed without calling
this function.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r-- | sound/core/oss/pcm_plugin.c | 56 | ||||
-rw-r--r-- | sound/core/pcm_misc.c | 32 |
2 files changed, 29 insertions, 59 deletions
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index c0afb92869d3..25dcf96a5dc6 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c | |||
@@ -264,6 +264,8 @@ static int snd_pcm_plug_formats(struct snd_mask *mask, int format) | |||
264 | SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE | | 264 | SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE | |
265 | SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE | | 265 | SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE | |
266 | SNDRV_PCM_FMTBIT_U24_BE | SNDRV_PCM_FMTBIT_S24_BE | | 266 | SNDRV_PCM_FMTBIT_U24_BE | SNDRV_PCM_FMTBIT_S24_BE | |
267 | SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_S24_3LE | | ||
268 | SNDRV_PCM_FMTBIT_U24_3BE | SNDRV_PCM_FMTBIT_S24_3BE | | ||
267 | SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE | | 269 | SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE | |
268 | SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE); | 270 | SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE); |
269 | snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW); | 271 | snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW); |
@@ -280,6 +282,10 @@ static int preferred_formats[] = { | |||
280 | SNDRV_PCM_FORMAT_S16_BE, | 282 | SNDRV_PCM_FORMAT_S16_BE, |
281 | SNDRV_PCM_FORMAT_U16_LE, | 283 | SNDRV_PCM_FORMAT_U16_LE, |
282 | SNDRV_PCM_FORMAT_U16_BE, | 284 | SNDRV_PCM_FORMAT_U16_BE, |
285 | SNDRV_PCM_FORMAT_S24_3LE, | ||
286 | SNDRV_PCM_FORMAT_S24_3BE, | ||
287 | SNDRV_PCM_FORMAT_U24_3LE, | ||
288 | SNDRV_PCM_FORMAT_U24_3BE, | ||
283 | SNDRV_PCM_FORMAT_S24_LE, | 289 | SNDRV_PCM_FORMAT_S24_LE, |
284 | SNDRV_PCM_FORMAT_S24_BE, | 290 | SNDRV_PCM_FORMAT_S24_BE, |
285 | SNDRV_PCM_FORMAT_U24_LE, | 291 | SNDRV_PCM_FORMAT_U24_LE, |
@@ -294,41 +300,37 @@ static int preferred_formats[] = { | |||
294 | 300 | ||
295 | int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) | 301 | int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) |
296 | { | 302 | { |
303 | int i; | ||
304 | |||
297 | if (snd_mask_test(format_mask, format)) | 305 | if (snd_mask_test(format_mask, format)) |
298 | return format; | 306 | return format; |
299 | if (! snd_pcm_plug_formats(format_mask, format)) | 307 | if (! snd_pcm_plug_formats(format_mask, format)) |
300 | return -EINVAL; | 308 | return -EINVAL; |
301 | if (snd_pcm_format_linear(format)) { | 309 | if (snd_pcm_format_linear(format)) { |
302 | int width = snd_pcm_format_width(format); | 310 | unsigned int width = snd_pcm_format_width(format); |
303 | int unsignd = snd_pcm_format_unsigned(format); | 311 | int unsignd = snd_pcm_format_unsigned(format) > 0; |
304 | int big = snd_pcm_format_big_endian(format); | 312 | int big = snd_pcm_format_big_endian(format) > 0; |
305 | int format1; | 313 | unsigned int badness, best = -1; |
306 | int wid, width1=width; | 314 | int best_format = -1; |
307 | int dwidth1 = 8; | 315 | for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) { |
308 | for (wid = 0; wid < 4; ++wid) { | 316 | int f = preferred_formats[i]; |
309 | int end, big1 = big; | 317 | unsigned int w; |
310 | for (end = 0; end < 2; ++end) { | 318 | if (!snd_mask_test(format_mask, f)) |
311 | int sgn, unsignd1 = unsignd; | 319 | continue; |
312 | for (sgn = 0; sgn < 2; ++sgn) { | 320 | w = snd_pcm_format_width(f); |
313 | format1 = snd_pcm_build_linear_format(width1, unsignd1, big1); | 321 | if (w >= width) |
314 | if (format1 >= 0 && | 322 | badness = w - width; |
315 | snd_mask_test(format_mask, format1)) | 323 | else |
316 | goto _found; | 324 | badness = width - w + 32; |
317 | unsignd1 = !unsignd1; | 325 | badness += snd_pcm_format_unsigned(f) != unsignd; |
318 | } | 326 | badness += snd_pcm_format_big_endian(f) != big; |
319 | big1 = !big1; | 327 | if (badness < best) { |
320 | } | 328 | best_format = f; |
321 | if (width1 == 32) { | 329 | best = badness; |
322 | dwidth1 = -dwidth1; | ||
323 | width1 = width; | ||
324 | } | 330 | } |
325 | width1 += dwidth1; | ||
326 | } | 331 | } |
327 | return -EINVAL; | 332 | return best_format >= 0 ? best_format : -EINVAL; |
328 | _found: | ||
329 | return format1; | ||
330 | } else { | 333 | } else { |
331 | unsigned int i; | ||
332 | switch (format) { | 334 | switch (format) { |
333 | case SNDRV_PCM_FORMAT_MU_LAW: | 335 | case SNDRV_PCM_FORMAT_MU_LAW: |
334 | for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) { | 336 | for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) { |
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 0019c59a779d..9142fce4dda2 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c | |||
@@ -422,38 +422,6 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int | |||
422 | 422 | ||
423 | EXPORT_SYMBOL(snd_pcm_format_set_silence); | 423 | EXPORT_SYMBOL(snd_pcm_format_set_silence); |
424 | 424 | ||
425 | /* [width][unsigned][bigendian] */ | ||
426 | static int linear_formats[4][2][2] = { | ||
427 | {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, | ||
428 | { SNDRV_PCM_FORMAT_U8, SNDRV_PCM_FORMAT_U8}}, | ||
429 | {{SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_FORMAT_S16_BE}, | ||
430 | {SNDRV_PCM_FORMAT_U16_LE, SNDRV_PCM_FORMAT_U16_BE}}, | ||
431 | {{SNDRV_PCM_FORMAT_S24_LE, SNDRV_PCM_FORMAT_S24_BE}, | ||
432 | {SNDRV_PCM_FORMAT_U24_LE, SNDRV_PCM_FORMAT_U24_BE}}, | ||
433 | {{SNDRV_PCM_FORMAT_S32_LE, SNDRV_PCM_FORMAT_S32_BE}, | ||
434 | {SNDRV_PCM_FORMAT_U32_LE, SNDRV_PCM_FORMAT_U32_BE}} | ||
435 | }; | ||
436 | |||
437 | /** | ||
438 | * snd_pcm_build_linear_format - return the suitable linear format for the given condition | ||
439 | * @width: the bit-width | ||
440 | * @unsignd: 1 if unsigned, 0 if signed. | ||
441 | * @big_endian: 1 if big-endian, 0 if little-endian | ||
442 | * | ||
443 | * Returns the suitable linear format for the given condition. | ||
444 | */ | ||
445 | snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian) | ||
446 | { | ||
447 | if (width & 7) | ||
448 | return SND_PCM_FORMAT_UNKNOWN; | ||
449 | width = (width / 8) - 1; | ||
450 | if (width < 0 || width >= 4) | ||
451 | return SND_PCM_FORMAT_UNKNOWN; | ||
452 | return linear_formats[width][!!unsignd][!!big_endian]; | ||
453 | } | ||
454 | |||
455 | EXPORT_SYMBOL(snd_pcm_build_linear_format); | ||
456 | |||
457 | /** | 425 | /** |
458 | * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields | 426 | * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields |
459 | * @runtime: the runtime instance | 427 | * @runtime: the runtime instance |