Date: Tue, 21 Dec 2004 01:30:38 +0900 (JST) From: Kazuhito HONDA <kazuhito@ph.noda.tus.ac.jp> To: FreeBSD-gnats-submit@FreeBSD.org Cc: kazuhito@ph.noda.tus.ac.jp Subject: kern/75316: Enable to select a recording sound source Message-ID: <20041221.013038.730549347.kazuhito@ph.noda.tus.ac.jp> Resent-Message-ID: <200412201640.iBKGeCSV096876@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041221.013038.730549347.kazuhito>