From 64d27f96cb719cf8b5dae634c4c548049d4ae6bf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 8 Aug 2007 16:49:08 +0200 Subject: [PATCH] [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 Signed-off-by: Jaroslav Kysela --- sound/core/oss/pcm_plugin.c | 56 +++++++++++++++++++------------------ 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) SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_BE | SNDRV_PCM_FMTBIT_S24_BE | + SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_S24_3LE | + SNDRV_PCM_FMTBIT_U24_3BE | SNDRV_PCM_FMTBIT_S24_3BE | SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE); snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW); @@ -280,6 +282,10 @@ static int preferred_formats[] = { SNDRV_PCM_FORMAT_S16_BE, SNDRV_PCM_FORMAT_U16_LE, SNDRV_PCM_FORMAT_U16_BE, + SNDRV_PCM_FORMAT_S24_3LE, + SNDRV_PCM_FORMAT_S24_3BE, + SNDRV_PCM_FORMAT_U24_3LE, + SNDRV_PCM_FORMAT_U24_3BE, SNDRV_PCM_FORMAT_S24_LE, SNDRV_PCM_FORMAT_S24_BE, SNDRV_PCM_FORMAT_U24_LE, @@ -294,41 +300,37 @@ static int preferred_formats[] = { int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) { + int i; + if (snd_mask_test(format_mask, format)) return format; if (! snd_pcm_plug_formats(format_mask, format)) return -EINVAL; if (snd_pcm_format_linear(format)) { - int width = snd_pcm_format_width(format); - int unsignd = snd_pcm_format_unsigned(format); - int big = snd_pcm_format_big_endian(format); - int format1; - int wid, width1=width; - int dwidth1 = 8; - for (wid = 0; wid < 4; ++wid) { - int end, big1 = big; - for (end = 0; end < 2; ++end) { - int sgn, unsignd1 = unsignd; - for (sgn = 0; sgn < 2; ++sgn) { - format1 = snd_pcm_build_linear_format(width1, unsignd1, big1); - if (format1 >= 0 && - snd_mask_test(format_mask, format1)) - goto _found; - unsignd1 = !unsignd1; - } - big1 = !big1; - } - if (width1 == 32) { - dwidth1 = -dwidth1; - width1 = width; + unsigned int width = snd_pcm_format_width(format); + int unsignd = snd_pcm_format_unsigned(format) > 0; + int big = snd_pcm_format_big_endian(format) > 0; + unsigned int badness, best = -1; + int best_format = -1; + for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) { + int f = preferred_formats[i]; + unsigned int w; + if (!snd_mask_test(format_mask, f)) + continue; + w = snd_pcm_format_width(f); + if (w >= width) + badness = w - width; + else + badness = width - w + 32; + badness += snd_pcm_format_unsigned(f) != unsignd; + badness += snd_pcm_format_big_endian(f) != big; + if (badness < best) { + best_format = f; + best = badness; } - width1 += dwidth1; } - return -EINVAL; - _found: - return format1; + return best_format >= 0 ? best_format : -EINVAL; } else { - unsigned int i; switch (format) { case SNDRV_PCM_FORMAT_MU_LAW: 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 EXPORT_SYMBOL(snd_pcm_format_set_silence); -/* [width][unsigned][bigendian] */ -static int linear_formats[4][2][2] = { - {{ SNDRV_PCM_FORMAT_S8, SNDRV_PCM_FORMAT_S8}, - { SNDRV_PCM_FORMAT_U8, SNDRV_PCM_FORMAT_U8}}, - {{SNDRV_PCM_FORMAT_S16_LE, SNDRV_PCM_FORMAT_S16_BE}, - {SNDRV_PCM_FORMAT_U16_LE, SNDRV_PCM_FORMAT_U16_BE}}, - {{SNDRV_PCM_FORMAT_S24_LE, SNDRV_PCM_FORMAT_S24_BE}, - {SNDRV_PCM_FORMAT_U24_LE, SNDRV_PCM_FORMAT_U24_BE}}, - {{SNDRV_PCM_FORMAT_S32_LE, SNDRV_PCM_FORMAT_S32_BE}, - {SNDRV_PCM_FORMAT_U32_LE, SNDRV_PCM_FORMAT_U32_BE}} -}; - -/** - * snd_pcm_build_linear_format - return the suitable linear format for the given condition - * @width: the bit-width - * @unsignd: 1 if unsigned, 0 if signed. - * @big_endian: 1 if big-endian, 0 if little-endian - * - * Returns the suitable linear format for the given condition. - */ -snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian) -{ - if (width & 7) - return SND_PCM_FORMAT_UNKNOWN; - width = (width / 8) - 1; - if (width < 0 || width >= 4) - return SND_PCM_FORMAT_UNKNOWN; - return linear_formats[width][!!unsignd][!!big_endian]; -} - -EXPORT_SYMBOL(snd_pcm_build_linear_format); - /** * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields * @runtime: the runtime instance -- 2.39.5