Commit 64d27f96 authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela

[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: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 9390ec85
...@@ -264,6 +264,8 @@ static int snd_pcm_plug_formats(struct snd_mask *mask, int format) ...@@ -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_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_U24_BE | SNDRV_PCM_FMTBIT_S24_BE | 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_LE | SNDRV_PCM_FMTBIT_S32_LE |
SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE); SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE);
snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW); snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW);
...@@ -280,6 +282,10 @@ static int preferred_formats[] = { ...@@ -280,6 +282,10 @@ static int preferred_formats[] = {
SNDRV_PCM_FORMAT_S16_BE, SNDRV_PCM_FORMAT_S16_BE,
SNDRV_PCM_FORMAT_U16_LE, SNDRV_PCM_FORMAT_U16_LE,
SNDRV_PCM_FORMAT_U16_BE, 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_LE,
SNDRV_PCM_FORMAT_S24_BE, SNDRV_PCM_FORMAT_S24_BE,
SNDRV_PCM_FORMAT_U24_LE, SNDRV_PCM_FORMAT_U24_LE,
...@@ -294,41 +300,37 @@ static int preferred_formats[] = { ...@@ -294,41 +300,37 @@ static int preferred_formats[] = {
int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask) int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask)
{ {
int i;
if (snd_mask_test(format_mask, format)) if (snd_mask_test(format_mask, format))
return format; return format;
if (! snd_pcm_plug_formats(format_mask, format)) if (! snd_pcm_plug_formats(format_mask, format))
return -EINVAL; return -EINVAL;
if (snd_pcm_format_linear(format)) { if (snd_pcm_format_linear(format)) {
int width = snd_pcm_format_width(format); unsigned int width = snd_pcm_format_width(format);
int unsignd = snd_pcm_format_unsigned(format); int unsignd = snd_pcm_format_unsigned(format) > 0;
int big = snd_pcm_format_big_endian(format); int big = snd_pcm_format_big_endian(format) > 0;
int format1; unsigned int badness, best = -1;
int wid, width1=width; int best_format = -1;
int dwidth1 = 8; for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) {
for (wid = 0; wid < 4; ++wid) { int f = preferred_formats[i];
int end, big1 = big; unsigned int w;
for (end = 0; end < 2; ++end) { if (!snd_mask_test(format_mask, f))
int sgn, unsignd1 = unsignd; continue;
for (sgn = 0; sgn < 2; ++sgn) { w = snd_pcm_format_width(f);
format1 = snd_pcm_build_linear_format(width1, unsignd1, big1); if (w >= width)
if (format1 >= 0 && badness = w - width;
snd_mask_test(format_mask, format1)) else
goto _found; badness = width - w + 32;
unsignd1 = !unsignd1; badness += snd_pcm_format_unsigned(f) != unsignd;
} badness += snd_pcm_format_big_endian(f) != big;
big1 = !big1; if (badness < best) {
} best_format = f;
if (width1 == 32) { best = badness;
dwidth1 = -dwidth1;
width1 = width;
}
width1 += dwidth1;
} }
return -EINVAL; }
_found: return best_format >= 0 ? best_format : -EINVAL;
return format1;
} else { } else {
unsigned int i;
switch (format) { switch (format) {
case SNDRV_PCM_FORMAT_MU_LAW: case SNDRV_PCM_FORMAT_MU_LAW:
for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) { for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) {
......
...@@ -422,38 +422,6 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int ...@@ -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); 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 * snd_pcm_limit_hw_rates - determine rate_min/rate_max fields
* @runtime: the runtime instance * @runtime: the runtime instance
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment