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
This commit is contained in:
parent
5abe80cf6b
commit
4ece1a889b
@ -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;
|
||||
i = sscanf(b2, "%d.%d", &ch, &ext);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
/* check there is at least one channel */
|
||||
if (ch <= ext)
|
||||
return (0);
|
||||
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 (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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(tmp) == 0)
|
||||
return (0);
|
||||
|
||||
strlcpy(buf, tmp, len);
|
||||
|
||||
return (snd_str2afmt(buf));
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -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];
|
||||
|
||||
|
@ -561,6 +561,20 @@ feeder_build_mixer(struct pcm_channel *c, struct feeder_chain_desc *cdesc)
|
||||
((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)
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user