From kazuhito@ph.noda.tus.ac.jp  Mon Dec 20 16:30:45 2004
Return-Path: <kazuhito@ph.noda.tus.ac.jp>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 5FD3116A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 20 Dec 2004 16:30:45 +0000 (GMT)
Received: from t-mta1.odn.ne.jp (mfep1.odn.ne.jp [143.90.131.179])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 0ED2F43D5C
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 20 Dec 2004 16:30:44 +0000 (GMT)
	(envelope-from kazuhito@ph.noda.tus.ac.jp)
Received: from localhost ([219.66.84.86]) by t-mta1.odn.ne.jp with ESMTP
          id <20041220163043511.LNX.199623.t-mta1.odn.ne.jp@mta1.odn.ne.jp>;
          Tue, 21 Dec 2004 01:30:43 +0900
Message-Id: <20041221.013038.730549347.kazuhito@ph.noda.tus.ac.jp>
Date: Tue, 21 Dec 2004 01:30:38 +0900 (JST)
From: Kazuhito HONDA <kazuhito@ph.noda.tus.ac.jp>
Reply-To: Kazuhito HONDA <kazuhito@ph.noda.tus.ac.jp>
To: FreeBSD-gnats-submit@freebsd.org
Cc: kazuhito@ph.noda.tus.ac.jp
Subject: Enable to select a recording sound source
X-Send-Pr-Version: 3.113

>Number:         75316
>Category:       kern
>Synopsis:       [sound] [patch] Enable to select a recording sound source
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-multimedia
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 20 16:40:12 GMT 2004
>Closed-Date:    Wed Dec 28 19:55:33 GMT 2005
>Last-Modified:  Wed Dec 28 19:55:33 GMT 2005
>Originator:     Kazuhito HONDA
>Release:        FreeBSD 6.0-CURRENT i386
>Organization:
>Environment:
System: FreeBSD kaoru 6.0-CURRENT FreeBSD 6.0-CURRENT #203: Tue Dec 21 01:04:58 JST 2004 root@kaoru:/usr/obj/src/sys/i386/compile/KAORU.6.0B.0 i386

USB audio device: Sound Blaster Digital Music (SBDM, Creative Labs.)

>Description:
Some USB audio devices have sound source selectors.
The most important one of them is the selector 
for changing a recording sound source.
But it couldn't be controlled on FreeBSD.

>How-To-Repeat:
Using a USB audio device which has a recording source selector.

