kern/75276: Volumes of USB audio can be controlled separately (uaudio)

Kazuhito HONDA kazuhito at ph.noda.tus.ac.jp
Sun Dec 19 11:40:07 PST 2004


>Number:         75276
>Category:       kern
>Synopsis:       Volumes of USB audio can be controlled separately (uaudio)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Dec 19 19:40:06 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Kazuhito HONDA
>Release:        FreeBSD 6.0-CURRENT i386
>Organization:
>Environment:
System: FreeBSD kaoru 6.0-CURRENT FreeBSD 6.0-CURRENT #192: Mon Dec 20 03:46:53 JST 2004 root at kaoru:/usr/obj/src/sys/i386/compile/KAORU.6.0B.0 i386

USB audio device: Sound Blaster Digital Music (SBDM, Creative Labs.)
>Description:
My SBDM has 6 feature descriptors and can be change 5 volumes separately 
(one feature descriptor has mute only).those are volumes, 
from line to output, from line to record, from mic to output, 
from mic to record and to speaker.
But FreeBSD recognize only:

Mixer pcm      is currently set to  75:75

>How-To-Repeat:
>Fix:
At first, you must apply the patch of kern/75274.
After that, apply the patch below.
When This patch was applied, FreeBSD recognize SBDM's volumes as

Mixer speaker  is currently set to  75:75
Mixer line     is currently set to  75:75
Mixer mic      is currently set to   0:0

In this case, two volumes from line to output and record, 
and two volumes from mic to output and to record, 
share "Mixer line" and "Mixer mic", respectively.
It is difficult to separate these sharing in FreeBSD sound system.

--- F_m.diff begins here ---
--- src/sys/dev/sound/usb/uaudio-91.c	Mon Dec 20 02:42:53 2004
+++ src/sys/dev/sound/usb/uaudio-91-m.c	Mon Dec 20 03:51:36 2004
@@ -1,5 +1,5 @@
 /*	$NetBSD: uaudio.c,v 1.91 2004/11/05 17:46:14 kent Exp $	*/
-/*	$FreeBSD: src/sys/dev/sound/usb/uaudio-91.c,v $: */
+/*	$FreeBSD: src/sys/dev/sound/usb/uaudio-91-m.c,v $: */
 
 /*
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -144,8 +144,9 @@ struct mixerctl {
 	u_int		mul;
 #if defined(__FreeBSD__) /* XXXXX */
 	unsigned	ctl;
-#else
+#endif
 	u_int8_t	class;
+#if !defined(__FreeBSD__)
 	char		ctlname[MAX_AUDIO_DEV_LEN];
 	char		*ctlunit;
 #endif
