mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-19 23:03:55 +00:00
Allow selection of a recording source on USB audio devices.
PR: 75316 Submitted by: Kazuhito HONDA <kazuhito at ph dot noda dot tus dot ac dot jp> Obtained from: NetBSD plus changes MFC after: 2 weeks
This commit is contained in:
parent
65046f8612
commit
587161d920
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=139289
|
@ -143,6 +143,8 @@ struct mixerctl {
|
||||||
u_int mul;
|
u_int mul;
|
||||||
#if defined(__FreeBSD__) /* XXXXX */
|
#if defined(__FreeBSD__) /* XXXXX */
|
||||||
unsigned ctl;
|
unsigned ctl;
|
||||||
|
#define MAX_SELECTOR_INPUT_PIN 256
|
||||||
|
u_int8_t slctrtype[MAX_SELECTOR_INPUT_PIN];
|
||||||
#endif
|
#endif
|
||||||
u_int8_t class;
|
u_int8_t class;
|
||||||
#if !defined(__FreeBSD__)
|
#if !defined(__FreeBSD__)
|
||||||
|
@ -1009,24 +1011,34 @@ uaudio_add_mixer(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
|
||||||
Static void
|
Static void
|
||||||
uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int id)
|
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;
|
const struct usb_audio_selector_unit *d = iot[id].d.su;
|
||||||
#endif
|
|
||||||
#if !defined(__FreeBSD__)
|
|
||||||
struct mixerctl mix;
|
struct mixerctl mix;
|
||||||
|
#if !defined(__FreeBSD__)
|
||||||
int i, wp;
|
int i, wp;
|
||||||
|
#else
|
||||||
|
int i;
|
||||||
|
struct mixerctl dummy;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
|
DPRINTFN(2,("uaudio_add_selector: bUnitId=%d bNrInPins=%d\n",
|
||||||
d->bUnitId, d->bNrInPins));
|
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.wIndex = MAKE(d->bUnitId, sc->sc_ac_iface);
|
||||||
mix.wValue[0] = MAKE(0, 0);
|
mix.wValue[0] = MAKE(0, 0);
|
||||||
uaudio_determine_class(&iot[id], &mix);
|
uaudio_determine_class(&iot[id], &mix);
|
||||||
mix.nchan = 1;
|
mix.nchan = 1;
|
||||||
mix.type = MIX_SELECTOR;
|
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.ctlunit = "";
|
||||||
mix.minval = 1;
|
mix.minval = 1;
|
||||||
mix.maxval = d->bNrInPins;
|
mix.maxval = d->bNrInPins;
|
||||||
|
@ -1038,8 +1050,8 @@ uaudio_add_selector(struct uaudio_softc *sc, const struct io_terminal *iot, int
|
||||||
if (wp > MAX_AUDIO_DEV_LEN - 1)
|
if (wp > MAX_AUDIO_DEV_LEN - 1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uaudio_mixer_add_ctl(sc, &mix);
|
|
||||||
#endif
|
#endif
|
||||||
|
uaudio_mixer_add_ctl(sc, &mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USB_DEBUG
|
#ifdef USB_DEBUG
|
||||||
|
@ -4071,6 +4083,39 @@ uaudio_query_mix_info(device_t dev)
|
||||||
return mask;
|
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
|
void
|
||||||
uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
|
uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
|
||||||
{
|
{
|
||||||
|
@ -4093,6 +4138,39 @@ uaudio_mixer_set(device_t dev, unsigned type, unsigned left, unsigned right)
|
||||||
return;
|
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
|
Static int
|
||||||
audio_attach_mi(device_t dev)
|
audio_attach_mi(device_t dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,5 +46,7 @@ void uaudio_chan_set_param_format(device_t dev, u_int32_t format,int dir);
|
||||||
int uaudio_chan_getptr(device_t dev, int);
|
int uaudio_chan_getptr(device_t dev, int);
|
||||||
void uaudio_mixer_set(device_t dev, unsigned type, unsigned left,
|
void uaudio_mixer_set(device_t dev, unsigned type, unsigned left,
|
||||||
unsigned right);
|
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_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);
|
void uaudio_query_formats(device_t dev, u_int32_t *pfmt, u_int32_t *rfmt);
|
||||||
|
|
|
@ -236,6 +236,9 @@ ua_mixer_init(struct snd_mixer *m)
|
||||||
mask = uaudio_query_mix_info(pa_dev);
|
mask = uaudio_query_mix_info(pa_dev);
|
||||||
mix_setdevs(m, mask);
|
mix_setdevs(m, mask);
|
||||||
|
|
||||||
|
mask = uaudio_query_recsrc_info(pa_dev);
|
||||||
|
mix_setrecdevs(m, mask);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +257,11 @@ ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
|
||||||
static int
|
static int
|
||||||
ua_mixer_setrecsrc(struct snd_mixer *m, u_int32_t src)
|
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[] = {
|
static kobj_method_t ua_mixer_methods[] = {
|
||||||
|
|
Loading…
Reference in a new issue