>Fix:
1. At first, the patch in `kern/75274' must be applied
2. The patch in `kern/75276' must be applied
3. This PR has no value without applying the patch 
    in `kern/75311' for recording
4. The patch blow must be applied.


--- F_mrs.diff begins here ---
--- src/sys/dev/sound/usb/uaudio.c	Tue Dec 21 00:55:32 2004
+++ src/sys/dev/sound/usb/uaudio-91-mrs.c	Tue Dec 21 00:57:33 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-mr.c,v $: */
+/*	$FreeBSD: src/sys/dev/sound/usb/uaudio-91-mrs.c,v $: */
 
 /*
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -144,6 +144,8 @@ struct mixerctl {
 	u_int		mul;
 #if defined(__FreeBSD__) /* XXXXX */
 	unsigned	ctl;
+#define MAX_SELECTOR_INPUT_PIN 256
+	u_int8_t	slctrtype[MAX_SELECTOR_INPUT_PIN];
 #endif
 	u_int8_t	class;
 #if !defined(__FreeBSD__)
@@ -1010,24 +1012,34 @@ uaudio_add_mixer(struct uaudio_softc *sc
 Static void
 uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
 {
-#if !defined(__FreeBSD__) || defined(USB_DEBUG)
 	const struct usb_audio_selector_unit *d = iot[id].d.su;
-#endif
-#if !defined(__FreeBSD__)
 	struct mixerctl mix;
+#if !defined(__FreeBSD__)
 	int i, wp;
+#else
+	int i;
+	struct mixerctl dummy;
 #endif
 
 	DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
 		    d->bUnitId, d->bNrInPins));
-#if defined(__FreeBSD__)
-	printf("uaudio_add_selector: NOT IMPLEMENTED\n");
-#else
 	mix.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
 	mix.wValue[0] = MAKE(0, 0);
 	uaudio_determine_class(&iot[id], &mix);
 	mix.nchan = 1;
 	mix.type = MIX_SELECTOR;
+#if defined(__FreeBSD__)
+	mix.ctl = SOUND_MIXER_NRDEVICES;	/* XXXXX */
+	mix.minval = 1;
+	mix.maxval = d->bNrInPins;
+	mix.mul = mix.maxval - mix.minval;
+	for (i = 0; i < MAX_SELECTOR_INPUT_PIN; i++) {
+		mix.slctrtype[i] = SOUND_MIXER_NRDEVICES;
+	}
+	for (i = mix.minval; i <= mix.maxval; i++) {
+		mix.slctrtype[i - 1] = uaudio_feature_name(&iot[d->baSourceId[i - 1]], &dummy);
+	}
+#else
 	mix.ctlunit = "";
 	mix.minval = 1;
 	mix.maxval = d->bNrInPins;
@@ -1039,8 +1051,8 @@ uaudio_add_selector(struct uaudio_softc 
 		if (wp > MAX_AUDIO_DEV_LEN - 1)
 			break;
 	}
-	uaudio_mixer_add_ctl(sc, &mix);
 #endif
+	uaudio_mixer_add_ctl(sc, &mix);
 }
 
 #ifdef USB_DEBUG
@@ -4072,6 +4084,39 @@ uaudio_query_mix_info(device_t dev)
 	return mask;
 }
 
+u_int32_t
+uaudio_query_recsrc_info(device_t dev)
+{
+	int i, rec_selector_id;
+	u_int32_t mask = 0;
+	struct uaudio_softc *sc;
+	struct mixerctl *mc;
+
+	sc = device_get_softc(dev);
+	rec_selector_id = -1;
+	for (i=0; i < sc->sc_nctls; i++) {
+		mc = &sc->sc_ctls[i];
+		if (mc->ctl == SOUND_MIXER_NRDEVICES && 
+		    mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
+			if (rec_selector_id == -1) {
+				rec_selector_id = i;
+			} else {
+				printf("There are many selectors.  Can't recognize which selector is a record source selector.\n");
+				return mask;
+			}
+		}
+	}
+	if (rec_selector_id == -1)
+		return mask;
+	mc = &sc->sc_ctls[rec_selector_id];
+	for (i = mc->minval; i <= mc->maxval; i++) {
+		if (mc->slctrtype[i - 1] == SOUND_MIXER_NRDEVICES)
+			continue;
+		mask |= 1 << mc->slctrtype[i - 1];
+	}
+	return mask;
+}
+
 void
 uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
 {
@@ -4092,6 +4137,39 @@ uaudio_mixer_set(device_t dev, unsigned 
 		}
 	}
 	return;
+}
+
+u_int32_t
+uaudio_mixer_setrecsrc(device_t dev, u_int32_t src)
+{
+	int i, rec_selector_id;
+	struct uaudio_softc *sc;
+	struct mixerctl *mc;
+
+	sc = device_get_softc(dev);
+	rec_selector_id = -1;
+	for (i=0; i < sc->sc_nctls; i++) {
+		mc = &sc->sc_ctls[i];
+		if (mc->ctl == SOUND_MIXER_NRDEVICES && 
+		    mc->type == MIX_SELECTOR && mc->class == UAC_RECORD) {
+			if (rec_selector_id == -1) {
+				rec_selector_id = i;
+			} else {
+				return src; /* Can't recognize which selector is record source selector */
+			}
+		}
+	}
+	if (rec_selector_id == -1)
+		return src;
+	mc = &sc->sc_ctls[rec_selector_id];
+	for (i = mc->minval; i <= mc->maxval; i++) {
+		if (src != (1 << mc->slctrtype[i - 1]))
+			continue;
+		uaudio_ctl_set(sc, SET_CUR, mc, 0, i);
+		return (1 << mc->slctrtype[i - 1]);
+	}
+	uaudio_ctl_set(sc, SET_CUR, mc, 0, mc->minval);
+	return (1 << mc->slctrtype[mc->minval - 1]);
 }
 
 Static int
--- src/sys/dev/sound/usb/uaudio.h	Tue Dec 21 00:55:37 2004
+++ src/sys/dev/sound/usb/uaudio-91-mrs.h	Tue Dec 21 00:57:45 2004
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/sound/usb/uaudio-91-mr.h,v $ */
+/* $FreeBSD: src/sys/dev/sound/usb/uaudio-91-mrs.h,v $ */
 
 /*
  * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.org>
@@ -46,5 +46,7 @@ void	uaudio_chan_set_param_format(device
 int	uaudio_chan_getptr(device_t dev, int);
 void	uaudio_mixer_set(device_t dev, unsigned type, unsigned left,
 		unsigned right);
+u_int32_t uaudio_mixer_setrecsrc(device_t dev, u_int32_t src);
 u_int32_t uaudio_query_mix_info(device_t dev);
+u_int32_t uaudio_query_recsrc_info(device_t dev);
 void	uaudio_query_formats(device_t dev, u_int32_t *pfmt, u_int32_t *rfmt);
--- src/sys/dev/sound/usb/uaudio_pcm.c	Tue Dec 21 00:55:56 2004
+++ src/sys/dev/sound/usb/uaudio_pcm-91-mrs.c	Tue Dec 21 01:03:07 2004
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/dev/sound/usb/uaudio_pcm-91-mr.c,v $ */
+/* $FreeBSD: src/sys/dev/sound/usb/uaudio_pcm-91-mrs.c,v $ */
 
 /*
  * Copyright (c) 2000-2002 Hiroyuki Aizu <aizu@navi.org>
@@ -236,6 +236,9 @@ ua_mixer_init(struct snd_mixer *m)
 	mask = uaudio_query_mix_info(pa_dev);
 	mix_setdevs(m,	mask);
 
+	mask = uaudio_query_recsrc_info(pa_dev);
+	mix_setrecdevs(m, mask);
+
 	return 0;
 }
 
@@ -254,7 +257,11 @@ ua_mixer_set(struct snd_mixer *m, unsign
 static int
 ua_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src)
 {
-	return src;
+	device_t pa_dev;
+	struct ua_info *ua = mix_getdevinfo(m);
+
+	pa_dev = device_get_parent(ua->sc_dev);
+	return uaudio_mixer_setrecsrc(pa_dev, src);
 }
 
 static kobj_method_t ua_mixer_methods[] = {
--- F_mrs.diff ends here ---


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->sound 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun Apr 3 08:55:15 GMT 2005 
Responsible-Changed-Why:  
Reassign to appropriate mailing list. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=75316 

From: Kazuhito HONDA <kazuhito@ph.noda.tus.ac.jp>
To: freebsd-gnats-submit@FreeBSD.org
Cc: kazuhito@ph.noda.tus.ac.jp
Subject: Re: kern/75316: Enable to select a recording sound source
Date: Sat, 16 Apr 2005 01:29:02 +0900 (JST)

 This PR has been MFCed. So please close this PR.
State-Changed-From-To: open->closed 
State-Changed-By: netchild 
State-Changed-When: Wed Dec 28 19:55:18 UTC 2005 
State-Changed-Why:  
Close as requested by originator. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=75316 
>Unformatted:
