GNOME Bugzilla – Bug 144489
acme doesn't use ALSA playback switch properly
Last modified: 2004-12-22 21:47:04 UTC
The ALSA component of acme doesn't use the playback switch feature of ALSA in a decent manner. The problem is twofold: 1. It only mutes the left channel. Some cards might mute everything whenever one channel is muted, but not all cards. This should be handled. 2. The volume is set to zero even on cards that support the playback switch. This causes all kinds of weird problems when different programs try to emulate a mute function by setting the volume to zero. Since ALSA has a playback switch the volume change should *only* be used for cards that for some reason doesn't support the playback switch.
Created attachment 28778 [details] [review] Patch 1 Patch attached with a fix to the above. The fix is however rather crude in that it assumes that the card has two channels (a assumption already made in other places in the code). A somewhat better solution is in bug 139647 which in some way addresses point 1 of this bug. A merge might be in order.
Created attachment 28814 [details] [review] several fixes New patch that tries to merge the ideas from the similar bug mentioned above. Since the documentation for ALSA's mixer interface is non-existant I've assembled this code by looking at some of the tools that are included with ALSA and some trial-and-error. The patching is fairly extensive so I'll explain it bit by bit. 1. Init. of the mixer is done in a seperate routine. This was done in two places previously. But since there doesn't seem to be support for using the PCM mixer anymore this could probably be solved differently. 2. The mixer wasn't updated when the mixer was changed by another program. By looking at alsa-mixer i figured out that a call to snd_mixer_handle_events() was needed. This has been added and tested successfully =) 3. Since we only have one volume there is little point in trying to do some special handling of multiple channels. Functions that can change all channels at the same time are used where possible. Where they can't I've used the mono channel (the same as first left). This is the first channel so it should be present on all cards. No documentation means I can't confirm this. Cards without a left channel should be rare though. The previous solution was doing an average of the left and right channel. But since get_volume is only called right before a set_volume, where we change both channels to the same value, there shouldn't be a problem ignoring the right channel. 4. A joined playback switch is a special case of playback switch (this can be determined by looking in amixer's source). The logic is changed a bit accordingly. Also there is a combined switch which doesn't imply a playback switch (again from amixer) so it is now tested for. I've tested the stuff on my machine and haven't found any problem. If we can just get the mixer applet fixed then gnome and ALSA is a pleasant experience =)
2004-07-15 Bastien Nocera <hadess@hadess.net> * actions/acme-volume-alsa.c: (acme_volume_alsa_finalize), (acme_volume_alsa_set_mute), (acme_volume_alsa_get_mute), (acme_volume_alsa_get_volume), (acme_volume_alsa_set_volume), (acme_volume_alsa_close_real), (acme_volume_alsa_open), (acme_volume_alsa_close), (acme_volume_alsa_init): rework the ALSA mixer so that: - the ALSA device isn't kept open at all times, only for 4 seconds after the last use (Closes: #141793) - the hardware mute is used if it is available (Closes: #141404, #144489, #140937) - lowering the volume doesn't move the balance to the right - it doesn't leak alsa-lib mixers all around
Seems the fix wasn't really complete. I kept on running my own patch until now so I didn't notice it. The problem is here: /* If we have a hardware mute */ if (self->_priv->has_mute) { snd_mixer_selem_set_playback_volume_all (self->_priv->elem, !val); acme_volume_alsa_close (self); return; } snd_mixer_selem_set_playback_volume_all() is called instead of snd_mixer_selem_set_playback_switch_all(). I've changed it here and confirmed that it solves the problem.
Good catch Pierre, fixed in gnome-2-8 and HEAD. 2004-12-16 Bastien Nocera <hadess@hadess.net> * actions/acme-volume-alsa.c: (acme_volume_alsa_set_mute): mute properly when the system has hardware mute, patch from Pierre Ossman <drzeus-bugzilla@drzeus.cx> (Closes: #144489)
Bug 156206 is a duplicate of this bug.
Bug 156206 also has a patch for using the External Amplifier switch.