@@ -263,13 +264,17 @@ struct io_terminal {
 #define UAC_EQUAL	2
 #define UAC_RECORD	3
 #define UAC_NCLASSES	4
-#if !defined(__FreeBSD__)
 #ifdef USB_DEBUG
+#if defined(__FreeBSD__)
+#define AudioCinputs	"inputs"
+#define AudioCoutputs	"outputs"
+#define AudioCrecord	"record"
+#define AudioCequalization	"equalization"
+#endif
 Static const char *uac_names[] = {
 	AudioCoutputs, AudioCinputs, AudioCequalization, AudioCrecord,
 };
 #endif
-#endif
 
 Static usbd_status uaudio_identify_ac
 	(struct uaudio_softc *, const usb_config_descriptor_t *);
@@ -307,9 +312,12 @@ Static void	uaudio_add_selector
 #ifdef USB_DEBUG
 Static const char *uaudio_get_terminal_name(int);
 #endif
-#if !defined(__FreeBSD__)
 Static int	uaudio_determine_class
 	(const struct io_terminal *, struct mixerctl *);
+#if defined(__FreeBSD__)
+Static const int uaudio_feature_name(const struct io_terminal *,
+		    struct mixerctl *);
+#else
 Static const char *uaudio_feature_name
 	(const struct io_terminal *, struct mixerctl *);
 #endif
@@ -738,7 +746,14 @@ uaudio_mixer_add_ctl(struct uaudio_softc
 	size_t len;
 	struct mixerctl *nmc;
 
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+	if (mc->class < UAC_NCLASSES) {
+		DPRINTF(("%s: adding %s.%d\n",
+			 __func__, uac_names[mc->class], mc->ctl));
+	} else {
+		DPRINTF(("%s: adding %d\n", __func__, mc->ctl));
+	}
+#else
 	if (mc->class < UAC_NCLASSES) {
 		DPRINTF(("%s: adding %s.%s\n",
 			 __func__, uac_names[mc->class], mc->ctlname));
@@ -947,9 +962,7 @@ uaudio_add_mixer(struct uaudio_softc *sc
 
 	bm = d1->bmControls;
 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
-#if !defined(__FreeBSD__)
 	uaudio_determine_class(&iot[id], &mix);
-#endif
 	mix.type = MIX_SIGNED_16;
 #if !defined(__FreeBSD__)	/* XXXXX */
 	mix.ctlunit = AudioNvolume;
@@ -1107,7 +1120,6 @@ uaudio_get_terminal_name(int terminal_ty
 }
 #endif
 
-#if !defined(__FreeBSD__)
 Static int
 uaudio_determine_class(const struct io_terminal *iot, struct mixerctl *mix)
 {
@@ -1158,6 +1170,108 @@ uaudio_determine_class(const struct io_t
 	return terminal_type;
 }
 
+#if defined(__FreeBSD__)
+const int 
+uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
+{
+	int terminal_type;
+
+	terminal_type = uaudio_determine_class(iot, mix);
+	if (mix->class == UAC_RECORD && terminal_type == 0)
+		return SOUND_MIXER_IMIX;
+	DPRINTF(("%s: terminal_type=%s\n", __func__,
+		 uaudio_get_terminal_name(terminal_type)));
+	switch (terminal_type) {
+	case UAT_STREAM:
+		return SOUND_MIXER_PCM;
+
+	case UATI_MICROPHONE:
+	case UATI_DESKMICROPHONE:
+	case UATI_PERSONALMICROPHONE:
+	case UATI_OMNIMICROPHONE:
+	case UATI_MICROPHONEARRAY:
+	case UATI_PROCMICROPHONEARR:
+		return SOUND_MIXER_MIC;
+
+	case UATO_SPEAKER:
+	case UATO_DESKTOPSPEAKER:
+	case UATO_ROOMSPEAKER:
+	case UATO_COMMSPEAKER:
+		return SOUND_MIXER_SPEAKER;
+
+	case UATE_ANALOGCONN:
+	case UATE_LINECONN:
+	case UATE_LEGACYCONN:
+		return SOUND_MIXER_LINE;
+
+	case UATE_DIGITALAUIFC:
+	case UATE_SPDIF:
+	case UATE_1394DA:
+	case UATE_1394DV:
+		return SOUND_MIXER_ALTPCM;
+
+	case UATF_CDPLAYER:
+		return SOUND_MIXER_CD;
+
+	case UATF_SYNTHESIZER:
+		return SOUND_MIXER_SYNTH;
+
+	case UATF_VIDEODISCAUDIO:
+	case UATF_DVDAUDIO:
+	case UATF_TVTUNERAUDIO:
+		return SOUND_MIXER_VIDEO;
+
+/* telephony terminal types */
+	case UATT_UNDEFINED:
+	case UATT_PHONELINE:
+	case UATT_TELEPHONE:
+	case UATT_DOWNLINEPHONE:
+		return SOUND_MIXER_PHONEIN;
+/*		return SOUND_MIXER_PHONEOUT;*/
+
+	case UATF_RADIORECV:
+	case UATF_RADIOXMIT:
+		return SOUND_MIXER_RADIO;
+
+	case UAT_UNDEFINED:
+	case UAT_VENDOR:
+	case UATI_UNDEFINED:
+/* output terminal types */
+	case UATO_UNDEFINED:
+	case UATO_DISPLAYAUDIO:
+	case UATO_SUBWOOFER:
+	case UATO_HEADPHONES:
+/* bidir terminal types */
+	case UATB_UNDEFINED:
+	case UATB_HANDSET:
+	case UATB_HEADSET:
+	case UATB_SPEAKERPHONE:
+	case UATB_SPEAKERPHONEESUP:
+	case UATB_SPEAKERPHONEECANC:
+/* external terminal types */
+	case UATE_UNDEFINED:
+/* embedded function terminal types */
+	case UATF_UNDEFINED:
+	case UATF_CALIBNOISE:
+	case UATF_EQUNOISE:
+	case UATF_DAT:
+	case UATF_DCC:
+	case UATF_MINIDISK:
+	case UATF_ANALOGTAPE:
+	case UATF_PHONOGRAPH:
+	case UATF_VCRAUDIO:
+	case UATF_SATELLITE:
+	case UATF_CABLETUNER:
+	case UATF_DSS:
+	case UATF_MULTITRACK:
+	case 0xffff:
+	default:
+		DPRINTF(("%s: 'master' for 0x%.4x\n", __func__, terminal_type));
+		return SOUND_MIXER_VOLUME;
+	}
+	return SOUND_MIXER_VOLUME;
+}
+#else
 Static const char *
 uaudio_feature_name(const struct io_terminal *iot, struct mixerctl *mix)
 {
@@ -1271,7 +1385,9 @@ uaudio_add_feature(struct uaudio_softc *
 	u_int fumask, mmask, cmask;
 	struct mixerctl mix;
 	int chan, ctl, i, unit;
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+	int mixernumber;
+#else
 	const char *mixername;
 #endif
 
@@ -1316,7 +1432,9 @@ uaudio_add_feature(struct uaudio_softc *
 		}
 #undef GET
 
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+		mixernumber = uaudio_feature_name(&iot[id], &mix);
+#else
 		mixername = uaudio_feature_name(&iot[id], &mix);
 #endif
 		switch (ctl) {
@@ -1333,8 +1451,7 @@ uaudio_add_feature(struct uaudio_softc *
 		case VOLUME_CONTROL:
 			mix.type = MIX_SIGNED_16;
 #if defined(__FreeBSD__)
-			/* mix.ctl = SOUND_MIXER_VOLUME; */
-			mix.ctl = SOUND_MIXER_PCM;
+			mix.ctl = mixernumber;
 #else
 			mix.ctlunit = AudioNvolume;
 			strlcpy(mix.ctlname, mixername, sizeof(mix.ctlname));
@@ -1442,9 +1559,7 @@ uaudio_add_processing_updown(struct uaud
 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 	mix.nchan = 1;
 	mix.wValue[0] = MAKE(UD_MODE_SELECT_CONTROL, 0);
-#if !defined(__FreeBSD__)
 	uaudio_determine_class(&iot[id], &mix);
-#endif
 	mix.type = MIX_ON_OFF;	/* XXX */
 #if !defined(__FreeBSD__)
 	mix.ctlunit = "";
@@ -1475,9 +1590,7 @@ uaudio_add_processing(struct uaudio_soft
 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 		mix.nchan = 1;
 		mix.wValue[0] = MAKE(XX_ENABLE_CONTROL, 0);
-#if !defined(__FreeBSD__)
 		uaudio_determine_class(&iot[id], &mix);
-#endif
 		mix.type = MIX_ON_OFF;
 #if !defined(__FreeBSD__)
 		mix.ctlunit = "";
@@ -1523,9 +1636,7 @@ uaudio_add_extension(struct uaudio_softc
 		mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 		mix.nchan = 1;
 		mix.wValue[0] = MAKE(UA_EXT_ENABLE, 0);
-#if !defined(__FreeBSD__)
 		uaudio_determine_class(&iot[id], &mix);
-#endif
 		mix.type = MIX_ON_OFF;
 #if !defined(__FreeBSD__)
 		mix.ctlunit = "";
--- F_m.diff ends here ---


/tmp/pbad.1LK6m3M8
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list