-
Notifications
You must be signed in to change notification settings - Fork 189
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
Jittery audio #60
Comments
Hi, please tell me which version of Android you are using. I've seen similar problem you're describing with Android 6.1.x. So, it might be the same issue. I've got Android 6.0.1 and there is no problems with streaming. Unfortunately, I've got rather limited possibilities for testing with various devices. If you've got some other devices, please try to use them as well and post the results here. Additional, you might try to see logs from the bluealsa server. However, I do not know where such a logs on Raspbian Stretch are stored.... In order to perform full debugging, try to compile bluez-alsa by yourself on Raspberry Pi (see the instruction in the readme) and run in. Beforehand, kill the bluealsa server which is already running. Try something like that:
And of course post logs here. |
I see this issue with a Moto G 4 Play device running Android 7.1.1 as well as an Intel TG701 tablet running Android 4.4.2. I'll try to get a hold of a device running 6.0.1 and report back. Here's the bluealsa log from the Android 7.1.1 device: pi@arachnos:~ $ sudo bluealsa Going to restart the pi before doing the same test with the Android 4.4.2 tablet in order to get a clean system state. |
The Android 4.4.2 device had much bigger issues, with long pauses where the bluealsa logs say it was "Closing BT". pi@arachnos:~ $ sudo bluealsa |
Thank, for these logs. So it seems, that the problem is with the "link quality" and bluealsa might be the cause of it. I'll make special branch for testing this issue (maybe tomorrow). Basically, what I'd like to see is if the missing RTP packages are caused by bluez or bluealsa. So, it is required to remove all decoding code within the bluealsa and allow the IO thread to just read data from the socket (without decoding and without sending it to the FIFO). If you like, you might try to do it by yourself (in this function), or wait till tomorrow. EDIT |
After commenting out the lines 296 to 324, the bluealsa output shows a lot less Missing RTP packets, though it still happens whenever I do anything at all on the system. If I only leave the console with bluealsa open and don't touch the computer at all, the messages go away completely. But even typing this message on a browser window causes missing RTP packets. If I move a window around the screen, I get a burst of Missing RTP packets per second. This with the system load between 10% and 20%. |
OK, so the problem seems to be load related after all. See this comment for some clues: #21 (comment) |
I'll see if I can get the configuration fix on that comment working on Raspbian Stretch, but this probably needs a FAQ/Wiki page on its own once a fix is identified, rather than being buried on a thread about compiling it. Raspbian Stretch uses bluealsa by default, so if their default configuration is useless because of system scheduling not giving enough CPU time to bluealsa, the fix should be very visible and easy to find for everybody migrating to Stretch. |
@leandrotlz, perhaps you can report this to Raspbian. I see no mention of this on their strech launch (party) blog. And seemingly the only way to communicate this to them is to respond on the blogs or forums. That being said, they do explicitly exclude (nor test apparently) bluetooth audio input from support, see this post. Seeing things from the other side, I would not use my "hack" as a proper solution for a distribution. As I said in the comment that @arkq mentions, it's a rather nuclear option that can make your system unresponsive if something misbehaves. I've ammended the thread #21 with some further comment, that could be an explanation for what is happening here. Specifically, the Pi problem in reverse, bluez-alsa not preempting bleutoothd and thus missing packets from the pipe. So not exactly a CPU time issue, but a CPU timing issue. |
@Captain-Coder thanks a lot for this extensive explanations. I was thinking for a while, that maybe it could be resolved in the bluealsa itself, however my knowledge is rather short in the area of RT systems (especially running on a board with a single CPU thread). One possible solution is to put bluez and bluealsa in the FF scheduler (or maybe RR just like you've said), however who should decide about that? I think, that the correct answer is the user (in the case of this issue, the distribution - Raspbian - creators), who wants prioritize Bluetooth audio over other things. Anyhow, there is one possibility to improve responsiveness of the IO thread in the bluealsa. My current approach is a single thread which do things as follows (in a pipeline fashion): -> select for read There is no select for writing and writing is non-blocking. So if there is no room for data it will fail. I could rearrange this logic to be governed by two threads, however this approach will require locks, which I'd like to avoid. Other approach is to multiplex reading and writing within a single thread. And that's what I will try to accomplish. However, I do not know if result will be worth the effort.... |
As far as I know only the first generation of PI is a single core, many if not most will now be true multi-core systems. So the single core Pi is really the worst case scenario. First off, I am by no means an expert on real-time scheduling in linux. I know the basics from my Operating Systems course in university, and learned some of the linux implementation details while trying to figure out how to get glitch free audio on my pi. From what I understand there are two types of processes SCHED_NORMAL for non real time processes and either SCHED_FIFO or SCHED_RR for real time processes. The trick here is that a process which has any of the rt schedulings will preempt running processes. So for this situation it doesn't matter much if it is the FIFO or RR one. The only thing that matters is to get the process reading the pipe under the RT scheduler regime. As opposed to the "when the next slot comes around" scheduling when using SCHED_NORMAL. If both bluez-alsa and bluetoothd are set to rt scheduling, then it is something to look into. On multi-core systems this prempring is real easy, there may well be a core available or linux can preempt one without to much overhead. But as we can see in this comment, on a single core Pi this generates a large overhead due to all the process preemption (for pretty much every write to a pipe). Had a quick glance at io.c, both IO functions looks fine to me (or put another way: I don't know how to do it better). The only thing that strikes me is the delay. I would think that the rate of the source and sink should be matched so delay/synchronisation should happen naturally on the blocking read from PCM? Having said that I can't find the actual "delay" function, it seems to be only communicating the incurred delay, not actually waiting for it? If it is an actual wait, the type of wait could have a big impact. A sleep(..) style wait would yield the remaining timeslice to the scheduler and allow the other end of the pipe to start reading pretty much immediately without having to resort to RT scheduling. (This could fail under load though). A spin-wait/delay could be a problem here, but if the delay is small it might be the only option. Splitting the IO thread into two opens up a whole can of worms. Not only will you require locking on your data structures as you say, but I can imagine synchronisation being a headache, and any (slight) missmatch between the rate of the source and sync will potentially buffer an ever increasing amount of data between the two threads. And oh, it causes even more context switches and latency. Like you, I'd try to steer clear of this route. I'm unsure what you mean by multiplexing in this context, what would the io thread logic look like in that case? |
That's true. Sink IO actually relies on the reading-based synchronization. However, source (theoretically) does not. Source reads from the PCM FIFO, which in fact is synced with the audio rate by the PCM ALSA plugin. However, there should be no sync requirement - e.g. one could open bluealsa PCM FIFO and write to it some audio (omitting ALSA system) without worry about transfer rate (that was my idea). So, synchronization is done by the bluealsa itself (it could be optimized a little, because right now, timing is calculated by the PCM plugin and by the bluealsa...).
Of course, for delay sleep is called (nanosleep actually). Spin-locks are mostly used by kernel (that what I've heard), using them in a userland might not be a good idea :D - generally speaking. I've been using spin-locks, but in microprocessors.
That is so called "can of worms" minus unnecessary context switches. However, the "synchronisation being a headache" preserves. I will select on reading and writing. If read wakes up, I will fill in the internal buffer, then if the write wakes up, I will send this buffer through the socket/PIPE (writing will be prioritized - firstly checked). In the select I will incorporate timeout which will maintain transfer rate, however with some granularity. Right now, transfer is checked and corrected every read/write spin, which might be unnecessary. Single read/write processes about 2ms of audio. If transfer will be within 10ms, it will be still OK, but it might help socket communication - there will be some room for timing de-synchronization between threads (from the kernel point of view). So, that's my basic idea. I will have to implement it anyway, because right now I'm trying to merge mSBC feature from the #37. It requires a little bit of freedom in the IO loop - aka internal buffer, because single mSBC packet is about 250 bytes, however, socket MTU is 24 bytes. And my communication template/example - Jabra headset - sends packets via the socket not with a constant rate, but with bursts when a single audio frame is encoded. So, I will try to implement something similar :). |
I am having this same problem with a Samsung S8+ running Android 7.0. I managed to connect my Asus transformer laptop (running Windows 32 bit) and music streaming from the PC to the Pi worked just fine. |
Hey guys, I also had this jittering on my rpi3. (I'm using the raspberry pi as bluetooth audio sink) In my case it was because of the internal bluetooth chip of the raspberry. bluez-alsa didn't have a impact on the cpu so it needed to be something else. after I tried an external bluetooth usb stick it was working without any problems in great quality useful infos: http://youness.net/raspberry-pi/bluetooth-headset-raspberry-pi-3-ad2p-hsp |
Another tip for rpi3 owners using built-in BT - try disabling built-in wifi via overlay
|
I can confirm a Pi zero (not W) with a BT adaptor works fine |
I can confirm a Pi zero W with inbuilt BT does not work fine |
I downloaded and compiled the code like so When I stream from my Android phone to the internal BT chip of the Pi3, I get the following debug messages from bluealsa (see below). Is there anything I can do to change the code or test that will help you? bluealsa: ../../src/ctl.c:489: Starting controller loop |
After lots of research, it looks like this is a problem with Raspberry Pi firmware. Wifi and BT do not coexist very well. It is referenced here The easiest workaround is to use a USB BT adapter until new Pi firmware comes out. |
I was able to do this on a rPi3 by setting up a UDEV rule to disable wifi when a BT device connects. I'm still getting a few xruns every minute and a faint chattering like when a CD is all scratched up but still playable. Separate issues I know. |
Having come back to my project after a few months, I can confirm that my original problem was definitely the rPi bluetooth/wifi interference as mentioned above, not anything to do with bluez-alsa (which is now working impressively well!) |
I am currently using a raspberry pi 3 and I also notice the jittery audio. The music is barely understandable. I am using bluealsa 1.2.0 and bluez 5.48. I experimented by setting real-time priorities for the services bluealsa, bluetoothd and bluealsa-aplay but nothing helped. Wifi is disabled using device tree overlay and the WiFi kernel modules are not loaded. I'm getting lots of messages: Can anyone advice me? Thanks |
To come back on my comment. I have been able to fix this by setting the serial speed to a higher value. I was using 115200 which was not sufficient at all. By configuring hciattach with speed 3000000, it worked almost perfectly. I only get sometimes an error (once at 20 minutes): bluealsa: Missing RTP packet: 18440 != 18439 Pieter |
Using this plugin to stream audio from Android to Raspberry Pi 3 (fresh install of Raspbian Stretch).
No real setup needed, and I haven't changed any settings, but when using bluealsa-aplay audio is unlistenable - cutting out every second or so - when using my phone or tablet. I've tried changing the buffer size but that only seems to make it worse.
I'm a bit of a linux noob and documentation here seems to be fairly minimal, so pointers on how to at least find relevant logs/debugging information would be greatly appreciated.
The text was updated successfully, but these errors were encountered: