[alsa-devel] [PATCH - oss plugin update 1/2] oss: Add support of 32-bit and other formats
Takashi Iwai
tiwai at suse.de
Mon Jun 24 09:54:42 CEST 2013
At Sun, 23 Jun 2013 01:25:18 +0100,
alex.d.wiggins at gmail.com wrote:
>
> From: Alex Wiggins <alex.d.wiggins at gmail.com>
>
> Added support of 32-bit and other audio formats via 3 changes:
>
> - Additional audio format definitions
> at the top of the file (if required);
>
> - Additional audio formats in oss_hw_params
> (to allow as input to pass to OSS);
>
> - Additional audio formats in oss_hw_constraint
> (to allow to report to ALSA).
>
> Signed-off-by: Alex Wiggins <alex.d.wiggins at gmail.com>
>
> diff --git a/oss/pcm_oss.c b/oss/pcm_oss.c
> index d43b44c..6d8dea4 100644
> --- a/oss/pcm_oss.c
> +++ b/oss/pcm_oss.c
> @@ -24,6 +24,32 @@
> #include <alsa/pcm_external.h>
> #include <linux/soundcard.h>
>
> +/* definitions for additional OSS formats if required */
> +#ifndef AFMT_S32_LE
> +#define AFMT_S32_LE 0x00001000
> +#endif
> +#ifndef AFMT_S32_BE
> +#define AFMT_S32_BE 0x00002000
> +#endif
> +#ifndef AFMT_S24_LE
> +#define AFMT_S24_LE 0x00008000
> +#endif
> +#ifndef AFMT_S24_BE
> +#define AFMT_S24_BE 0x00010000
> +#endif
> +#ifndef AFMT_S24_PACKED
> +#define AFMT_S24_PACKED 0x00040000
> +#endif
> +#ifndef AFMT_FLOAT
> +#define AFMT_FLOAT 0x00004000
> +#endif
> +#ifndef AFMT_SPDIF_RAW
> +#define AFMT_SPDIF_RAW 0x00020000
> +#endif
> +#ifndef AFMT_VORBIS
> +#define AFMT_VORBIS 0x00000800
> +#endif
> +
> typedef struct snd_pcm_oss {
> snd_pcm_ioplug_t io;
> char *device;
> @@ -165,6 +191,143 @@ static int oss_hw_params(snd_pcm_ioplug_t *io,
> case SND_PCM_FORMAT_S16_BE:
> oss->format = AFMT_S16_BE;
> break;
> + /* allow additional data formats (such as 32 bit) as input
> + to pass to OSS (set in OSS driver) */
> + case SND_PCM_FORMAT_S32_LE:
> + oss->format = AFMT_S32_LE;
> + break;
> + case SND_PCM_FORMAT_S32_BE:
> + oss->format = AFMT_S32_BE;
> + break;
> + case SND_PCM_FORMAT_S8:
> + oss->format = AFMT_S8;
> + break;
> + case SND_PCM_FORMAT_U16_LE:
> + oss->format = AFMT_U16_LE;
> + break;
> + case SND_PCM_FORMAT_U16_BE:
> + oss->format = AFMT_U16_BE;
> + break;
> + case SND_PCM_FORMAT_S24_LE:
> + oss->format = AFMT_S24_LE;
> + break;
> + case SND_PCM_FORMAT_S24_BE:
> + oss->format = AFMT_S24_BE;
> + break;
> + case SND_PCM_FORMAT_MU_LAW:
> + oss->format = AFMT_MU_LAW;
> + break;
> + case SND_PCM_FORMAT_A_LAW:
> + oss->format = AFMT_A_LAW;
> + break;
> + case SND_PCM_FORMAT_IMA_ADPCM:
> + oss->format = AFMT_IMA_ADPCM;
> + break;
> + case SND_PCM_FORMAT_MPEG:
> + oss->format = AFMT_MPEG;
> + break;
> + case SND_PCM_FORMAT_S24_3LE:
> + oss->format = AFMT_S24_PACKED;
> + break;
> + case SND_PCM_FORMAT_FLOAT:
> + oss->format = AFMT_FLOAT;
> + break;
> + case SND_PCM_FORMAT_IEC958_SUBFRAME:
> + oss->format = AFMT_SPDIF_RAW;
> + break;
> + /* following formats need defining checking native endian:
> + case SND_PCM_FORMAT_S16:
> + oss->format = AFMT_S16_NE;
> + break;
> + case SND_PCM_FORMAT_U16:
> + oss->format = AFMT_U16_NE;
> + break;
> + case SND_PCM_FORMAT_S24:
> + oss->format = AFMT_S24_NE;
> + break;
> + case SND_PCM_FORMAT_S32:
> + oss->format = AFMT_S32_NE;
> + */
Use #if/#endif instead of multi-line comments.
> + /* following formats found in ALSA but not in OSS:
> + case SND_PCM_FORMAT_U24_LE:
> + oss->format = AFMT_U24_LE;
> + break;
> + case SND_PCM_FORMAT_U24_BE:
> + oss->format = AFMT_U24_BE;
> + break;
> + case SND_PCM_FORMAT_U32_LE:
> + oss->format = AFMT_U32_LE;
> + break;
> + case SND_PCM_FORMAT_U32_BE:
> + oss->format = AFMT_U32_BE;
> + break;
> + case SND_PCM_FORMAT_FLOAT_LE:
> + oss->format = AFMT_FLOAT_LE;
> + break;
> + case SND_PCM_FORMAT_FLOAT_BE:
> + oss->format = AFMT_FLOAT_BE;
> + break;
> + case SND_PCM_FORMAT_FLOAT64_LE:
> + oss->format = AFMT_FLOAT64_LE;
> + break;
> + case SND_PCM_FORMAT_FLOAT64_BE:
> + oss->format = AFMT_FLOAT64_BE;
> + break;
> + case SND_PCM_FORMAT_IEC958_SUBFRAME_LE:
> + oss->format = AFMT_SPDIF_RAW_LE;
> + break;
> + case SND_PCM_FORMAT_IEC958_SUBFRAME_BE:
> + oss->format = AFMT_SPDIF_RAW_BE;
> + break;
> + case SND_PCM_FORMAT_GSM:
> + oss->format = AFMT_GSM;
> + break;
> + case SND_PCM_FORMAT_SPECIAL:
> + oss->format = AFMT_SPECIAL;
> + break;
> + case SND_PCM_FORMAT_S24_3BE:
> + oss->format = AFMT_S24_PACKED_BE;
> + break;
> + case SND_PCM_FORMAT_U24_3LE:
> + oss->format = AFMT_U24_PACKED;
> + break;
> + case SND_PCM_FORMAT_U24_3BE:
> + oss->format = AFMT_U24_PACKED_BE;
> + break;
> + case SND_PCM_FORMAT_S20_3LE:
> + oss->format = ;
> + break;
> + case SND_PCM_FORMAT_S20_3BE:
> + oss->format = ;
> + break;
> + case SND_PCM_FORMAT_U20_3LE:
> + oss->format = ;
> + break;
> + case SND_PCM_FORMAT_U20_3BE:
> + oss->format = ;
> + break;
> + case SND_PCM_FORMAT_S18_3LE:
> + oss->format = ;
> + break;
> + case SND_PCM_FORMAT_S18_3BE:
> + oss->format = ;
> + break;
> + case SND_PCM_FORMAT_U18_3LE:
> + oss->format = ;
> + break;
> + case SND_PCM_FORMAT_U18_3BE:
> + oss->format = ;
> + break;
> + case SND_PCM_FORMAT_U24:
> + oss->format = AFMT_U24_NE;
> + break;
> + case SND_PCM_FORMAT_U32:
> + oss->format = AFMT_U32_NE;
> + break;
> + case SND_PCM_FORMAT_FLOAT64:
> + oss->format = AFMT_FLOAT64;
> + break;
> + */
Ditto.
> default:
> fprintf(stderr, "*** OSS: unsupported format %s\n", snd_pcm_format_name(io->format));
> return -EINVAL;
> @@ -273,6 +436,40 @@ static int oss_hw_constraint(snd_pcm_oss_t *oss)
> format[nformats++] = SND_PCM_FORMAT_S16_BE;
> if (tmp & AFMT_MU_LAW)
> format[nformats++] = SND_PCM_FORMAT_MU_LAW;
> + /* allow additional data formats (such as 32 bit)
> + to be reported from OSS to ALSA below */
> + if (tmp & AFMT_S32_LE)
> + format[nformats++] = SND_PCM_FORMAT_S32_LE;
> + if (tmp & AFMT_S32_BE)
> + format[nformats++] = SND_PCM_FORMAT_S32_BE;
> + if (tmp & AFMT_A_LAW)
> + format[nformats++] = SND_PCM_FORMAT_A_LAW;
> + if (tmp & AFMT_IMA_ADPCM)
> + format[nformats++] = SND_PCM_FORMAT_IMA_ADPCM;
> + if (tmp & AFMT_S8)
> + format[nformats++] = SND_PCM_FORMAT_S8;
> + if (tmp & AFMT_U16_LE)
> + format[nformats++] = SND_PCM_FORMAT_U16_LE;
> + if (tmp & AFMT_U16_BE)
> + format[nformats++] = SND_PCM_FORMAT_U16_BE ;
> + if (tmp & AFMT_MPEG)
> + format[nformats++] = SND_PCM_FORMAT_MPEG;
> + if (tmp & AFMT_FLOAT)
> + format[nformats++] = SND_PCM_FORMAT_FLOAT;
> + if (tmp & AFMT_S24_LE)
> + format[nformats++] = SND_PCM_FORMAT_S24_LE;
> + if (tmp & AFMT_S24_BE)
> + format[nformats++] = SND_PCM_FORMAT_S24_BE;
> + if (tmp & AFMT_SPDIF_RAW)
> + format[nformats++] = SND_PCM_FORMAT_IEC958_SUBFRAME;
> + if (tmp & AFMT_S24_PACKED)
> + format[nformats++] = SND_PCM_FORMAT_S24_3LE;
> + /* following formats found in OSS but not in ALSA */
> + if (tmp & AFMT_AC3)
> + format[nformats++] = SND_PCM_FORMAT_UNKNOWN;
> + if (tmp & AFMT_VORBIS)
> + format[nformats++] = SND_PCM_FORMAT_UNKNOWN;
> + /* assume signed 16 bit (native CPU endian) if not found above */
> if (! nformats)
> format[nformats++] = SND_PCM_FORMAT_S16;
> if ((err = snd_pcm_ioplug_set_param_list(io, SND_PCM_IOPLUG_HW_FORMAT,
You need to adjust format[] array size if you add more possible
formats.
thanks,
Takashi
More information about the Alsa-devel
mailing list