NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/56308: AUDIO_SETINFO can't set play.gain and play.balance together
>Number: 56308
>Category: kern
>Synopsis: AUDIO_SETINFO can't set play.gain and play.balance together
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jul 13 19:30:00 +0000 2021
>Originator: Mouse
>Release: NetBSD 9.1
>Organization:
Dis-
>Environment:
System: NetBSD Aaeon-9.Rodents-Montreal.ORG 9.1 NetBSD 9.1 (GEN91) #0: Fri Aug 13 14:35:31 EDT 2021 mouse%Aaeon-9.Rodents-Montreal.ORG@localhost:/home/mouse/kbuild/GEN91 amd64
Architecture: x86_64
Machine: amd64
>Description:
When using ioctl(...,AUDIO_SETINFO,...) with both play.gain and
play.balance specified, the former is ignored.
This is beacuse audio_hw_setinfo fails to update pgain if
newpi->gain is specified:
static int
audio_hw_setinfo(struct audio_softc *sc, const struct audio_info *newai,
struct audio_info *oldai)
{
u_int pgain;
...
/* Backup play.{gain,balance} */
if (SPECIFIED(newpi->gain) || SPECIFIED_CH(newpi->balance)) {
au_get_gain(sc, &sc->sc_outports, &pgain, &pbalance);
if (oldai) {
oldpi->gain = pgain;
oldpi->balance = pbalance;
}
}
/* Backup record.{gain,balance} */
if (SPECIFIED(newri->gain) || SPECIFIED_CH(newri->balance)) {
...
}
if (SPECIFIED(newpi->gain)) {
error = au_set_gain(sc, &sc->sc_outports,
newpi->gain, pbalance);
if (error) {
...
}
}
if (SPECIFIED(newri->gain)) {
...
}
if (SPECIFIED_CH(newpi->balance)) {
error = au_set_gain(sc, &sc->sc_outports,
pgain, newpi->balance);
I find that calling AUDIO_SETINFO twice, once with balance but
not gain specified and once with gain but not balance
specified, works as a workaround (which is why I set priority
to low).
>How-To-Repeat:
Try it. In my case, this looked like
AUDIO_INITINFO(&ai);
ai.play.sample_rate = 8000;
ai.play.channels = 1;
ai.play.precision = 16;
ai.play.encoding = AUDIO_ENCODING_ULINEAR_LE;
ai.play.gain = 254;
ai.play.port = oai.play.avail_ports;
ai.play.pause = 0;
ai.play.balance = AUDIO_MID_BALANCE;
ai.monitor_gain = 254;
ai.mode = AUMODE_PLAY | AUMODE_PLAY_ALL;
if (ioctl(fd,AUDIO_SETINFO,&ai) < 0)
{ fprintf(stderr,"AUDIO_SETINFO: %s\n",strerror(errno));
exit(1);
}
with the volume formerly set to something other than 254.
Verify, by listening to the audio or by checking with
audioctl(1), that the volume is not actually changed.
>Fix:
Presumably, the "if (SPECIFIED(newpi->gain))" block needs to
set pgain to something. I have not tried this; I have a
workaround and I'd rather leave figuring out the correct thing
to set pgain to to someone who knows this code. (My guess
would be
pgain = newpi->gain
but that is just a guess; I'm not as sure as I'd like that
pgain and newpi->gain use compatible scales.)
I suspect recording needs a similar fix, but I have not tried
that; my use case doesn't record.
/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mouse%rodents-montreal.org@localhost
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Home |
Main Index |
Thread Index |
Old Index