[alsa-devel] [PATCH - oss plugin update revised 1/2] oss: Add support of 32-bit and other formats

alex.d.wiggins at gmail.com alex.d.wiggins at gmail.com
Sun Jun 30 02:47:07 CEST 2013


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..d5b5bc4 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,145 @@ 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: */
+	#if 0
+	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;
+	#endif
+	/* following formats found in ALSA but not in OSS: */
+	#if 0
+	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;
+	#endif
 	default:
 		fprintf(stderr, "*** OSS: unsupported format %s\n", snd_pcm_format_name(io->format));
 		return -EINVAL;
@@ -239,7 +404,7 @@ static int oss_hw_constraint(snd_pcm_oss_t *oss)
 		SND_PCM_ACCESS_MMAP_INTERLEAVED
 	};
 	unsigned int nformats;
-	unsigned int format[5];
+	unsigned int format[20];
 	unsigned int nchannels;
 	unsigned int channel[6];
 	/* period and buffer bytes must be power of two */
@@ -273,6 +438,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,
-- 
1.8.3.1



More information about the Alsa-devel mailing list