CHIP AirPlay server (how to install and configure shairport-sync)


#1

Here’s some info on how to set up AirPlay that I haven’t seen anywhere else so I thought I would share.

I’m using the latest headless server version of the standard flash image as of this time:

root@chip:~# uname -a
Linux chip 4.4.13-ntc-mlc #1 SMP Tue Dec 6 21:38:00 UTC 2016 armv7l GNU/Linux

Install shairport-sync

apt-get update && apt-get -y install shairport-sync

Edit /etc/shairport-sync.conf using nano or whatever editor you like. (I always use ‘vi’ but people seem to like nano so…)

Here are some things to configure. This might work as a copy-and-paste configuration but I don’t recommend it. Instead, consider each option and edit in place.

general =
{
  name = "My Big Speakers"; // or whatever you want
  // This next one can be "basic" or "soxr" (which takes twice as much CPU)
  // Start with soxr and change to basic if you get skipping.
  interpolation = "soxr";
  output_backend = "alsa";
  mdns_backend = "avahi";
  log_verbosity = 0; // only set this if you need to debug a problem. max is 3. 2 is useful
  playback_mode = "stereo"; // should be default but I set it anyway just to be sure
}

sessioncontrol =
{
  allow_session_interruption = "yes"; // optional but can be useful if it thinks its connected but isn't
}

alsa =
{
  output_device = "default";
  // This next one is important because the default doesn't work and
  // if not set your volume control will be done
  // by scaling the samples, lowering the effective bits per sample.
  mixer_control_name = "Power Amplifier";
  // Raise this if you need to for some reason, but you may get lag adjusting volume. Max is 66150
  audio_backend_buffer_desired_length = 6615;
  // I had problems getting ALSA errors and skips when I tried to use synchronization,
  // so I'm recommending "no" if you don't need to synchronize multiple outputs.
  // You can try "yes" but disable this first if you get skipping.
  disable_synchronization = "no";
}

Now we need to make sure the damon doesn’t get starved of CPU, so edit /etc/init.d/shairport-sync and change this:

START_ARGS="--chuid ${USER}"

To this:

START_ARGS="--chuid ${USER} --procsched rr:10 --iosched real-time:4"

The procsched option does the same thing as using chrt to change the scheduling algorithm to the “real time” algorithm (SCHED_RR or Round Robin which is a little more friendly than FIFO) with a rather low priority. man 7 sched for more info.

I don’t know if iosched really helps any here so leave that out if desired. man ionice for more info.

(re)start the daemon:

/etc/init.d/shairport-sync stop ; /etc/init.d/shairport-sync start

Plug in to audio, connect your iphone/ipad, and that should be it.

With the task scheduler set to real-time, you should be able to run “stress -c 20” and see absolutely no problem hammering the CPU. You can probably even run “stress -c 20 -m 5” and won’t get any skipping when the CHIP runs out of memory unless you have synchronization turned on.


#2

I don’t know what’s wrong but unless I disable synchronization I get stuff like this:

Jan 14 05:19:14 chip shairport-sync[2749]: Error -- ALSA device in incorrect state (4) for play.
Jan 14 05:19:14 chip shairport-sync[2749]: Lost sync with source for 4 consecutive packets -- flushing and resyncing. Error: 2701.
Jan 14 05:19:14 chip shairport-sync[2749]: syncing to seqno 26637.
Jan 14 05:19:14 chip shairport-sync[2749]: Open Mixer
Jan 14 05:19:14 chip shairport-sync[2749]: Setting volume db to -3324.750000.
Jan 14 05:19:15 chip shairport-sync[2749]: Packet reception interval stats: mean, standard deviation and max for the last 2,500 packets in microseconds:     8281.1,    41593.6,  1867801.0.
Jan 14 05:19:21 chip shairport-sync[2749]: Error -- ALSA device in incorrect state (4) for play.
Jan 14 05:19:21 chip shairport-sync[2749]: Error -- ALSA device in incorrect state (4) for play.

Anyone have any idea what might be causing this? CPU usage is never over like 30%.


#3

Thanks for the tips about synchronization. I’ve been playing with Shairport on and off for a month with my PocketCHIP, and was getting very frustrated with the choppy audio after just a few seconds.

Disabling synchronization in /etc/shairport-sync.conf solved the usability issues.

In my use case it’s not a huge deal, but I’m still curious why synchronization causes it to fail so miserably. Also, has anyone else noticed wifi network connectivity issues while trying to play synchronized? When I’m SSH’d in from my other PC, it’s almost like clockwork…SSH hangs as soon as I start sending audio to the PocketCHIP. Before I found this post, I was almost ready to invest in a USB ethernet card to test wired connectivity with shairport, but for now I have music in the garage so additional testing is less of a priority. I may still get around to it if I run across a cheap nic somewhere.


