GNOME Bugzilla – Bug 441552
[alsa] can not set Default Mixer Tracks to track on second sound card
Last modified: 2007-05-28 21:16:41 UTC
Please describe the problem: Under Sound Preferences -> Devices, I can select my second sound card (actually a USB webcam with one Microphone track) as "Default Mixer Tracks" device, and select the Microphone track. However, when I press the volume up/down keys, the Microphone track of the first sound card is adjusted. Steps to reproduce: 1. Select a track on the second sound card as Default Mixer Track 2. Open up the Volume Control panel and watch the sliders of the second card 3. Press volume up/down keys 4. Watch the sliders of the first card 5. Press volume up/down keys Actual results: The slider moves on the first card. Expected results: The slider should move on the second time. Does this happen every time? Yes. Other information: The gconf values are correct: /desktop/gnome/sound/default_mixer_device=alsamixer:hw:1 /desktop/gnome/sound/default_mixer_tracks=[Microphone] The problem was reported in Ubuntu: https://bugs.launchpad.net/bugs/116929
I played around in gdb as good as I can (I am not experienced with gabstracted code), and I could verify a few things in acme_volume_gstreamer_open (from acme-volume-gstreamer.c): - at line 306, self->_priv->mixer = GST_MIXER (element); the mixer is set to an "alsamixer" object - at line 311, g_object_set (G_OBJECT (self->_priv->mixer), "device", &factory_and_device[1], NULL); the "device" property is set to "hw:1" - at line 328, for (m = gst_mixer_list_tracks (self->_priv->mixer); it starts iterating the tracks of the wrong mixer device - at line 334, if (!strcmp (t->data, track->label)) it finds a match for the track label, but I guess this is the "Microphone" track on the wrong mixer I guess the fault happens in gst_mixer_list_tracks, it seems that it doesn't use the "device" property correctly.
Created attachment 88885 [details] gdb session I attach a gdb session log, with some comments from a similar session here: (I get lost with gdb when we get to the GST_IMPLEMENT_ALSA_MIXER_METHODS macro.) In gst_mixer_list_tracks: klass->list_tracks is <gst_alsa_mixer_element_list_tracks> klass->list_tracks(mixer) is called with this mixer: (gdb) print (GstElement) *mixer $2 = {object = {object = {g_type_instance = {g_class = 0x810fe50}, ref_count = 1, qdata = 0x0}, refcount = 0, lock = 0x81d69e8, name = 0x81afba8 "alsamixerelement2", name_prefix = 0x0, parent = 0x0, flags = 2, _gst_reserved = 0x0}, state_lock = 0x81d6940, state_cond = 0x81d6a50, state_cookie = 1, current_state = GST_STATE_READY, next_state = GST_STATE_VOID_PENDING, pending_state = GST_STATE_VOID_PENDING, last_return = GST_STATE_CHANGE_SUCCESS, bus = 0x0, clock = 0x0, base_time = 0, numpads = 0, pads = 0x0, numsrcpads = 0, srcpads = 0x0, numsinkpads = 0, sinkpads = 0x0, pads_cookie = 0, _gst_reserved = {0x0, 0x0, 0x0, 0x0}} (gdb) Then in GST_IMPLEMENT_ALSA_MIXER_METHODS: (gdb) info locals this = (GstAlsaMixerElement *) 0x81d6a1c __PRETTY_FUNCTION__ = "gst_alsa_mixer_element_list_tracks" (gdb) print *this $7 = {parent = {object = {object = {g_type_instance = {g_class = 0x6f68706f}, ref_count = 25966, qdata = 0x29}, refcount = 136145600, lock = 0x81d6df8, name = 0x81d8590 ",j\035\b°\203\035\b", name_prefix = 0x24 <Address 0x24 out of bounds>, parent = 0x24, flags = 136326016, _gst_reserved = 0xb71ae3f0}, state_lock = 0xb71ba000, state_cond = 0x81d6a88, state_cookie = 57, current_state = GST_STATE_VOID_PENDING, next_state = GST_STATE_VOID_PENDING, pending_state = GST_STATE_VOID_PENDING, last_return = GST_STATE_CHANGE_FAILURE, bus = 0x0, clock = 0x0, base_time = 0, numpads = 0, pads = 0x0, numsrcpads = 0, srcpads = 0x63697665, numsinkpads = 101, sinkpads = 0x39, pads_cookie = 136146060, _gst_reserved = {0x81d6c8c, 0x81d6bb0, 0x81d6bb0, 0x81e9184}}, mixer = 0x821c86c, device = 0x81e9a48 "\200\221\036\b\220\220#\b¸p\035\b\020\206\035\bèj\035\bà\215#\b8\233\036\bÈ\004\"\b8Ú\037\bÐ\003 \b"} (gdb) Seems like the above contents are just rubbish, and have not been initialized. Then the selected mixer gets lost in the next gdb "step": (gdb) where
+ Trace 136270
$4 = {tracklist = 0x0, handle = 0x81de6c8, device = 0x81dea20 "default", cardname = 0x8207440 "HDA Intel", dir = GST_ALSA_MIXER_ALL} Here the first sound card is being used, and at line 356, the tracklist gets filled with the tracks of this card. Back in GST_IMPLEMENT_ALSA_MIXER_METHODS now: (gdb) print *this->mixer $16 = {tracklist = 0x81c99a0, handle = 0x81d6a88, device = 0x81d8300 "default", cardname = 0x821c8b8 "HDA Intel", dir = GST_ALSA_MIXER_ALL} It doesn't seem like I can get any further, but I hope this can be useful information for those who take a look at this bug.
If it is indeed alsa-mixer returning the track list for the wrong device, that would make it a GStreamer bug. Let's try to get some input from them.
The code in http://svn.gnome.org/viewcvs/gnome-control-center/trunk/gnome-settings-daemon/actions/acme-volume-gstreamer.c?view=annotate doesn't really look entirely right, if I read it correctly. In particular, lines 298 and 310, where the mixer/element is _first_ set to STATE_READY and only then the "device" property is set. I think it should be the other way around. The "device" property should be set _before_ putting the mixer in READY state (which effectively opens the handle for the device). Along the same lines, you need to set the state to NULL if you want to switch the device (didn't check what the code does here).
Created attachment 88908 [details] [review] Fix state change
> Created an attachment (id=88908) [edit] > Fix state change I'm not sure if that will work in this form. GstMixer/GstImplementsInterface is a bit 'special'. In particular, GST_IS_MIXER() will only evaluate to true if the mixer handle is open (ie. state is >= READY if I'm not mistaken).
Yes, I can confirm that GST_IS_MIXER() fails if state is GST_STATE_NULL. I tried the patch and it doesn't help.
Created attachment 88914 [details] [review] Updated patch. Please test. Sorry. Now I understand the GstImplementsInterface interface.
Created attachment 88917 [details] gdb session GST_IS_MIXER() still fails with the new patch. See gdb session.
Created attachment 88932 [details] stderr from gnome-settings-daemon with GST_DEBUG=*:5 As Jan Arne suggested on IRC, I ran gnome-settings-daemon with GST_DEBUG=*:5 and found this part (attached full log). (BTW, the trick to not having g-s-d restart automatically, and be able to start it manually, was to suspend x-session-manager.) 0:00:34.046954000 5898 0x80710d8 DEBUG GST_ELEMENT_FACTORY gstelementfactory.c:398:gst_element_factory_create: created element "alsamixer" 0:00:34.047027000 5898 0x80710d8 LOG GST_REFCOUNTING gstobject.c:352:gst_object_unref:<alsamixer> 0x818df50 unref 2->1 0:00:34.047087000 5898 0x80710d8 DEBUG GST_STATES gstelement.c:2180:gst_element_set_state_func:<alsamixerelement3> set_state to READY 0:00:34.047126000 5898 0x80710d8 DEBUG GST_STATES gstelement.c:2211:gst_element_set_state_func:<alsamixerelement3> current NULL, old_pending VOID_PENDING, next VOID_PENDING, old return SUCCESS 0:00:34.047162000 5898 0x80710d8 DEBUG GST_STATES gstelement.c:2245:gst_element_set_state_func:<alsamixerelement3> final: setting state from NULL to READY 0:00:34.047245000 5898 0x80710d8 WARN alsa control.c:910:snd_ctl_open_noupdate: alsalib error: Invalid CTL �� 0:00:34.047294000 5898 0x80710d8 WARN alsa gstalsamixer.c:63:gst_alsa_mixer_open: Cannot open mixer for sound device '��': No such file or directory 0:00:34.047331000 5898 0x80710d8 WARN alsa gstalsamixerelement.c:244:gst_alsa_mixer_element_change_state:<alsamixerelement3> error: Failed to open alsa mixer device '��' 0:00:34.047367000 5898 0x80710d8 DEBUG default gstelement.c:1559:gst_element_message_full:<alsamixerelement3> start 0:00:34.047417000 5898 0x80710d8 LOG GST_REFCOUNTING gstobject.c:325:gst_object_ref:<alsamixerelement3> 0x81a11f8 ref 1->2 0:00:34.047455000 5898 0x80710d8 LOG GST_REFCOUNTING gstobject.c:352:gst_object_unref:<alsamixerelement3> 0x81a11f8 unref 2->1 0:00:34.047502000 5898 0x80710d8 INFO GST_ERROR_SYSTEM gstelement.c:1590:gst_element_message_full:<alsamixerelement3> posting message: Could not open resource for reading and writing. 0:00:34.047558000 5898 0x80710d8 LOG GST_MESSAGE gstmessage.c:202:gst_message_init: new message 0x8096cd8 0:00:34.047593000 5898 0x80710d8 LOG GST_MESSAGE gstmessage.c:285:gst_message_new_custom: source alsamixerelement3: creating new message 0x8096cd8 error 0:00:34.047628000 5898 0x80710d8 LOG GST_REFCOUNTING gstobject.c:325:gst_object_ref:<alsamixerelement3> 0x81a11f8 ref 1->2 0:00:34.047661000 5898 0x80710d8 DEBUG default gstelement.c:1491:gst_element_post_message:<alsamixerelement3> not posting message 0x8096cd8: no bus 0:00:34.047695000 5898 0x80710d8 LOG GST_REFCOUNTING gstminiobject.c:304:gst_mini_object_unref: 0x8096cd8 unref 1->0 0:00:34.047727000 5898 0x80710d8 LOG GST_MESSAGE gstmessage.c:211:gst_message_finalize: finalize message 0x8096cd8 0:00:34.047760000 5898 0x80710d8 LOG GST_REFCOUNTING gstobject.c:352:gst_object_unref:<alsamixerelement3> 0x81a11f8 unref 2->1 0:00:34.047800000 5898 0x80710d8 INFO GST_ERROR_SYSTEM gstelement.c:1613:gst_element_message_full:<alsamixerelement3> posted error message: Could not open resource for reading and writing. 0:00:34.047836000 5898 0x80710d8 INFO GST_STATES gstelement.c:2298:gst_element_change_state:<alsamixerelement3> have FAILURE change_state return 0:00:34.047869000 5898 0x80710d8 INFO GST_STATES gstelement.c:1945:gst_element_abort_state:<alsamixerelement3> aborting state from NULL to READY 0:00:34.047922000 5898 0x80710d8 LOG GST_STATES gstelement.c:2337:gst_element_change_state:<alsamixerelement3> exit state change 0
Try the last patch with g_object_set (G_OBJECT (element), "device", factory_and_device[1], NULL); instead of g_object_set (G_OBJECT (element), "device", &factory_and_device[1], NULL);
That helped! Now the device is correct, and the matching of tracks in acme_volume_gstreamer_open works fine. However, my slider does not move, and it displays a "mute" icon on the pop-up indicator. In fact, acme_volume_get_mute() returns 1 in do_sound_action(), and acme_volume_get_volume() returns 6. This might be another issue specific to my webcam though. $ amixer -c 1 Simple mixer control 'Mic',0 Capabilities: cvolume cswitch cswitch-joined Capture channels: Mono Limits: Capture 0 - 3 Mono: Capture 0 [0%] [26.00dB] [on]
Created attachment 88938 [details] [review] Another updated patch ... The other issue seems to be raised by GstAlsaMixer mapping pswitch to mute and cswitch to record.
Another issue, probably off-topic: vol_step is 6, and if the current volume is 67, 67+6 is not enough to make it jump to 100 (I only have 0,33,67,100). I have to use a vol_step of 17 to get 100. I guess the logic is that +17 is more than half the way to the next step. Setting /apps/gnome_settings_daemon/volume_step to 17 works, but shouldn't this be automatic and depending on the mixer volume steps available?
Should another bug be opened about the mute (pswitch) issue? Anyway, thanks everybody for the fix of the original problem, and your amazing responsiveness!
Yes please open other bugs for the mute/record and volume problems. I'll try to fix them later.
2007-05-28 Jan Arne Petersen <jpetersen@jpetersen.org> * actions/acme-volume-gstreamer.c: (acme_volume_gstreamer_open): set the device property to the correct value before opening the mixer. (closes bug #441552) Applied to trunk and 2.18
I filed bug #441908 and bug #441910 for the mute and volume step issues.