Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 May 2015 17:07:11 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r282651 - head/sys/dev/sound/usb
Message-ID:  <201505081707.t48H7BSI081826@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Fri May  8 17:07:11 2015
New Revision: 282651
URL: https://svnweb.freebsd.org/changeset/base/282651

Log:
  Add support for more than 8 audio channels per PCM stream for USB
  audio class compliant devices under FreeBSD. Tested using 16 recording
  and 16 playback audio channels simultaneously.
  
  MFC after:	2 weeks

Modified:
  head/sys/dev/sound/usb/uaudio.c

Modified: head/sys/dev/sound/usb/uaudio.c
==============================================================================
--- head/sys/dev/sound/usb/uaudio.c	Fri May  8 17:00:33 2015	(r282650)
+++ head/sys/dev/sound/usb/uaudio.c	Fri May  8 17:07:11 2015	(r282651)
@@ -115,6 +115,8 @@ SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, def
 #define	UAUDIO_NFRAMES		64	/* must be factor of 8 due HS-USB */
 #define	UAUDIO_NCHANBUFS	2	/* number of outstanding request */
 #define	UAUDIO_RECURSE_LIMIT	255	/* rounds */
+#define	UAUDIO_CHANNELS_MAX	MIN(64, AFMT_CHANNEL_MAX)
+#define	UAUDIO_MATRIX_MAX	8	/* channels */
 
 #define	MAKE_WORD(h,l) (((h) << 8) | (l))
 #define	BIT_TEST(bm,bno) (((bm)[(bno) / 8] >> (7 - ((bno) % 8))) & 1)
@@ -346,6 +348,7 @@ struct uaudio_softc {
 	uint8_t	sc_uq_au_no_xu:1;
 	uint8_t	sc_uq_bad_adc:1;
 	uint8_t	sc_uq_au_vendor_class:1;
+	uint8_t	sc_pcm_bitperfect:1;
 };
 
 struct uaudio_terminal_node {
@@ -1062,6 +1065,10 @@ uaudio_attach_sub(device_t dev, kobj_cla
 		 */
 		uaudio_pcm_setflags(dev, SD_F_SOFTPCMVOL);
 	}
+	if (sc->sc_pcm_bitperfect) {
+		DPRINTF("device needs bitperfect by default\n");
+		uaudio_pcm_setflags(dev, SD_F_BITPERFECT);
+	}
 	if (mixer_init(dev, mixer_class, sc))
 		goto detach;
 	sc->sc_mixer_init = 1;
@@ -1826,19 +1833,21 @@ uaudio_chan_fill_info_sub(struct uaudio_
 
 		format = chan_alt->p_fmt->freebsd_fmt;
 
+		/* get default SND_FORMAT() */
+		format = SND_FORMAT(format, chan_alt->channels, 0);
+
 		switch (chan_alt->channels) {
-		case 2:
-			/* stereo */
-			format = SND_FORMAT(format, 2, 0);
-			break;
+		uint32_t temp_fmt;
 		case 1:
-			/* mono */
-			format = SND_FORMAT(format, 1, 0);
+		case 2:
+			/* mono and stereo */
 			break;
 		default:
 			/* surround and more */
-			format = feeder_matrix_default_format(
-			    SND_FORMAT(format, chan_alt->channels, 0));
+			temp_fmt = feeder_matrix_default_format(format);
+			/* if multichannel, then format can be zero */
+			if (temp_fmt != 0)
+				format = temp_fmt;
 			break;
 		}
 
@@ -1865,6 +1874,10 @@ uaudio_chan_fill_info_sub(struct uaudio_
 		chan->pcm_cap.fmtlist = chan->pcm_format;
 		chan->pcm_cap.fmtlist[0] = format;
 
+		/* check if device needs bitperfect */
+		if (chan_alt->channels > UAUDIO_MATRIX_MAX)
+			sc->sc_pcm_bitperfect = 1;
+
 		if (rate < chan->pcm_cap.minspeed || chan->pcm_cap.minspeed == 0)
 			chan->pcm_cap.minspeed = rate;
 		if (rate > chan->pcm_cap.maxspeed || chan->pcm_cap.maxspeed == 0)
@@ -1939,15 +1952,15 @@ uaudio_chan_fill_info(struct uaudio_soft
 			channels = 4;
 			break;
 		default:
-			channels = 16;
+			channels = UAUDIO_CHANNELS_MAX;
 			break;
 		}
-	} else if (channels > 16) {
-		channels = 16;
-	}
-	if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND)) {
+	} else if (channels > UAUDIO_CHANNELS_MAX)
+		channels = UAUDIO_CHANNELS_MAX;
+
+	if (sbuf_new(&sc->sc_sndstat, NULL, 4096, SBUF_AUTOEXTEND))
 		sc->sc_sndstat_valid = 1;
-	}
+
 	/* try to search for a valid config */
 
 	for (x = channels; x; x--) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505081707.t48H7BSI081826>