diff options
author | hselasky <hselasky@FreeBSD.org> | 2015-06-03 15:32:43 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2015-06-03 15:32:43 +0000 |
commit | 79cd6230a5ab8914948a63f3edd0eb3baae36865 (patch) | |
tree | 3d2dd1d36683dc01586692410c01bd4910fb4cf3 /sys/dev/sound/pcm/channel.c | |
parent | 02441119bc168497d2df4672b0666f72aa513093 (diff) | |
download | FreeBSD-src-79cd6230a5ab8914948a63f3edd0eb3baae36865.zip FreeBSD-src-79cd6230a5ab8914948a63f3edd0eb3baae36865.tar.gz |
MFC r282650 and r282651:
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.
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.
Bump the FreeBSD version to force recompiling all external modules.
Diffstat (limited to 'sys/dev/sound/pcm/channel.c')
-rw-r--r-- | sys/dev/sound/pcm/channel.c | 147 |
1 files changed, 61 insertions, 86 deletions
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index 75b02d0..6a3609b 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -1029,32 +1029,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); @@ -1068,88 +1053,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)); - } - } - - if (afmt == 0) + i = sscanf(b2, "%d.%d", &ch, &ext); + + 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 |