GNOME Bugzilla – Bug 336075
ALSA emu10k1 mixer tracks are wrongly classified as playback tracks
Last modified: 2006-09-01 10:50:33 UTC
I have a Creative Audigy 1 Live!. Since GNOME 2.10 (or so) gnome-volume-control aka gst-mixer classifies all capture mixer tracks as playback tracks. As a result there are two PCM channels, two Microphone channels, and so on in the playback panel. This confuses the volume-control-applet, because I cannot select the right PCM track of the two. If I select PCM it only controls the capture (because it was added first to the track list?) but not the playback track. So I decided to have a closer look at the gstreamer alsa plugin. I have written a little utility, which outputs the results of the used alsa functions in gstalsamixer.c: Here the output of the one problematic tracks: 6: PCM has_common_volume=0 has_capture_switch=0 has_playback_switch=0 has_capture_volume=1 has_playback_volume=1 In gstalsamixer.c:gst_alsa_mixer_ensure_track_list is a loop which adds all alsa mixer tracks. In this loop the gst flags are initialized to: gint flags = GST_MIXER_TRACK_OUTPUT; Then there is an if-statement which uses snd_mixer_selem_has_capture_switch to classify between playback and capture (I guess this is the meaning) and sets flags to GST_MIXER_TRACK_INPUT, if snd_mixer_selem_has_capture_switch is true. But as you can see in the output above ALSA reports has_capture_switch==false for the PCM channel. The gst flags are never changed to GST_MIXER_TRACK_INPUT at this point, thou this track can control both capture and playback volume. At later point an if-statement uses snd_mixer_selem_has_capture_volume to decide if the track should be added to the capture list. Since this is true for the PCM channel a new gst mixer track is created: track = gst_alsa_mixer_track_new (element, samename, i, channels, flags, GST_ALSA_MIXER_TRACK_CAPTURE); Here is the discrepancy: (gst) 'flags' is still GST_MIXER_TRACK_OUTPUT. ('alsa flags' are set correctly to capture.) Later a playback mixer track is added the same way. Therefore "duplicate" mixer tracks are displayed in gst-mixer playback panel.
Looking closer at the source of gstalsamixer.c it seems, gst-alsa depends on the alsa device having a capture switch. Just compare gstalsamixer.c:gst_alsa_mixer_set_mute and gstalsamixer.c:gst_alsa_mixer_set_record. gst_alsa_mixer_set_mute nicely depends on snd_mixer_selem_has_playback_switch and acts accordingly. gst_alsa_mixer_set_record always uses snd_mixer_selem_set_capture_switch_all. Even if the alsa device does not have a capture switch.
Another bug in gstalsamixer.c: If an alsa track has both, capture and playback volume, channels for this track may be counted wrong: gstalsamixer.c:139: 'channels' initialized to 0 gint channels = 0; gstalsamixer.c:166: 'channels' used for counting capture channels if (snd_mixer_selem_has_capture_volume (element)) { while (snd_mixer_selem_has_capture_channel (element, channels)) channels++; [...] } gstalsamixer.c:179: 'channels' used for counting playback channels without being reset to 0!!!! if (snd_mixer_selem_has_playback_volume (element)) { while (snd_mixer_selem_has_playback_channel (element, channels)) channels++; [...] }
Is there any chance that you could come up with a patch for these issues? I am trying to fix the gst-mixer end of the problem (see bug #313495). I'm also looking at the gstalsa code and the libasound2 code, and am scratching my head over how ALSA's exclusive capture switch and capture groups should be implemented. :(
Created attachment 64874 [details] [review] First try I have made this patch some time ago. It correctly models the problematic duplicate ALSA mixer tracks as two seperate playback and capture tracks. An "Capture" is appended to the labels of such capture tracks, so GNOME mixer_applet can differentiate between playback and capture. I known this should be corrected in mixer_applet and not in gstreamer, but I was just lazy... ;)
Great! I've tried the patch and it solves some prolems, however there are a couple of odd things now occuring. I wrote a program to list all the mixer elements and channels that gstreamer presents; here is the output from before and after the patch: label: Line-in | label: Line-in channels: 2 | channels: 2 range 0-31 | range 0-31 flags: input mute | flags: output mute gstreamer is not creating the corresponding 'Line-in Capture' channel. amixer describes the control as: Simple mixer control 'Line',0 Capabilities: pvolume pswitch pswitch-joined cswitch cswitch-exclusive Capture exclusive group: 0 Playback channels: Front Left - Front Right Capture channels: Front Left - Front Right Limits: Playback 0 - 31 Front Left: Playback 0 [0%] [off] Capture [off] Front Right: Playback 0 [0%] [off] Capture [off] The same happens for other channels with that set of capabilities: CD, Mic, Video, Phone and Aux.
Hmm, in my opinion it's correctly classified as playback track, because pvolume controls how loud you can hear the line-in input through the speakers. You cannot control how load it will be recorded (no cvolume). It is always recorded with full loudness. But you can turn off the recording completely (cswitch). Currently this situation is not covered by the patch. There should be an gst capture track but without a volume control, so you can switch recording. I will try to fix it soon. I think we should look at alsamixer. I'm almost certain the 'Line' volume slider is on the playback pane, isn't it?
My bad, your are quite correct. I didn't notice that the Line ALSA control lacks the cvolume capability. I'm not sure that adding a volume control without a capture switch is a complete solution, though. The Line control has cswitch-exclusive--this means that activating capture for the Line control deactivates it for all other controls in the same capture group. GstMixerTrack assumes that the record flag is just a simple toggle, so the mixer state gets really screwed up when using gnome-volume-control. Another confusion caused by the difference between the ALSA Control model and the GstMixer model is the effect of muting an input track. A GstMixer track can have both Mute and Record toggled on/off; however in ALSA's model, a control only has a capture toggle switch. This mismatch, and the lack of support for capture groups, makes diagnosing the interaction between GstMixer and the actual alsamixer rather tricky. ;)
Created attachment 64953 [details] [review] Second try From gst/interfaces/mixertrack.h: "Input tracks can have 'recording' enabled, which means that any input will be hearable into the speakers that are attached to the output. Mute is obvious." 1) This patch redefines the meaning of mute and recording flags for capture tracks: * mute controls whether the input will be hearable into the speakers (alsa-pswitch) * recording directly corresponds to the alsa-pswitch In my opinion it is "more obvious" and it suits the gnome-volume-control button symbols. 2) Alsa-tracks with playback and capture capabilities are modeled as two seperate gst-tracks; mute is shared between this two (toggling mute for capture track toggles also the mute flag of the playback track and vice versa). 3) Support for alsa exlusive cswitch groups (not tested).
> * recording directly corresponds to the alsa-pswitch Not the alsa-cswitch? The comment in mixertrach.h implies that the record flag of a GstMixerTrack is the same as the playback switch of an ALSA control, however this leaves no way to toggle the actual capture switch of a control. > Support for alsa exlusive cswitch groups (not tested). Doesn't quite work... toggling the record flag on the 'Microphone Capture' track just changes the mute flag on the 'Microphone' track. I think this is because of the above problem?
(In reply to comment #9) > > * recording directly corresponds to the alsa-pswitch > > Not the alsa-cswitch? Oops, just a typo. I meant alsa-cswitch. > > Support for alsa exlusive cswitch groups (not tested). > > Doesn't quite work... toggling the record flag on the 'Microphone Capture' > track just changes the mute flag on the 'Microphone' track. I think this is > because of the above problem? This should be the right behavior for the mute flag. What happens if you toggle the other button of this two? Hmm, maybe we have different opinions about what should be the record flag. In gnome-volume-control capture tracks have two buttons. Thinking of my old cassette recorder, my interpretation of them looks like this: If I press the record button, it records my silly shouting into the microphone to the tape and also I can hear the input through the speakers. Unless I press mute. In this case, I hear nothing through the speakers, but it still records untainted to the tape. So - litte speaker symbol: *Mute* button from cassette recorder -> gstreamer *mute* flag -> controls alsa-pswitch (or emulates it) - little microphone symbol: With a microphone you can *record*. If I switch it off, I cannot record. -> gstreamer *record* flag -> controls alsa-cswitch (or emulates it) It is the opposite meaning of mute and record flags from the comment in mixertrack.h.
I think I agree with what you are describing, it's just that toggling (what gnome-volume-control presents as) the 'Microphone Capture' switch does not affect the capture switch of ALSA's 'Microphone' control. Instead, it affects the control's playback switch. I will describe what happens in more detail: I now have a series of Switches in gnome-volume-control labelled 'Microphone Capture', 'Phone Capture' and so on. I expected enabling one of them to disable the rest (as their ALSA controls are all in the same capture group). But instead, they toggle on and off individually. From watching the changes to the tracks in the Playback tab, I can see that toggling the 'Microphone Capture' switch also toggles the mute icon underneath the 'Microphone' track in the Playback tab. The same is true for CD, Phone, Line-in and so on. (This association does not hold in reverse; if I mute the 'Microphone' track in the Playback tab then the 'Microphone Capture' switch does not get toggled.) These tracks all have the same capabilities: pvolume pvolume-joined pswitch pswitch-joined cswitch cswitch-exclusive It has just occurred to me that gnome-volume-control is toggling the 'mute' flag of the GstMixerControls. gnome-volume-control needs a way to know whether to toggle a GstMixerTrack's 'mute' or 'record' flags when the user toggles the track's switch. I should mention here that if a GstMixerTrack has no channels then gnome-volume-control presents it as a 'switch' which is basically a checkbox that toggles on/off. Currently the switch only controls a GstMixerTrack's 'mute' flag. Another strange thing is now happening: I now have both 'Bass' and 'Bass Capture' tracks (the 'Bass' ALSA control is described by amixer as having only the 'volume' capability). Toggling the mute flag of either track affects the mute flag of the other as expected; changing the volume of the 'Bass' track only changes the volume of 'Bass Capture' if the tracks are not muted. Changing the volume or record flags of 'Bass Capture' doesn't affect 'Bass' at all. From watching alsamixer, I can see that the 'Bass' track is the one that actually controls ALSA's 'Bass' control.
(In reply to comment #11) > I should mention here that if a GstMixerTrack has no channels then > gnome-volume-control presents it as a 'switch' which is basically a checkbox > that toggles on/off. Currently the switch only controls a GstMixerTrack's > 'mute' flag. Damn it! Any suggestions how to solve this? Adding an dummy volume control? Special treatment of such tracks, so the switch controls the 'record' and not the 'mute' flag? Or perhaps someone writes a native ALSA support for gnome-volume-control... ;) > Another strange thing is now happening: > > I now have both 'Bass' and 'Bass Capture' tracks (the 'Bass' ALSA > control is described by amixer as having only the 'volume' capability). I have noticed this, too. It is an one-line fix. ALSA controls with common volume are presented as playback tracks only now.
(In reply to comment #12) > Special treatment of such tracks, so the switch controls the 'record' and not > the 'mute' flag? I have hacked gnome-volume-control to set the 'record' flag if the track name ends in 'Capture'. This is a bit nasty but I guess it will do until/unless GstMixerTrack is modified to allow an app to find out whether a track has a playback/capture (mute/record) switch. I'll add this stuff to my patch for bug #313495. Speaking from an HIG perspective I think the way that alsamixer (and now gnome-volume-control) present exclusive capture groups is unintuitive. I have a couple of ideas about how to fix this, what do you think about them? 1. Display the exclusive capture switches with a radio button instead of a checkbox. Would require a property on GstMixerTrack that lets the mixer app know that a switch (a track with 0 channels) is a member of a capture group. 2. Select which member of a group is active from a GtkComboBox. Would require the capture group to be presented as a GstMixerOptions track. This is one area where the libasound simple mixer abstraction actually hinders us. If we used the hcontrol(?) API directly this would be simpler: $ amixer contents ... numid=68,iface=MIXER,name='Capture Source' ; type=ENUMERATED,access=rw---,values=2,items=8 ; Item #0 'Mic' ; Item #1 'CD' ; Item #2 'Video' ; Item #3 'Aux' ; Item #4 'Line' ; Item #5 'Mix' ; Item #6 'Mix Mono' ; Item #7 'Phone' : values=0,0 ... > Or perhaps someone writes a native ALSA support for > gnome-volume-control... ;) If only! ;)
(In reply to comment #13) > (In reply to comment #12) > > Special treatment of such tracks, so the switch controls the 'record' and not > > the 'mute' flag? > > I have hacked gnome-volume-control to set the 'record' flag if the track name > ends in 'Capture'. This is a bit nasty but I guess it will do until/unless > GstMixerTrack is modified to allow an app to find out whether a track has a > playback/capture (mute/record) switch. I'll add this stuff to my patch for bug > #313495. I think, I should undo my decision swapping the meaning of gstreamer 'record' and 'mute' for capture tracks. 'GST_MIXER_TRACK_RECORD' is just a confusing appellation. Should be 'GST_MIXER_TRACK_RECORD_AUDIBLE' or something like that. But I'm not the only one, who got confused. The gnome-volume-control author bound the record toggle button with the gstreamer record flag instead with the mute flag... > Speaking from an HIG perspective I think the way that alsamixer (and now > gnome-volume-control) present exclusive capture groups is unintuitive. I have a > couple of ideas about how to fix this, what do you think about them? Uff, Ahhh, HIG! Sorry, but I'm definitly the last person who you should talking about HIG stuff... :)
Created attachment 65038 [details] [review] emu10k1 duplicate channels fix v3 Like the last patch, but the record and mute flags behave exactly as described in mixertrack.h now. (Tho the meaning of the little microphone and speaker buttons for the capture tracks in gnome-volume-control are not obvious now.)
(In reply to comment #14) > I think, I should undo my decision swapping the meaning of gstreamer 'record' > and 'mute' for capture tracks. 'GST_MIXER_TRACK_RECORD' is just a confusing > appellation. Should be 'GST_MIXER_TRACK_RECORD_AUDIBLE' or something like that. > But I'm not the only one, who got confused. The gnome-volume-control author > bound the record toggle button with the gstreamer record flag instead with the > mute flag... Hm. So the mute flag of an output track maps to the pswitch, and the record flag of an input track also maps to the pswitch? How then can I set the cswitch? Hm, also, what happens if I set the mute flag of an input track or the record flag of an output? :) > > Speaking from an HIG perspective I think the way that alsamixer (and now > > gnome-volume-control) present exclusive capture groups is unintuitive. I > > have a couple of ideas about how to fix this, what do you think about them? > > Uff, Ahhh, HIG! Sorry, but I'm definitly the last person who you should talking > about HIG stuff... :) Well, I was hoping for comments on the sanity of the changes that would be necessary to gstalsamixer... I was hoping to trick you into modifying it for me. ;) Once we get gnome-volume-control cooperating with the gstalsamixer I can take a crack at implementing them myself though. :)
Created attachment 65303 [details] [review] emu10k1 duplicate channels fix v4 The first summer heat must have influenced my mind: MUTE flag controls the pwitch and RECORD the cswitch again now. Other changes include better update of Gstreamer flags (MUTE, RECORD), if they are emulated (MUTE == volume 0%) and volume is raised by some other alsa application.
Created attachment 65305 [details] [review] emu10k1 duplicate channels fix v4.1 * Fixed some copy&paste bug: volumes can be changed now again... ;) * Removed some debugging output
While updating my patch with the improvement you suggested I noticed that toggling a control's playback or capture switch in alsamixer doesn't seem to be updating the corresponding GstMixerTrack's MUTE or RECORD flags. This is with v4.1 of your patch; with v2 it was fine. In fact, if the control has a cvolume, enabling the cswitch in alsamixer causes the RECORD flag to be updated... but disabling it does not. If the control has neither pvolume nor cvolume then toggling its pswitch or cswitch doesn't update the MUTE or RECORD flags of the GstMixerTrack.
Created attachment 65377 [details] [review] emu10k1 duplicate channels fix v4.2 The RECORD flag should be updated correctly now. Can you state more precisely the problem with MUTE flag?
Muting/unmuting 'Mic boost', 'Headphone LFE' and so on in alsamixer doesn't update the MUTE flag on the corresponding GstMixerTrack.
Hi, this patch should really be sent to the gstreamer people, I think it has some great additions that we'd love to see in a next GNOME release. About mute&record: both your interpretations are correct, those were the intended meanings. About grouping: placing capture things in the playback tab was a bug, this patch fortunately fixes that. A radiobutton/combobox has the disadvantage that you cannot select 'none'. In addition (more technically), API for deciding whether capture is exclusive or >1 is currently missing in GStreamer, although OSS/ALSA both expose this as a property. A patch for this would be appreciated, but I'd still recommend to leave the checkbox as-is for now. I'll get flamed by the HIG people, but again, there's nothing better right now. Maybe I'll write a new widget: a unselectable radiobox (round, like radiobutton, to indicate exclusiveness, but with a checkbox instead of a circle to indicate unselectability). About mute/0% volume: this is a system bug that we cannot fix. You can do ugly hacks around, but I can always think of situations that will break it and provide a worse user experience. Let's please leave it as is, at least it doesn't break too badly in common use cases. Anything else I should comment on?
What would be the best way to bring this to the attention of the gstreamer guys? I tried IRC and the gstreamer-devel mailing list but didn't get any bites.
Try again and again and again and again until someone finally bites and decides to take the decision to either reject the patch for some reason or apply it. GStreamer people: please take this patch, it is needed, gnome-volume-control is not 100% useful on some soundcards without it Increasing priority because patch is attached and confirming bug.
Created attachment 71537 [details] [review] same as v4.2 above but made to apply against HEAD and gst-indented Updated patch to apply against HEAD (also ran gst-indent over it, cleaned up some c++-style comments, a mid-block variable declaration and an unused variable). Had to merge some stuff manually, so it would be good if people tested it again to make sure I didn't break anything doing that. Question though: with this patch on my cheap on-board sound card (snd_via82xx) the layout in gnome-volume-control looks like this: PLAYBACK: [Master] [Headphone] [PCM] [Line-in] [CD] [Microphone] [PC Speaker] (no capture tab) whereas before it looked like: PLAYBACK: [Master] [Headphone] [PCM] [PC Speaker] CAPTURE : [Line-in] [CD] [Microphone] Is this how it's supposed to be? (or does it require further patches to g-v-c to display correctly again?)
I can't say for certain without having the same hardware as you :) but that isn't necessarily incorrect. If you run 'amixer scontents' you can see what is going on. It appears that your Line-in, CD and Microphone volume sliders actually control the *playback* volume of their respective controls. In amixer terms, the controls have the 'pvolume' capability. The pvolume only affects the volume of the sound that comes out of your speakers (when the control is not muted). It does not affect the volume of the sound as it is captured--that is what the cvolume is for. If your Line-in control has no cvolume capability then it won't show up in the Capture tab of gnome-volume-control. Note also that you should apply my patch to gnome-volume-control; the two patches together resolve the misunderstandings that the gnome-volume-control program and the GstAlsaMixer class have about how to interpret the properties of different ALSA controls.
Created attachment 71571 [details] [review] same as above, but with additional GStreamer debug output statements Thanks for the explanation, makes sense. What startled me was that there was no Capture tab at all while the sound card does have a recording facility. This is fixed with gnome-volume-control from CVS though where there's a tab containing the capture switch now.
Patch committed to -base CVS: 2006-08-29 Tim-Philipp Müller <tim at centricular dot net> Patch by: Viktor Peters <viktor dot peters at gmail dot com> * ext/alsa/gstalsamixer.c: (gst_alsa_mixer_ensure_track_list), (gst_alsa_mixer_update), (gst_alsa_mixer_get_volume), (gst_alsa_mixer_set_volume), (gst_alsa_mixer_set_mute), (gst_alsa_mixer_set_record): * ext/alsa/gstalsamixertrack.c: (gst_alsa_mixer_track_update_alsa_capabilities), (alsa_track_has_cap), (gst_alsa_mixer_track_new), (gst_alsa_mixer_track_update): * ext/alsa/gstalsamixertrack.h: Improve and fix mixer track handling, in particular better handling of alsa's pvolume/pswitch/cvolume/cswitch capabilities; create separate track objects for tracks that have both capture and playback volume (and label them differently as well so they're not mistakenly assumed to be duplicates); classify mixer tracks that only affect the audible volume of something (rather than the capture volume) as playback tracks. Redefine/fix meaning of RECORD and MUTE flags for capture tracks to correspond to alsa-pswitch alsa-cswitch (following the meaning documented in the mixer interface header file); add support for alsa's exclusive cswitch groups; update/sync state/flags better if mixer settings are changed by another application. Fixes #336075. Thanks! Improvements to the GstMixer documentation in gst-plugins-base/gst-libs/gst/interfaces/mixer*.[ch] would also be much appreciated (alternatively, a list of things that should be documented would also be useful) :)
*** Bug 353811 has been marked as a duplicate of this bug. ***