New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bluez-alsa and mpd 0.21.x don't play well together; cpu pegged #174
Comments
This is just a friendly nudge. Did the brief exchange last month with the MPD maintainer lead anywhere? I'm willing to ask the alsa-lib maintainers for clarification but I don't know how to pose the question and I wouldn't know how to interpret the response. |
Did the brief exchange last month with the MPD maintainer lead anywhere?
I'm afraid, that it did not lead "us" anywhere.
Quoting from MaxKellermann:
bluez-alsa's implementation makes assumptions on the number and order
of poll descriptors - it assumes it will get the exact same buffer which was
previously passed to snd_pcm_poll_descriptors(). But the alsa-lib API
documentation does not document that applications must do that, therefore
I must assume that bluez-alsa's assumption is wrong and this is a bug in
bluez-alsa.
He is right, I was not able to find any documentation regarding passed buffers (persistence of it). However, it makes more sense to pass the same buffer to the consecutive calls, than passing different buffer of different size. Let say, that we can pass buffer of any size and ordering to the snd_pcm_poll_descriptors_revents(), so we can pass buffer of few MB at let this function (underlying implementation) to sniff for correct file descriptor - that's insane.
Bluez-alsa's implementation is based on the alsa-plugins repository, and every PCM plug-in in this repository check whether the size of the buffer matches exactly (where bluez-alsa allows bigger buffer, but does not use it) the requirements - values returned by the snd_pcm_poll_descriptors_count() - which is explicitly stated by the documentation. It uses the word "should" not "shall"/"must" so there is some room for interpretation (is it?) :D.
The poll desctiptor array should have the size returned by ::snd_pcm_poll_descriptors_count() function.
https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#ga742e8705f6992fd0e36efc868e574f01
There is no info about preserving the ordering, though. BUT, the official implementation of the AAF PCM plug-in does assume, that the order is preserved:
http://git.alsa-project.org/?p=alsa-plugins.git;a=blob;f=aaf/pcm_aaf.c;h=cc7dbe385b974c7e824713578996cc6823312a13;hb=HEAD#l1226
http://git.alsa-project.org/?p=alsa-plugins.git;a=blob;f=aaf/pcm_aaf.c;h=cc7dbe385b974c7e824713578996cc6823312a13;hb=HEAD#l1250
So, I'm also not willing to change my implementation, which I assume is correct... stalemate :)
|
Thanks for clarifying the situation. |
Stalemate is not good :-( Per MPD dev's last response if a clarification is obtained from ALSA dev there is a possibility for resolving the issue. MusicPlayerDaemon/MPD#432 (comment) I'll be happy to ask ALSA team but I don't have any experience with the API and so my conversation might not go anywhere. I know it's a pain but perhaps you could ask them? -Tim |
I've made a fairly simple change to MPD in my fork here: |
@TheOldPresbyope @moodeaudio |
Sorry I didn't respond yesterday. Last night I built the current bluez-alsa master and your alsa-revents branch of MPD. My goal was to test them in the moOde audio player, a project maintained by its BDFL @moodeaudio. In my sleepy state I borked something in merging in the new code but will revisit this evening. moOde audio player runs on Raspbian/RPis. I'd love to help build the case to present to the MPD maintainer but I don't have other examples of breakage. Note that the MPD maintainer has several times invoked the documentation of the ALSA API as the arbiter. I'm not competent to address the ALSA developers. Do you feel you can make a case to them that the documentation needs to be clarified? PS - mille grazie for doing this work. |
A quick update on finding supporting evidence - a quick grep of the alsa repository shows that the following source files from the alsa-lib reposittory explicitly check the size of the pfd array and the order of the array elements passed to snd_pcm_poll_decsriptors_revents(), returning an error if the checks fail: and the following source file from the alsa-plugins repository does not check the pollfd array, but does fail if the elements are in the wrong sequence: What is really needed now is one or more examples of actual devices which trigger these tests and result in failure with MPD. Let's hope someone reading this may be able to report one! |
@borine No, to be honest I've never come across any application/PCM which has similar issue due to using multiple number of FDs. The only example which has slipped through my fingers is the AAF plugin. However, it was added to the repo on 2018-10-24, so it has been developed pretty recently - one can not say that the "incorrect" usage of the snd_pcm_poll_descriptors_revents() implementation is due to code being old...
@moodeaudio I've got rather bad experience of asking alsa-lib developers about anything. I've proposed few patches for ioplug, but no one has ever looked at it - there were not questions but solutions to few issues in the codebase. Few months later one of the addressed issues has been fixed, one half-fixed, but introduced other quirks, and other left untouched. Maybe someone with bigger authority might break through the alsa-lib firewall :D |
@arkq, I completely understand your position wrt the alsa-lib project. I've read similar reports of other dev's having great difficulty dealing with alsa-lib proj. If I understand @borine's evidence of how alsa-lib sources are coded to handle the particular condition we are experiencing I would think that MPD maintainer would seriously consider a PR even though the ALSA documentation may not be golden. |
Can confirm that your
Once paired and connected, also properly receives BT audio stream from my Nexus phone, but vanilla MPD 0.20.20 and 0.21.5 worked with bluez-alsa in that configuration too. Much thanks. |
OK, thanks for testing. I've run it continuously for 3 days on both an rpi zero-w and an intel box. I had one crash of mpd on the rpi, but haven't been able to reproduce it. Other than that it works well not only with bluealsa, but also an IQAudio DAC and an intel HDA chipset.
Hmm, I'm surprised that MPD 0.21.5 works at all with buealsa - it makes the same call to snd_pcm_poll_descriptors_revents() that fails with playback when capturing also. That call was introduced in MPD 0.21.2. |
Sure, here's link to moOde 5 beta :-) |
@moodeaudio thanks. I can reproduce this lock-up reliably today just by doing "mpc next" while listening to a playlist. MPD stops the current song but never starts the next one. Not sure how I came to miss this earlier. Anyway, I need a little to to determine whether this is a defect in bluealsa or MPD, (or both). I'll make a new commit when I have a fix ready. |
I just checked to be sure I wasn't mis-remembering. With moOde r50c (the beta referred to above) running MPD 0.21.5 I'm getting Bluetooth audio streaming in from my Nexus phone and playing through the onboard audio. Nominal CPU usage. |
@TheOldPresbyope |
@arkq |
I'm not seeing the lock-up you report. moOde builds a playlist from my selections from sources. I can switch between tracks on the playlist. "mpc next" works. [on RPi3B+, Raspbian, moOde r50c] |
Ok, thanks, that's very useful feedback. I'll dig further to see what's happening on my system. |
My bad. You are correct of course. I forgot moOde selects bluealsa-aplay as its BT renderer. Sorry. |
So, why I didn't get lockups until today, and (I think) @TheOldPresbyope does not get them. |
Below are the files that moOde 5 beta uses for bluealsa audio output. Maybe this config is causing issue? In the file /etc/bluealsaaplay.conf the param AUDIODEV is set to plughw:0,0 or if Bluetooth speaker sharing is turned on in moOde Audio Config then its set to btaplay_dmix which invokes /usr/share/alsa/alsa.conf.d/20-bluealsa-dmix.conf. AFAIK plughw will automatically try to reformat the audio stream to be compatible with output device. IIRC it used to be set to hw:0,0 in some earlier version of moOde. /etc/mpd.confaudio_output { /etc/bluealsaaplay.confAUDIODEV=plughw:0,0 /usr/share/alsa/alsa.conf.d/20-bluealsa-dmix.confpcm.btstream { /usr/share/alsa/alsa.conf.d/20-bluealsa-dmix.confpcm.btaplay_dmix { pcm.plug_btaplay_dmix { |
Correct, I was playing 44.1KHz rips of CD in my successful test of "next". Can't say for sure about the web radio stations. I'll try repro'ing your All this is making me acutely aware of how superficially I understand the MPD-ALSA-BluezAlsa wiring. s an aside, I agree with your assessment regarding "preferred fix". |
@TheOldPresbyope
I see that @arkq is very busy atm implementing a d-bus interface for bluealsa, so I've just gone ahead and prepared a PR that makes the changes I think are necessary in the alsa pcm plugin. It can sit in his in-box until he has enough free time to consider it. In the meantime I'm happy that I have working builds of mpd and bluealsa that work well together (at least in my use cases) so I'll take a break from this effort for a while and just enjoy the music. Thanks to all for helping me get this far. |
@borine Sorry for not being very responsive, but indeed I'm busy (not with bluez-alsa alone, but in general) :) I'm watching this thread, though. If you've got any fixes please do not hesitate to make a PR. I know that the PCM ALSA plug-in is buggy but unfortunately it is rather hard to implement it in a correct way - there is no test-suit for ALSA PCM... and the documentation is "in the alsa-lib code" mostly. In a long run there is a plan for a total ALSA PCM plug-in refactoring, but right now I don't know where the direction should be, so I'm very happy with any fixes to current implementation. It might be also beneficial to have PCM test cases in case of future changes, so the knowledge how the PCM should behave will not fade away. But it might be a rather tedious work... Once, I've tried to create a test for BT device disconnection - analogue of USB-based sound card eject. And the problem is, that without alsa-lib fixes this work is impossible - there are some bugs in the ioplug code that prevent correct implementation (that was my first "pleasure" with alsa-lib mailing list). |
Hi, This issue has been fixed in bluez-alsa 2.0.0. It works perfectly with MPD 0.21.15 :-) @TheOldPresbyope, I'd propose closing the issue. |
I'm not sure how it has been fixed :D I have not made any changes related to file descriptor ordering. From my point of view with 2.0.0 it might be even worse than before, because the number of file descriptors is controlled by libdbus. So maybe it was fixed by mdp...? |
lol, I didn't see a specific mention of it in MPD change log so I assumed you made some changes in 2.0.0 that fixed it. We may never know what was causing the failure or how it's been somehow fixed but it's working now and hopefully will continue to do so going forward :-) |
Actually, the combination of bluealsa with mpd works "by accident", and has done so since bluealsa commit aab107c which removed the check on the size of the pfd array passed by mpd to bluealsa after a poll() event. |
I see. Maybe best to leave the issue open. I'll have to do more A/B testing to determine whether to stay on 1.3.1 and the two MPD's or go for 2.0.0 and MPD 0.21.y. After a bit of testing this morning I'm seeing a delay of 30 secs between the time when an incoming bluetooth connection is established and the time when the udev rule fires that starts bluealsa-aplay I don't recall this delay being present on 1.3.1 but I'll test to be sure.
|
I don't know for what you need udev, but with 2.0.0 everything should be wired via DBus. You can start bluealsa-aplay before bluealsa :) |
I'll have to study that some more. The udev rule detects the incoming client connection and then does a few things to switch playback from MPD to bluealsa-aplay. Is there a way to detect the connection and run a script via d-bus? |
You would need a lightweight daemon watching dbus events. I use a small python script to handle this...... This is not for the current version of bluelasa, but this concept works nicely. |
Testing suggests that its kernel 4.19.81 that causes the 30 sec delay issue and some other breakage. This happens with either 1.3.1 or 2.0.0 bluez-alsa. Reverting to < kernel 4.19.81 and no issues with either 1.3.1 or 2.0.0 blues-alsa. Note that I only tested w/ 4.19.80 and 4.19.75. |
To add, I'm not necessarily ruling out an MPD issue. I've been testing with MPD 0.21.15 and one of the moOde devs suggested testing with the latest 0.21.16 release. I'll get to that tonight and report back. |
Same issue with 4.19.81 + MPD 0.21.16 + bluez-alsa 2.0.0. Note that I'm only able to do integration testing and not debugging of the kernel or other parts for his issue. Swapping is a kernel that's < 4.19.81 and no issues. |
Forget what I said about "confusing error messages" - turns out the "broken pipe" error message is normal behaviour for all applications when a BT device disconnects with bluealsa. So FWIW I think it is now safe to use the pcm plugin from bluealsa >= 2.0.0 in combination with mpd 0.21.x or 0.22.x (when released). Even though the interaction is not as designed, it is still predictable, stable, and reliable. I haven't checked the ctl plugin yet, but expect to have rather more issues with mpd's unique alsa code there. If I get time later I'll set up a test with the mpd mixer_type set to "hardware" and see where that takes me. |
when using the "hardware" mixer_type mpd aborts with an assertion failure when the BT device is disconnected from bluealsa. That failure is most definitely a bug in mpd, and I did raise a PR to fix it, but then withdrew it when I realised it only did half the job. This is because the bluealsa ctl plugin also causes an assertion failure in libasound if the bluealsa daemon is stopped (you can see alsamixer fall over to demonstrate this one is not an mpd bug) So my advice is to always use mpd's "software" mixer, never the (default) "hardware" mixer with bluealsa until both these assertion failures are fixed. |
Guys, How long I should play music from MPD->BT until the quirks you describe happen? I have a working environment, but I need to check BlueAlsa version and perhaps update it into 2.0.0 |
@roizcorp MPD's alsa interface has never been fully compatible with bluealsa. The two projects use fundamentally different interpretations of the alsa specification regarding the use of poll() to handle events. As each project has changed over time, so the effect of this incompatibility has changed. So the results you see will depend entirely on which versions of mpd and bluealsa you are trying to use together. Right now, the latest release of bluealsa (2.0.0 ), and all updates to the master branch since then, works well with the latest release of mpd (0.21.19) and also the mpd development branch (0.22.x) provided you use mpd's software mixer, not the "hardware" mixer. With these latest versions, you should be able to play music continuously with no time limit.
You would need put an alsa input definition into your mpd.conf file. Check out mpd's documentation for using its alsa input plugin. Mpd's alsa plugin code is much improved in the master branch (0.22.x) and is documented here: https://www.musicpd.org/doc/html/plugins.html#alsa [edit] I've just remembered mpd 0.21.x does not have any config options for alsa input - they are introduced in the development 0.22.x branch. So for mpd 0.21.x you have to use the hard-coded default audio format, no need for mpd.conf entry. I don't have an install of 0.21.x available to test, but from memory an example using the mpc client program would be:
mpd 0.21.x will resample the stream to 44100:16:2. |
Hi, |
I'm a little bit lazy to create release notes... But the main change for >= 2.0.0 is the usage of D-Bus as an interface for BlueALSA server. This change alone should improve overall stability (especially during system startup). Also, there was a lot of work around phone audio (SCO profile), which should more or less work with the latest release (v2.1.0). |
so basically refactoring...which is good |
I must admit, I have not upgraded yet..I'm torn between the fact 1.4.0 works perfectly to my understanding and 2.0.0 is newer and cooler. |
so I have 2 environment:
|
@arkq The fact is that bluealsa and mpd do work together now in both their latest release code current development code. So I recommend that this issue be closed as current comments are really completely different issues. |
@borine do you build your MPD and Bluealsa directly from git i.e. the latest code available? I'm only intrested to use them both? can you share your mpd/bluealsa/alsa/asoundrc configuration so I could see what I'm doing wrong? for some reason MPD does not like the bluealsa output configuration which worked previously SRV=org.bluealsa... |
So here is my last post to this thread; a working example installation: platformRaspberry Pi 3B+, headless bluealsafollow build instructions here: configure options: create bluealsa system account and add to groups audio and bluetooth
follow systemd instructions here: uncomment these entries in /etc/systemd/system/bluealsa.service
modify enable the bluealsa service
add user pi to bluetooth group and reload dbus config
mpdobtain latest sources:
(note: master branch can also be used if you prefer) follow the instructions here: create config file:
create mpd system account and add to group audio:
create mpd data storage structure:
edit the following entries in /usr/local/etc/mpd.conf:
create a new audio output entry in /usr/local/etc/mpd.conf
enable the mpd socket unit:
Using the installationmake sure services are running
pair and connect the bluetooth speaker using bluetoothctl add music files to /var/lib/mpd/music
play music
|
Thank you @borine , I'm using archlinuxarm over raspberry pi 4 (the first bluealsa env. is running over rpi1 !). Prior to your reply it did not work for me but the only things i did change (and are taken for your post) are the addition of the argument |
one last final, final comment 😄
I think this issue can now, finally, be closed |
The original issue reported here was removed by a change to bluez-alsa code many months ago. Bluealsa PCMs are currently working well with MPD provided the latest releases (or development code) of both projects is used. There is stiil a bug in MPD which causes it to fail when a ctl element is removed, but that is not the fault of bluealsa (by design bluetooth mixer controls are removed when the corresponding bluetoth device disconnects). The ALSA API allows applications to test for and handle this event, but MPD does not do that. You can work around it by using MPD's internal software mixer to avoid use of the bluealsa volume control. I'm closing this as many of the comments are no longer relevant to latest bluez-alsa and MPD code, Please open a new issue if you experience a problem using latest MPD with latest bluealsa. |
MPD does not work properly with bluez-alsa driven Bluetooth devices, at least not in certain configurations. In those it emits the following error: > output: Failed to play on "XXX" (alsa): snd_pcm_poll_descriptors() failed: Invalid argument > exception: Failed to open audio output The reason seems to be that MPD makes certain assumptions about some poll file descriptor array that bluez-alsa receives (though ALSA callbacks) but disagrees with. The alsa-lib API supposedly has the contract under specified. If you feel like having a bit more life juice drained out of you, you are encouraged to read up on the circus here: arkq#174 MusicPlayerDaemon/MPD#432 MusicPlayerDaemon/MPD#548 MusicPlayerDaemon/MPD#1037 MusicPlayerDaemon/MPD#1204 This change works around the issue by ignoring the return value of the call to bluealsa_dbus_connection_poll_fds from within bluealsa_poll_descriptors, which is the PCM devices poll_descriptors handler. Better than no sound...
Please read [https://github.com/MusicPlayerDaemon/MPD/issues/432]
It describes a situation we've run into using bluez-alsa with MPD on Raspberry Pis to direct audio to BT speakers. This combination worked fine with MPD up through v0.20.20. Performance was good and CPU consumption on Rasperry Pis was satisfactorily low.
With MPD v0.21.x, real-time scheduling has been introduced. The real-time rtio thread consumes 100 percent of a cpu core streaming to Bluetooth through bluez-alsa and can drag Raspbian to its knees.
As you will see down thread in the referenced issue, after I ran a test devised by the MPD maintainer he concluded that the problem lay not in MPD but either in bluez-alsa, in the (possibly different) interpretations you and he have of alsa-lib API documentation, or in the API documentation itself.
I'd like to help resolve this issue but it's beyond my technical grasp. At best I can run tests and report results.
The text was updated successfully, but these errors were encountered: