{"id":772,"date":"2013-03-18T10:00:57","date_gmt":"2013-03-18T15:00:57","guid":{"rendered":"https:\/\/www.foell.org\/justin\/?p=772"},"modified":"2019-10-21T11:52:24","modified_gmt":"2019-10-21T16:52:24","slug":"raspberry-pulse","status":"publish","type":"post","link":"https:\/\/www.foell.org\/justin\/raspberry-pulse\/","title":{"rendered":"Raspberry Pulse: Raspberry Pi + PulseAudio + Shairport"},"content":{"rendered":"<p>I was given a <a title=\"Raspberry Pi\" href=\"http:\/\/www.raspberrypi.org\/\">Raspberry Pi<\/a> for my birthday last week, and I&#8217;ve already got it up and running, doing what I intended it to do: be an audio sink for iPhone and my laptop &#8211; which has terrible speakers.<\/p>\n<p>I knew it would be a PulseAudio sink for my laptop. There&#8217;s also neat piece of software called <a title=\"shairport on GitHub\" href=\"https:\/\/github.com\/albertz\/shairport\">shairport<\/a> that will act as an AirPlay sink &#8211; and people are using it on Raspberry Pi&#8217;s.<\/p>\n<p>By default, the common Linux Distribution &#8220;<a title=\"Raspbian\" href=\"http:\/\/www.raspbian.org\/\">Raspbian<\/a>&#8221; for this tiny computer uses ALSA for sound. This is fine for basic stuff, but I was reminded that when two things <em>ever<\/em> try to play sound at the same time, contention issues arise. It reminded me of a earlier day in Linux history, before the advent of <a title=\"PulseAudio\" href=\"http:\/\/pulseaudio.org\">PulseAudio<\/a> and the magic it imparts.<br \/>\n<!--more--><\/p>\n<p>I made it my mission to set up Pulse as the default audio handler and make sure shairport would still play nicely in this setting. I want to state that despite what I&#8217;ve read, the built-in mini-jack on my Raspberry Pi has been working fine (no USB sound needed). Also, many shairport write-ups have wifi configuration sections &#8211; but AirPlay has been working fine for me with the Raspberry Pi wired into the same router my iPhone connects to. No need for extra hardware, just some know-how. So far, it&#8217;s been a success, so I thought I&#8217;d share my configuration.<\/p>\n<p>I&#8217;ve used some conventions in this writeup:<\/p>\n<ul>\n<li><strong>BOLD<\/strong> text where I&#8217;ve added or changed something (a new line or configuration setting)<\/li>\n<li><strong>[&#8230;]<\/strong> where I&#8217;ve omitted the unchanged contents of a file<\/li>\n<li><code>commands<\/code> in code tags<\/li>\n<li>\n<pre>file contents<\/pre>\n<p>in pre tags<\/li>\n<li>In the case where commands are extraordinarily long or there are several sequential commands, I&#8217;ve used pre tags for those as well<\/li>\n<\/ul>\n<h2>Install &amp; Configure PulseAudio<\/h2>\n<p>I found there are a few &#8220;tricks&#8221; to getting Pulse to work the way I wanted. Some of it involved going against conventional wisdom and running Pulse in &#8220;system&#8221; mode. To me this isn&#8217;t an issue at all as the Raspberry Pi sits on my desk to provide audio service to anyone that&#8217;s legitimately connected to my network.<\/p>\n<p>Start by installing PulseAudio and its Zeroconf module:<\/p>\n<p><code>sudo apt-get install pulseaudio pulseaudio-module-zeroconf<\/code><\/p>\n<p>Set Pulse to run as a system daemon:<\/p>\n<p><code>sudo vi \/etc\/default\/pulseaudio<\/code><\/p>\n<pre>[...]\r\nPULSEAUDIO_SYSTEM_START=<strong>1<\/strong>\r\n[...]\r\nDISALLOW_MODULE_LOADING=<strong>0<\/strong><\/pre>\n<p>At this point you can turn on the PulseAudio system service:<\/p>\n<p><code>sudo \/etc\/init.d\/pulseaudio start<\/code><\/p>\n<p>You can test the sound by running:<\/p>\n<p><code>paplay \/usr\/share\/scratch\/Media\/Sounds\/Vocals\/Singer1.wav<\/code><\/p>\n<p>However, I was getting strange errors like<\/p>\n<pre>pa_context_connect() failed: Connection refused<\/pre>\n<p>even though Pulse was up-and-running. I think Pulse on my Raspberry Pi was getting confused because my desktop system also runs PulseAudio as well and some connection info was\u00a0transferred\u00a0in my SSH session. To convince Raspberry Pi&#8217;s Pulse to play locally, I set the PULSE_SERVER environment variable:<\/p>\n<p><code>sudo vi \/etc\/environment<\/code><\/p>\n<pre><strong>PULSE_SERVER=localhost<\/strong><\/pre>\n<p>Uncomment the following lines and change the resample method and resampling rate. The sample rate was needed to allow playback from my Ubuntu laptop, the resample method was needed to allow playback from iPhone.<\/p>\n<p><code>sudo vi \/etc\/pulse\/daemon.conf<\/code><\/p>\n<pre>[...]\r\nresample-method =\u00a0<strong>trivial<\/strong>\r\n[...]\r\ndefault-sample-rate =\u00a0<strong>48000<\/strong><\/pre>\n<p>Comment out the suspend-on-idle module to prevent all the clicks &amp; pops. Turn on anonymous network access and publish the configuration using zeroconf. Change &#8220;192.168.0.0&#8221; if your network uses a different numbering scheme.<\/p>\n<p>If we were running PulseAudio in user mode, these next changes would be the equivalent of running <code>paprefs<\/code> visiting the Network tab and checking:<\/p>\n<ul>\n<li>Enable network access to local sound devices\n<ul>\n<li>Allow other machines on the LAN to discover local sound devices<\/li>\n<li>Don&#8217;t require authentication<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><code>sudo vi \/etc\/pulse\/system.pa<\/code><\/p>\n<pre>[...]\r\n<strong>#<\/strong>load-module module-suspend-on-idle\r\n[...]\r\n<strong>load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0\/24 auth-anonymous=1\r\nload-module module-zeroconf-publish<\/strong><\/pre>\n<p>Move your \/etc\/asound.conf to \/etc\/asound.old:<br \/>\n<code>sudo mv \/etc\/asound.conf \/etc\/asound.old<\/code><br \/>\nThen create a new one with PulseAudio as the default:<br \/>\n<code>sudo vi \/etc\/asound.conf<\/code><\/p>\n<pre>pcm.pulse {\r\n    type pulse\r\n}\r\nctl.pulse {\r\n    type pulse\r\n}\r\npcm.!default {\r\n    type pulse\r\n}\r\nctl.!default {\r\n    type pulse\r\n}<\/pre>\n<p>Tell libao (shairport&#8217;s sound library) to use Pulse instead of ALSA directly:<br \/>\n<code>sudo vi \/etc\/libao.conf<\/code><\/p>\n<pre>default_driver=<strong>pulse<\/strong>\r\nquiet<\/pre>\n<h2>Install &amp; Configure shairport<\/h2>\n<p>This is basically a re-hashing of <a title=\"Turn a Raspberry Pi Into an AirPlay Receiver for Streaming Music in Your Living Room\" href=\"http:\/\/lifehacker.com\/5978594\/turn-a-raspberry-pi-into-an-airplay-receiver-for-streaming-music-in-your-living-room\">several<\/a> <a title=\"AirPi \u2013 AirPlay audio with Raspberry\" href=\"http:\/\/trouch.com\/2012\/08\/03\/airpi-airplay-audio-with-raspberry\/\">other<\/a> useful installs I found. I felt the need to include it here for completeness.<\/p>\n<p>Start by installing the necessary Git &amp; Perl build packages:<\/p>\n<pre>sudo apt-get install git libao-dev libssl-dev libcrypt-openssl-rsa-perl libio-socket-inet6-perl libwww-perl avahi-utils libmodule-build-perl<\/pre>\n<p>Unlike other shairport write-ups, I installed the Perl module &#8216;Net::SDP&#8217; (needed for iOS6 support) via CPAN instead of Git. Adding this library supposedly enables shairport to work with iOS6 devices, but my wife&#8217;s phone (which is iOS6) doesn&#8217;t work, however my iOS5 phone does. Anyway, it doesn&#8217;t hurt to install it:<\/p>\n<p><code>sudo cpan install Net::SDP<\/code><\/p>\n<p>Then clone, and build shairport from GitHub:<\/p>\n<pre>git clone https:\/\/github.com\/albertz\/shairport.git shairport\r\ncd shairport\r\nmake\r\nsudo make install\r\nsudo cp shairport.init.sample \/etc\/init.d\/shairport\r\nsudo chmod a+x \/etc\/init.d\/shairport\r\nsudo update-rc.d shairport defaults<\/pre>\n<p>I went an extra step and made the shairport service run as the pulse user, and to write the process ID file to the pulse-owned \/var\/run\/pulse directory:<\/p>\n<p><code>sudo vi \/etc\/init.d\/shairport<\/code><\/p>\n<pre>[...]\r\nNAME=<strong>AirPi<\/strong>\r\n<strong>USER=pulse<\/strong>\r\nDAEMON=\"\/usr\/local\/bin\/shairport.pl\"\r\nPIDFILE=\/var\/run\/<strong>pulse\/<\/strong>$NAME.pid\r\nDAEMON_ARGS=\"-w $PIDFILE -a $NAME\"\r\n\r\n[ -x $binary ] || exit 0\r\n\r\nRETVAL=0\r\n\r\nstart() {\r\n    echo -n \"Starting shairport: \"\r\n        start-stop-daemon --start --quiet --pidfile \"$PIDFILE\" \\\r\n                          <strong>--chuid $USER \\<\/strong>\r\n                          --exec \"$DAEMON\" -b --oknodo -- $DAEMON_ARGS\r\n        log_end_msg $?\r\n}\r\n[...]<\/pre>\n<p>You can now start shairport like any other service:<\/p>\n<p><code>sudo \/etc\/init.d\/shairport start<\/code><\/p>\n<p>Did I mention you should do some testing after each of these steps? I forgot to mention it, but you probably should just to make sure everything is heading in the right direction. If I&#8217;ve forgotten anything, let me know and I&#8217;ll post an update.<\/p>\n<div class='kindleWidget kindleLight' ><img decoding=\"async\" src=\"https:\/\/www.foell.org\/justin\/wp-content\/plugins\/send-to-kindle\/media\/white-15.png\" \/><span>Send to Kindle<\/span><\/div>","protected":false},"excerpt":{"rendered":"<p>I was given a Raspberry Pi for my birthday last week, and I&#8217;ve already got it up and running, doing what I intended it to do: be an audio sink for iPhone and my laptop &#8211; which has terrible speakers. I knew it would be a PulseAudio sink for my laptop. There&#8217;s also neat piece&hellip; <a href=\"https:\/\/www.foell.org\/justin\/raspberry-pulse\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1,8],"tags":[76,74,14,75,166,73,72],"class_list":["post-772","post","type-post","status-publish","format-standard","hentry","category-business","category-ubuntu","tag-airplay","tag-alsa","tag-git","tag-github","tag-linux","tag-pulseaudio","tag-raspberry-pi"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/posts\/772","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/comments?post=772"}],"version-history":[{"count":23,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/posts\/772\/revisions"}],"predecessor-version":[{"id":1167,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/posts\/772\/revisions\/1167"}],"wp:attachment":[{"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/media?parent=772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/categories?post=772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.foell.org\/justin\/wp-json\/wp\/v2\/tags?post=772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}