#4

I tried but there comes this error:

> Broadcast message from systemd-journald@chip (Mon 2017-07-03 20:42:03 UTC):
> shairport-sync[1492]: Failed to find mixer element

> Message from syslogd@chip at Jul  3 20:42:03 ...
>  shairport-sync[1492]: Failed to find mixer element

Entries in my shairport-sync.conf:

alsa =
{
output_device = "default";
mixer_control_name = "Power Amplifier";
};

As user ‘chip’ i have only “Master” in alsamixer.
As user ‘root’ there are all Mixer controls like ‘Power Amplifier’ etc.

But my configuration doesn’t get this… - what am i doing wrong?


#5

Try using “hw:0” as your output device. That’s what works for my configuration.


#6

Thanks for the Tip with “hw:0” - This worked for me. :grinning:

Another question: i have a chip with wlan0 connected to my router, wlan1 as access point.
MPD / MPC is running beside Shairport.

Is there a way to configure which service handle first?
Or maybe stop the other (temporalily) if new input?


#7

Hi.
I use mpd and airplay on one machine.

  1. Install mpc on the same machine where mpd runs. mpc is a simple and light client for mpd.

  2. In /etc/init.d/shairport-sync locate:

     // Advanced parameters for controlling how a Shairport Sync runs
     sessioncontrol = 
     {
     //	run_this_before_play_begins = "/full/path/to/application and args"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
     //	run_this_after_play_ends = "/full/path/to/application and args"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
     //	wait_for_completion = "no"; // set to "yes" to get Shairport Sync to wait until the "run_this..." applications have terminated before continuing
     };
    

    and edit to add mpc commands, in my case:

     sessioncontrol = 
     {
     run_this_before_play_begins = "/usr/bin/mpc pause"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
     run_this_after_play_ends = "/usr/bin/mpc play"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
     wait_for_completion = "yes"; // set to "yes" to get Shairport Sync to wait until the "run_this..." applications have terminated before continuing
    };
    

That is:

  • uncomment these 3 lines
  • tell shairport to pause mpd before putting Airplay stream to Alsa
  • wait to complete and then play mpd after finished

This makes mpd paused when you play using Airplay and makes mpd play when you pause or disconnect Airplay streaming device (no matter if mpd was or was NOT playing before) - tested on iPad Pro 9.7" with iOS 10.

Better thing would be to:

  • capture current state of mpd before starting playing airplay and then resume to saved state
  • detect if mpd was playing stream or just a file and use mpc stop for stream, mpc pause for song

but I just installed shairport yesterday.


#8

Has anyone figured out how to get this to run on reboot. When I reboot I get the the error message below, but when I restart it manually it’s fine. To me, this suggests that some necessary systems service or other is not up-and running. Any thoughts?

sudo systemctl status shairport-sync
[sudo] password for chip:
● shairport-sync.service - ShairportSync AirTunes receiver
Loaded: loaded (/lib/systemd/system/shairport-sync.service; disabled)
Active: inactive (dead) since Thu 1970-01-01 00:43:56 UTC; 1min 50s ago
Docs: man:shairport-sync(7)
file:///usr/share/doc/shairport-sync/README.md.gz
https://github.com/mikebrady/shairport-sync
Process: 295 ExecStart=/usr/bin/shairport-sync --daemon $DAEMON_ARGS (code=exited, status=0/SUCCESS)
Main PID: 311 (code=exited, status=0/SUCCESS)

Jan 01 00:43:43 chip systemd[1]: Starting ShairportSync AirTunes receiver…
Jan 01 00:43:44 chip shairport-sync[311]: Successful Startup
Jan 01 00:43:45 chip systemd[1]: Started ShairportSync AirTunes receiver.
Jan 01 00:43:56 chip systemd[1]: Stopping ShairportSync AirTunes receiver…
Jan 01 00:43:56 chip systemd[1]: Stopped ShairportSync AirTunes receiver.


#9

The output shows the shairport-sync service is disabled. With systemctl enabled / disabled determines if a service is persistent across reboots. If “enabled” it will (should) automatically start on reboot. To enable run this command:

sudo systemctl enable shairport-sync

After the service is enabled the status should display the configuration change on the “Loaded:…” line. Output will looks as follows:

sudo systemctl status shairport-sync
[sudo] password for chip:
● shairport-sync.service - ShairportSync AirTunes receiver
Loaded: loaded (/lib/systemd/system/shairport-sync.service; enabled)
Active: inactive (dead) since Thu 1970-01-01 00:43:56 UTC; 1min 50s ago