{"id":301,"date":"2014-07-22T22:57:40","date_gmt":"2014-07-23T05:57:40","guid":{"rendered":"http:\/\/kaytat.com\/?page_id=301"},"modified":"2024-01-28T19:44:46","modified_gmt":"2024-01-29T03:44:46","slug":"simple-protocol-player","status":"publish","type":"page","link":"https:\/\/kaytat.com\/blog\/?page_id=301","title":{"rendered":"Simple Protocol Player"},"content":{"rendered":"<p><a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.kaytat.simpleprotocolplayer&amp;hl=en\">Play store link<\/a><\/p>\n<h1>Why?<\/h1>\n<p>I want to be able to watch movies and videos on the TV, but I want the audio to be heard only through headphones.<\/p>\n<p>And I had a few requirements:<\/p>\n<ol>\n<li>Wireless<\/li>\n<li>Broadcast<\/li>\n<li>Low latency<\/li>\n<\/ol>\n<h3>Wireless<\/h3>\n<p>One solution is to run a headphone extension cable from the TV.\u00a0\u00a0 But that gets unwieldy pretty quickly for distances greater than a few feet.<\/p>\n<h3>Broadcast<\/h3>\n<p>I want the audio to be heard by multiple people at the same time through each individual set of headphones.<\/p>\n<h3>Low-latency<\/h3>\n<p>The audio has to be rendered with the least amount of latency possible so that the video could be watchable.\u00a0 If the audio is delayed, then the dialog\/sound effects\/etc wouldn&#8217;t be in-sync with the video.<\/p>\n<h1>PulseAudio<\/h1>\n<p>Since my HTPC is Ubuntu 12.04 running XBMC, I figured I could reuse some existing OSS software to stream audio from Ubuntu to a mobile device.\u00a0 And since I have an Android phone, I figured I would start there.<\/p>\n<p>This project was really easy to implement because PulseAudio on Ubuntu already supports a TCP stream of uncompressed PCM audio.\u00a0 The only requirement is to add a few lines (below) to enable the module.<\/p>\n<p>The documentation for the module is at <a title=\"http:\/\/www.freedesktop.org\/wiki\/Software\/PulseAudio\/Documentation\/User\/Modules\/#index20h3\" href=\"http:\/\/www.freedesktop.org\/wiki\/Software\/PulseAudio\/Documentation\/User\/Modules\/#index20h3\">http:\/\/www.freedesktop.org\/wiki\/Software\/PulseAudio\/Documentation\/User\/Modules\/#index20h3<\/a><\/p>\n<p>And the Android app simply reads data from a socket and uses Android&#8217;s AudioTrack to render the audio.\u00a0 The app is based on the random music player SDK example.<\/p>\n<h1>It&#8217;s so glitchy<\/h1>\n<p>The challenge is to try to keep the video on the TV synced with the audio.\u00a0 And that means rendering the audio with the lowest latency possible.<\/p>\n<p>The very first versions of the app do not handle this well.\u00a0 Basically,\u00a0 when the app detects it&#8217;s falling behind, it simply starts dropping data left and right.\u00a0 This results in obvious glitches in audio.\u00a0 It sacrifices quality for latency because delayed audio while watching movies sucks.<\/p>\n<p>Improvements will be made.<\/p>\n<h1>Setting up PulseAudio<\/h1>\n<p>[Also check out the link to the module documentation above]<\/p>\n<p>There are only a couple of steps:<\/p>\n<ol>\n<li>Determine which source to stream<\/li>\n<li>Edit config files so with the proper parameters<\/li>\n<li>Restart PulseAudio<\/li>\n<\/ol>\n<p>I am running Ubuntu 12.04.<\/p>\n<h3>Determine which source to use<\/h3>\n<p>Open up a terminal in Ubuntu and type<\/p>\n<pre>pactl list sources short<\/pre>\n<p>This will spit out a bunch of text, but what you&#8217;re looking for is the &#8216;analog-stereo.monitor.&#8217;\u00a0 I have edited the output from my machine and highlighted important items in red.<\/p>\n<pre>0\u00a0\u00a0 \u00a0alsa_output.pci-0000_01_00.1.hdmi-stereo.monitor\u00a0\u00a0 \u00a0module-alsa-card.c\u00a0\u00a0 \u00a0s16le 2ch 44100Hz\u00a0\u00a0 \u00a0SUSPENDED\n<span style=\"color: #ff0000;\">1\u00a0\u00a0 \u00a0alsa_output.pci-0000_00_1b.0.analog-stereo.monitor<\/span>\u00a0\u00a0 \u00a0module-alsa-card.c\u00a0\u00a0 \u00a0s16le 2ch 44100Hz\u00a0\u00a0 \u00a0SUSPENDED\n2\u00a0\u00a0 \u00a0alsa_input.pci-0000_00_1b.0.analog-stereo\u00a0\u00a0 \u00a0module-alsa-card.c\u00a0\u00a0 \u00a0s16le 2ch 44100Hz\u00a0\u00a0 \u00a0SUSPENDED\n\n<\/pre>\n<p>Look for &#8220;analog-stereo.monitor&#8221; and take note of the index number on the left.\u00a0 In my case, it&#8217;s 1.<\/p>\n<h3>Edit config files<\/h3>\n<p>You will need to edit the config files to load this module with the specific parameters.\u00a0 To do so, type (you will need the sudo password)<\/p>\n<pre>gedit admin:\/\/\/etc\/pulse\/default.pa<\/pre>\n<p>Add the following line near the bottom, substituting your source index:<\/p>\n<pre>load-module module-simple-protocol-tcp source=1 record=true port=12345<\/pre>\n<p>I had problems with the default port of 4711 because it seems to be already in use and so I just choose 12345.<\/p>\n<p>For mono, you can use channels=1 and for a lower sampling rate rate=24000. \u00a0The app has been updated to include support for this in an attempt to reduce latency.<\/p>\n<p>If you are hearing static, try changing the audio format generated by pulse from 32bit little endian to 16bit little endian (<a href=\"https:\/\/github.com\/kaytat\/SimpleProtocolPlayer\/issues\/24\">link<\/a>).<\/p>\n<pre>load-module module-simple-protocol-tcp source=1 record=true port=12345 format=s16le<\/pre>\n<h3>Restart Pulse<\/h3>\n<p>Restart PulseAudio with the new configuration.<\/p>\n<pre>pulseaudio -k\n# The following might not be necessary because pulse will autospawn\npulseaudio --start<\/pre>\n<p>And that should be it.<\/p>\n<p>Start up the app, type in IP address\/port of the Ubuntu box and stream audio to your Android device.<\/p>\n<h1>Windows server<\/h1>\n<p>A corresponding Windows server has been published to github.\u00a0 Please see the following for more information: <a href=\"https:\/\/kaytat.com\/blog\/?p=332\">https:\/\/kaytat.com\/blog\/?p=332<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Play store link Why? I want to be able to watch movies and videos on the TV, but I want the audio to be heard only through headphones. And I had a few requirements: Wireless Broadcast Low latency Wireless One solution is to run a headphone extension cable from the TV.\u00a0\u00a0 But that gets unwieldy &#8230; <a title=\"Simple Protocol Player\" class=\"read-more\" href=\"https:\/\/kaytat.com\/blog\/?page_id=301\" aria-label=\"More on Simple Protocol Player\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-301","page","type-page","status-publish"],"_links":{"self":[{"href":"https:\/\/kaytat.com\/blog\/index.php?rest_route=\/wp\/v2\/pages\/301","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kaytat.com\/blog\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/kaytat.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/kaytat.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kaytat.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=301"}],"version-history":[{"count":22,"href":"https:\/\/kaytat.com\/blog\/index.php?rest_route=\/wp\/v2\/pages\/301\/revisions"}],"predecessor-version":[{"id":475,"href":"https:\/\/kaytat.com\/blog\/index.php?rest_route=\/wp\/v2\/pages\/301\/revisions\/475"}],"wp:attachment":[{"href":"https:\/\/kaytat.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=301"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}