kern/75316: Enable to select a recording sound source
Kazuhito HONDA
kazuhito at ph.noda.tus.ac.jp
Mon Dec 20 08:40:13 PST 2004
>Number: 75316
>Category: kern
>Synopsis: Enable to select a recording sound source
>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: Mon Dec 20 16:40:12 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 #203: Tue Dec 21 01:04:58 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:
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 at 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 at 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:
>Unformatted:
More information about the freebsd-bugs
mailing list