svn commit: r282651 - head/sys/dev/sound/usb
Hans Petter Selasky
hselasky at FreeBSD.org
Fri May 8 17:07:12 UTC 2015
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--) {
More information about the svn-src-head
mailing list