12

I have installed raspbian on my Pi and configured a PulseAudio sink with the intention to stream all audio from my desktop to a Pi, driving the loudspeakers.

I followed this nice description: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=38&t=11124

At first, this appeared to work without problem. However, the audio sent from the desktop is constantly stuttering on the Pi, as if there were constant buffer underruns with just a few samples missing in-between.

I spent the whole day trying to find the cause, but to no avail. The basic setup is:

  • wired LAN connection
  • latest raspbian pi (26 Sep 2013) with latest firmware updates
  • PulseAudio 2.0 on both sides (Ubuntu desktop)
  • Playback through mplayer, totem, ffplay
  • network transmission via module-native-protocol-tcp

This is what I tried:

  • Playing audio directly on the Pi works perfectly.
  • Streaming to other (desktop) computers works fine.
  • Sending audio with a direct connection (specifying $PULSE_SERVER) works quite well with very little stuttering, but still prone to Problem-2 (see below)
  • Sending audio via desktop PulseAudio tunneling gives constant stuttering
  • Increasing priorities / realtime scheduling... did not help
  • Fixing sampling rate to 48 kHz ... did not help
  • Setting resampling algorithm to "trivial" ... did not help
  • Adjusting default-fragments/fragment-size ... did not help
  • I cannot find any indication of a problem in the PulseAudio logs (shown from the time I started playback):

    D: [alsa-sink] protocol-native.c: Requesting rewind due to end of underrun.
    D: [alsa-sink] sink-input.c: Requesting rewind due to uncorking
    D: [pulseaudio] sink.c: Suspend cause of sink alsa_output.platform-bcm2835_AUD0.0.analog-stereo is 0x0000, resuming
    I: [alsa-sink] alsa-sink.c: Trying resume...
    I: [alsa-sink] alsa-util.c: cannot disable ALSA period wakeups
    D: [alsa-sink] alsa-util.c: Maximum hw buffer size is 341 ms
    D: [alsa-sink] alsa-util.c: Set buffer size first (to 16384 samples),  period size second (to 16384 samples).
    I: [alsa-sink] alsa-util.c: ALSA period wakeups were not disabled
    D: [alsa-sink] alsa-sink.c: Latency set to 25.00ms
    D: [alsa-sink] alsa-sink.c: hwbuf_unused=60736
    D: [alsa-sink] alsa-sink.c: setting avail_min=15665
    I: [alsa-sink] alsa-sink.c: Time scheduling watermark is 15.00ms
    I: [alsa-sink] alsa-sink.c: Resumed successfully...
    I: [alsa-sink] alsa-sink.c: Starting playback.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [pulseaudio] module-suspend-on-idle.c: Sink alsa_output.platform-bcm2835_AUD0.0.analog-stereo becomes busy.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] alsa-sink.c: Cutting sleep time for the initial iterations by half.
    D: [alsa-sink] ratelimit.c: 115 events suppressed
    D: [alsa-sink] alsa-sink.c: Wakeup from ALSA!
    ... no more output, but stuttering continues ...
    

Problem 2: as said above, I can get quite ok audio with a direct connection. However, after a few skips within the stream (using mplayer), the PulseAudio server hangs and does not play any audio at all. Sometimes it can be revived by restarting mplayer. Sometimes it hangs so badly that PulseAudio has to be restarted. Sometimes it even hangs when I only change the volume level.

According to the PulseAudio docs, the advantage of a direct connection over a tunnelled connection is to have better buffering control, which seems to indicate why I get good audio with the direct connection: http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Network/

I am out of ideas now. What could cause the stuttering and Problem 2 ? Just an idea how to proceed debugging would also be appreciated.

3
  • How did you play the audio directly? I've had no problems with aplay, but paplay stutters and echos terribly. Jan 29, 2014 at 6:48
  • I used mplayer, totem, madplay, ... But the fact that different players behave differently support my guess that it seems to be a software problem with data buffering. Some players pushing more data ahead of real-time than others.
    – farindk
    Jan 30, 2014 at 16:13
  • I'm having trouble just playing sine waves. I think I'll need to solve that before I can try streaming over the LAN. Feb 17, 2014 at 0:27

6 Answers 6

6

tsched_buffer_size and tsched_buffer_watermark were the settings that made it work for me.

I run my PulseAudio as a system instance, so the config is in /etc/pulse/system.pa. If you are using a session instance instead, then the config will be in /etc/pulse/default.pa.

This is the default:

### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
load-module module-udev-detect
.else
### Use the static hardware detection module (for systems that lack udev/hal  support)
load-module module-detect
.endif

I replaced it with this: (ie, commented it out)

### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
#load-module module-udev-detect
.else
### Use the static hardware detection module (for systems that lack udev/hal  support)
#load-module module-detect
.endif

Then I added the following line:

load-module module-alsa-card device_id=0 tsched=true tsched_buffer_size=1048576 tsched_buffer_watermark=262144

See http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Modules/#index6h3

