Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 May 2015 17:00:34 +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: r282650 - in head/sys: dev/sound/pcm sys
Message-ID:  <201505081700.t48H0Y6q077749@svn.freebsd.org>

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

Log:
  Extend the maximum number of allowed PCM channels in a PCM stream to
  127 and decrease the maximum number of sub-channels to 1. These
  definitions are only used inside the kernel and can be changed later
  if more than one sub-channel is desired. This has been done to allow
  so-called USB audio rack modules to work with FreeBSD.
  
  Bump the FreeBSD version to force recompiling all external modules.
  
  MFC after:	2 weeks
  Reviewed by:	mav

Modified:
  head/sys/dev/sound/pcm/channel.c
  head/sys/dev/sound/pcm/channel.h
  head/sys/dev/sound/pcm/feeder_chain.c
  head/sys/dev/sound/pcm/sound.h
  head/sys/sys/param.h

Modified: head/sys/dev/sound/pcm/channel.c
==============================================================================
--- head/sys/dev/sound/pcm/channel.c	Fri May  8 16:43:01 2015	(r282649)
+++ head/sys/dev/sound/pcm/channel.c	Fri May  8 17:00:33 2015	(r282650)
@@ -1020,32 +1020,17 @@ static const struct {
 	{    NULL,  NULL, NULL, 0           }
 };
 
-static const struct {
-	char *name, *alias1, *alias2;
-	int matrix_id;
-} matrix_id_tab[] = {
-	{ "1.0",  "1",   "mono", SND_CHN_MATRIX_1_0     },
-	{ "2.0",  "2", "stereo", SND_CHN_MATRIX_2_0     },
-	{ "2.1", NULL,     NULL, SND_CHN_MATRIX_2_1     },
-	{ "3.0",  "3",     NULL, SND_CHN_MATRIX_3_0     },
-	{ "3.1", NULL,     NULL, SND_CHN_MATRIX_3_1     },
-	{ "4.0",  "4",   "quad", SND_CHN_MATRIX_4_0     },
-	{ "4.1", NULL,     NULL, SND_CHN_MATRIX_4_1     },
-	{ "5.0",  "5",     NULL, SND_CHN_MATRIX_5_0     },
-	{ "5.1",  "6",     NULL, SND_CHN_MATRIX_5_1     },
-	{ "6.0", NULL,     NULL, SND_CHN_MATRIX_6_0     },
-	{ "6.1",  "7",     NULL, SND_CHN_MATRIX_6_1     },
-	{ "7.0", NULL,     NULL, SND_CHN_MATRIX_7_0     },
-	{ "7.1",  "8",     NULL, SND_CHN_MATRIX_7_1     },
-	{  NULL, NULL,     NULL, SND_CHN_MATRIX_UNKNOWN }
-};
-
 uint32_t
 snd_str2afmt(const char *req)
 {
-	uint32_t i, afmt;
-	int matrix_id;
-	char b1[8], b2[8];
+	int ext;
+	int ch;
+	int i;
+	char b1[8];
+	char b2[8];
+
+	memset(b1, 0, sizeof(b1));
+	memset(b2, 0, sizeof(b2));
 
 	i = sscanf(req, "%5[^:]:%6s", b1, b2);
 
@@ -1059,88 +1044,78 @@ snd_str2afmt(const char *req)
 	} else
 		return (0);
 
-	afmt = 0;
-	matrix_id = SND_CHN_MATRIX_UNKNOWN;
-
-	for (i = 0; afmt == 0 && afmt_tab[i].name != NULL; i++) {
-		if (strcasecmp(afmt_tab[i].name, b1) == 0 ||
-		    (afmt_tab[i].alias1 != NULL &&
-		    strcasecmp(afmt_tab[i].alias1, b1) == 0) ||
-		    (afmt_tab[i].alias2 != NULL &&
-		    strcasecmp(afmt_tab[i].alias2, b1) == 0)) {
-			afmt = afmt_tab[i].afmt;
-			strlcpy(b1, afmt_tab[i].name, sizeof(b1));
-		}
-	}
+	i = sscanf(b2, "%d.%d", &ch, &ext);
 
-	if (afmt == 0)
+	if (i == 0) {
+		if (strcasecmp(b2, "mono") == 0) {
+			ch = 1;
+			ext = 0;
+		} else if (strcasecmp(b2, "stereo") == 0) {
+			ch = 2;
+			ext = 0;
+		} else if (strcasecmp(b2, "quad") == 0) {
+			ch = 4;
+			ext = 0;
+		} else
+			return (0);
+	} else if (i == 1) {
+		if (ch < 1 || ch > AFMT_CHANNEL_MAX)
+			return (0);
+		ext = 0;
+	} else if (i == 2) {
+		if (ext < 0 || ext > AFMT_EXTCHANNEL_MAX)
+			return (0);
+		if (ch < 1 || (ch + ext) > AFMT_CHANNEL_MAX)
+			return (0);
+	} else
 		return (0);
 
-	for (i = 0; matrix_id == SND_CHN_MATRIX_UNKNOWN &&
-	    matrix_id_tab[i].name != NULL; i++) {
-		if (strcmp(matrix_id_tab[i].name, b2) == 0 ||
-		    (matrix_id_tab[i].alias1 != NULL &&
-		    strcmp(matrix_id_tab[i].alias1, b2) == 0) ||
-		    (matrix_id_tab[i].alias2 != NULL &&
-		    strcasecmp(matrix_id_tab[i].alias2, b2) == 0)) {
-			matrix_id = matrix_id_tab[i].matrix_id;
-			strlcpy(b2, matrix_id_tab[i].name, sizeof(b2));
+	for (i = 0; afmt_tab[i].name != NULL; i++) {
+		if (strcasecmp(afmt_tab[i].name, b1) != 0) {
+			if (afmt_tab[i].alias1 == NULL)
+				continue;
+			if (strcasecmp(afmt_tab[i].alias1, b1) != 0) {
+				if (afmt_tab[i].alias2 == NULL)
+					continue;
+				if (strcasecmp(afmt_tab[i].alias2, b1) != 0)
+					continue;
+			}
 		}
+		/* found a match */
+		return (SND_FORMAT(afmt_tab[i].afmt, ch + ext, ext));	
 	}
-
-	if (matrix_id == SND_CHN_MATRIX_UNKNOWN)
-		return (0);
-
-#ifndef _KERNEL
-	printf("Parse OK: '%s' -> '%s:%s' %d\n", req, b1, b2,
-	    (int)(b2[0]) - '0' + (int)(b2[2]) - '0');
-#endif
-
-	return (SND_FORMAT(afmt, b2[0] - '0' + b2[2] - '0', b2[2] - '0'));
+	/* not a valid format */
+	return (0);
 }
 
 uint32_t
 snd_afmt2str(uint32_t afmt, char *buf, size_t len)
 {
-	uint32_t i, enc, ch, ext;
-	char tmp[AFMTSTR_LEN];
+	uint32_t enc;
+	uint32_t ext;
+	uint32_t ch;
+	int i;
 
 	if (buf == NULL || len < AFMTSTR_LEN)
 		return (0);
 
-	
-	bzero(tmp, sizeof(tmp));
+	memset(buf, 0, len);
 
 	enc = AFMT_ENCODING(afmt);
 	ch = AFMT_CHANNEL(afmt);
 	ext = AFMT_EXTCHANNEL(afmt);
-
-	for (i = 0; afmt_tab[i].name != NULL; i++) {
-		if (enc == afmt_tab[i].afmt) {
-			strlcpy(tmp, afmt_tab[i].name, sizeof(tmp));
-			strlcat(tmp, ":", sizeof(tmp));
-			break;
-		}
-	}
-
-	if (strlen(tmp) == 0)
+	/* check there is at least one channel */
+	if (ch <= ext)
 		return (0);
-	
-	for (i = 0; matrix_id_tab[i].name != NULL; i++) {
-		if (ch == (matrix_id_tab[i].name[0] - '0' +
-		    matrix_id_tab[i].name[2] - '0') &&
-		    ext == (matrix_id_tab[i].name[2] - '0')) {
-			strlcat(tmp, matrix_id_tab[i].name, sizeof(tmp));
-			break;
-		}
+	for (i = 0; afmt_tab[i].name != NULL; i++) {
+		if (enc != afmt_tab[i].afmt)
+			continue;
+		/* found a match */
+		snprintf(buf, len, "%s:%d.%d",
+		    afmt_tab[i].name, ch - ext, ext);
+		return (SND_FORMAT(enc, ch, ext));
 	}
-
-	if (strlen(tmp) == 0)
-		return (0);
-
-	strlcpy(buf, tmp, len);
-
-	return (snd_str2afmt(buf));
+	return (0);
 }
 
 int

Modified: head/sys/dev/sound/pcm/channel.h
==============================================================================
--- head/sys/dev/sound/pcm/channel.h	Fri May  8 16:43:01 2015	(r282649)
+++ head/sys/dev/sound/pcm/channel.h	Fri May  8 17:00:33 2015	(r282650)
@@ -162,6 +162,7 @@ struct pcm_channel {
 	} channels;
 
 	struct pcmchan_matrix matrix;
+  	struct pcmchan_matrix matrix_scratch;
 
 	int volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
 

Modified: head/sys/dev/sound/pcm/feeder_chain.c
==============================================================================
--- head/sys/dev/sound/pcm/feeder_chain.c	Fri May  8 16:43:01 2015	(r282649)
+++ head/sys/dev/sound/pcm/feeder_chain.c	Fri May  8 17:00:33 2015	(r282650)
@@ -561,6 +561,20 @@ feeder_build_mixer(struct pcm_channel *c
 	((c)->mode == FEEDER_CHAIN_LEAN &&				\
 	!((c)->current.afmt & (AFMT_S16_NE | AFMT_S32_NE)))))
 
+static void
+feeder_default_matrix(struct pcmchan_matrix *m, uint32_t fmt, int id)
+{
+	int x;
+
+	memset(m, 0, sizeof(*m));
+
+	m->id = id;
+	m->channels = AFMT_CHANNEL(fmt);
+	m->ext = AFMT_EXTCHANNEL(fmt);
+	for (x = 0; x != SND_CHN_T_MAX; x++)
+		m->offset[x] = -1;
+}
+
 int
 feeder_chain(struct pcm_channel *c)
 {
@@ -641,10 +655,10 @@ feeder_chain(struct pcm_channel *c)
 	 */
 	hwmatrix = CHANNEL_GETMATRIX(c->methods, c->devinfo, hwfmt);
 	if (hwmatrix == NULL) {
-		device_printf(c->dev,
-		    "%s(): failed to acquire hw matrix [0x%08x]\n",
-		    __func__, hwfmt);
-		return (ENODEV);
+		/* setup a default matrix */
+		hwmatrix = &c->matrix_scratch;
+		feeder_default_matrix(hwmatrix, hwfmt,
+		    SND_CHN_MATRIX_UNKNOWN);
 	}
 	/* ..... and rebuild hwfmt. */
 	hwfmt = SND_FORMAT(hwfmt, hwmatrix->channels, hwmatrix->ext);
@@ -656,13 +670,14 @@ feeder_chain(struct pcm_channel *c)
 	    softmatrix->ext != AFMT_EXTCHANNEL(softfmt)) {
 		softmatrix = feeder_matrix_format_map(softfmt);
 		if (softmatrix == NULL) {
-			device_printf(c->dev,
-			    "%s(): failed to acquire soft matrix [0x%08x]\n",
-			    __func__, softfmt);
-			return (ENODEV);
+			/* setup a default matrix */
+		  	softmatrix = &c->matrix;
+			feeder_default_matrix(softmatrix, softfmt,
+			    SND_CHN_MATRIX_PCMCHANNEL);
+		} else {
+			c->matrix = *softmatrix;
+			c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL;
 		}
-		c->matrix = *softmatrix;
-		c->matrix.id = SND_CHN_MATRIX_PCMCHANNEL;
 	}
 	softfmt = SND_FORMAT(softfmt, softmatrix->channels, softmatrix->ext);
 	if (softfmt != c->format)

Modified: head/sys/dev/sound/pcm/sound.h
==============================================================================
--- head/sys/dev/sound/pcm/sound.h	Fri May  8 16:43:01 2015	(r282649)
+++ head/sys/dev/sound/pcm/sound.h	Fri May  8 17:00:33 2015	(r282650)
@@ -213,10 +213,12 @@ struct snd_mixer;
  * ~(0xb00ff7ff)
  */
 #define AFMT_ENCODING_MASK	0xf00fffff
-#define AFMT_CHANNEL_MASK	0x01f00000
+#define AFMT_CHANNEL_MASK	0x07f00000
 #define AFMT_CHANNEL_SHIFT	20
-#define AFMT_EXTCHANNEL_MASK	0x0e000000
-#define AFMT_EXTCHANNEL_SHIFT	25
+#define AFMT_CHANNEL_MAX	0x7f
+#define AFMT_EXTCHANNEL_MASK	0x08000000
+#define AFMT_EXTCHANNEL_SHIFT	27
+#define AFMT_EXTCHANNEL_MAX	1
 
 #define AFMT_ENCODING(v)	((v) & AFMT_ENCODING_MASK)
 

Modified: head/sys/sys/param.h
==============================================================================
--- head/sys/sys/param.h	Fri May  8 16:43:01 2015	(r282649)
+++ head/sys/sys/param.h	Fri May  8 17:00:33 2015	(r282650)
@@ -58,7 +58,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1100072	/* Master, propagated to newvers */
+#define __FreeBSD_version 1100073	/* Master, propagated to newvers */
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,



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