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 /sound/core | |
| 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>
Diffstat (limited to 'sound/core')
| -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 c0afb92869..25dcf96a5d 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 0019c59a77..9142fce4dd 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 |