4
  • Good point. I tried, but it did not help. Even with much larger buffer sizes. Sending audio over a direct connection by setting PULSE_SERVER to the Pi gives clean audio, but just changing volume will eventually freeze the connection. Audio via tunneling still gives the stuttering. My guess is that this is really a PulseAudio problem, because with that large buffer sizes (I used 4 MB), one should see that the audio is decoded way ahead of time at the beginning of a file. But it is not. So there must be something slowing down the refill.
    – farindk
    Oct 6, 2013 at 22:18
  • Running into the same kind of issues. In my particular case, PULSE_SERVER+mplayer works like a charm, while PULSE_SERVER+clementine (which I believe is using gstreamer) stutters terribly. Any idea what differs between the two? Jan 14, 2014 at 21:52
  • @Protzenko: My guess without looking at any source is that mplayer might push data until PulseAudio is blocking, while gstreamer might send out data clocked by a realtime reference. That would mean that buffers are much more filled in the former case, and consequently, there is a larger delay.
    – farindk
    Jan 21, 2014 at 9:38
  • I'm seeing the same problem PULSE_SERVER+ffmpeg fine, PULSE_SERVER + mpd shutters and implicit underruns May 3, 2016 at 22:46
4

The main point is that you must use module-tunnel-sink-new, but you must also make a few other changes to get stutter-free network audio on the raspberry pi 1.

  1. Run pulseaudio on the raspberry pi with realtime priority:
pulseaudio --start --high-priority=yes --realtime=yes

Let us use the term sender to denote the computer which sends the stream to your raspberry pi.

  1. Set default-fragments and default-fragment-size-msec in daemon.conf at sender to these values:
default-fragments = 8
default-fragment-size-msec = 12
  1. Use module-tunnel-sink-new by issuing this command at sender (assing the hostname of your raspberry pi is RP1 and you have mDNS working on your local network. Otherwise, just use the IP-adress of your raspberry pi).
pactl load-module module-tunnel-sink-new server=RP1.local

With these settings I get stutter-free audio from a raspberrypi 1 over a wireless network operating at 54 Mbps (In my setup, sender uses ethernet and RP1 is using wlan). Actually, it works even when both sender and raspberrypi is using wlan, at least if there are no other devices on the wireless network.

4
  • Works great so far. I did find that for my Pi3 (with a somewhat newer debian/software) I had to change something else for the "default-fragments" settings to be picked up. (namely, something setting tsched=0, see wiki.archlinux.org/index.php/PulseAudio/…)
    – rien333
    Dec 15, 2018 at 15:35
  • If you still experience stuttering, the arch wiki also recommend changing to the rtp streaming protocol: wiki.archlinux.org/index.php/PulseAudio/…
    – rien333
    Dec 15, 2018 at 18:24
  • 1
    Thanks a lot! I already had step 1, then step 3 and finally found this answer. Step 2 practically solve all my stutter and freeze issues, even on Wi-Fi! RTP appeared to solve, yet not always, and introduced new problems. Step 2 settings look like they can't have any drawback, except perhaps a slightly higher CPU consumption (because pulseaudio handles twice as many fragments per second). How comes this is not default, or at least saliently advised? Jun 12, 2020 at 19:55
  • Also, according to wiki.archlinux.org/index.php/PulseAudio/… *fragments* parameters are ignored until tsched=0 is used. I did not use it and my problem is solved by step 2... This is inconsistent. Anyway, it works! Jun 12, 2020 at 19:57
1

did you check out this page:

http://manpages.ubuntu.com/manpages/lucid/man5/pulse-daemon.conf.5.html

DEFAULT FRAGMENT SETTINGS

   Some hardware drivers  require  the  hardware  playback  buffer  to  be
   subdivided  into  several  fragments.  It  is  possible to change these
   buffer metrics for machines with high  scheduling  latencies.  Not  all
   possible  values  that  may  be  configured  here  are available in all
   hardware. The driver will to find the nearest setting supported. Modern
   drivers that support timer-based scheduling ignore these options.

   default-fragments= The default number of fragments. Defaults to 4.

   default-fragment-size-msec=The  duration of a single fragment. Defaults
   to 25ms (i.e. the total buffer is thus 100ms long).
1
  • Yes, tried that, but it did not help. As I mentioned, the audio-playback on the device itself works fine. I assume this it a network protocol problem with the PulseAudio tunneling. Even the direct connection protocol works well. I've now switched to a simple Bluetooth streaming hardware, which is reliable and using the RPi for other things.
    – farindk
    Jan 21, 2014 at 9:34
1

To get rid of stuttering or timeout problems, try a FW downgrade:

sudo rpi-update eeb2e51c3e08cd5efa4246aa8dc54a09b25ada12
3
  • 1
    WARNING Be aware of what rpi-update use in this fashion can do to your system.
    – earthmeLon
    Jul 1, 2015 at 18:30
  • @earthmeLon you could at least give a reference or try to inform us what using rpi-update in this fashion can do to our systems...
    – user11171
    Mar 10, 2017 at 16:54
  • Be sure to Read the Manual, and do some research to understand how this affects your system and any potential dangers.
    – earthmeLon
    Mar 10, 2017 at 17:13
0

I recognized that this issue might be related to the kernel version. After upgrading from 3.6.11 to 3.12.0 I constantly received those underruns. A downgrade back to 3.6.11 solved the problem for me.

0

I have been reading this page a couple of times... I have also been frustrated with the stuttering of the RaspberryPi-pulseaudio-network combination. I searched a bit more and found a page where I found a part of the solution:

=> Disable the module-suspend-on-idle in the default.pa (or system.pa).

Behold, the stuttering has disappeared!

Now the only problem is that after a while (10 to 20 secs) the playback hangs :-/

Any suggestions?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.