|
a/doc/scmulti.html |
|
b/doc/scmulti.html |
|
... |
|
... |
738 |
<body class="article">
|
738 |
<body class="article">
|
739 |
<div id="header">
|
739 |
<div id="header">
|
740 |
<h1>Managing multiroom audio with Linn Songcast and upmpdcli</h1>
|
740 |
<h1>Managing multiroom audio with Linn Songcast and upmpdcli</h1>
|
741 |
</div>
|
741 |
</div>
|
742 |
<div id="content">
|
742 |
<div id="content">
|
743 |
<div class="sect1">
|
743 |
<div id="preamble">
|
744 |
<h2 id="_what_is_linn_songcast">What is Linn Songcast</h2>
|
|
|
745 |
<div class="sectionbody">
|
744 |
<div class="sectionbody">
|
746 |
<div class="paragraph"><p><strong>Songcast</strong> is a protocol for transporting audio streams across the network,
|
745 |
<div class="paragraph"><p>General information about <strong>upmpdcli</strong> support for <strong>Songcast</strong> can be found
|
747 |
developped by <a href="http://oss.linn.co.uk/trac/wiki/Songcast">Linn</a> as a
|
746 |
<a href="sc2mpd.html">here</a>. This page explains how to set up a multiroom
|
748 |
series of open-source libraries and applications.</p></div>
|
747 |
synchronized audio system using <strong>upmpdcli</strong> and <strong>Songcast</strong>.</p></div>
|
749 |
<div class="paragraph"><p>There are two types of entities involved in the protocol:</p></div>
|
|
|
750 |
<div class="ulist"><ul>
|
|
|
751 |
<li>
|
|
|
752 |
<p>
|
|
|
753 |
A <strong>Songcast</strong> <em>Sender</em> generates an audio stream.
|
|
|
754 |
</p>
|
|
|
755 |
</li>
|
|
|
756 |
<li>
|
|
|
757 |
<p>
|
|
|
758 |
A <strong>Songcast</strong> <em>Receiver</em>, which typically runs on an OpenHome Renderer,
|
|
|
759 |
receives the stream and plays it.
|
|
|
760 |
</p>
|
|
|
761 |
</li>
|
|
|
762 |
</ul></div>
|
|
|
763 |
<div class="paragraph"><p>The streams transported by <strong>Songcast</strong> are actual real-time audio data, which
|
|
|
764 |
can go straight to an audio card for playing.</p></div>
|
|
|
765 |
<div class="paragraph"><p>Controlling the streams (connecting, starting, stopping) is
|
|
|
766 |
done through an UPnP service named OpenHome <em>Receiver</em>, which runs on an
|
|
|
767 |
UPnP Media Renderer implementing the OpenHome services.</p></div>
|
|
|
768 |
<div class="paragraph"><p>The typical use of <strong>Songcast</strong> is to have an audio driver on a Windows or OS X
|
|
|
769 |
desktop capture and forward the audio stream to a remote <strong>Songcast</strong> device
|
|
|
770 |
(this is the main purpose of the <strong>Songcast</strong> Mac and Windows applications,
|
|
|
771 |
apart from actually controlling the audio destination).</p></div>
|
|
|
772 |
<div class="paragraph"><p>Any application on the desktop will (be compelled to) transparently play to
|
|
|
773 |
the remote device, without need to know anything about <strong>Songcast</strong>.</p></div>
|
|
|
774 |
</div>
|
748 |
</div>
|
775 |
</div>
|
749 |
</div>
|
776 |
<div class="sect1">
|
750 |
<div class="sect1">
|
777 |
<h2 id="_multiple_receivers">Multiple Receivers</h2>
|
751 |
<h2 id="_multiple_receivers">Multiple Receivers</h2>
|
778 |
<div class="sectionbody">
|
752 |
<div class="sectionbody">
|
779 |
<div class="paragraph"><p>Multiple <em>Receiver</em> hosts can connect to the same <em>Sender</em>, so that they
|
753 |
<div class="paragraph"><p>Multiple <strong>Songcast</strong> <em>Receiver</em> hosts can connect to the same <em>Sender</em>, so
|
780 |
will all be playing the same audio.</p></div>
|
754 |
that they will all be playing the same audio.</p></div>
|
781 |
<div class="paragraph"><p>The Mac and Windows <strong>Songcast</strong> apps only let you connect the <em>Sender</em> to one
|
755 |
<div class="paragraph"><p>The Mac and Windows <strong>Songcast</strong> apps only let you activate one
|
782 |
Receiver though.</p></div>
|
756 |
<em>Receiver</em> though.</p></div>
|
783 |
<div class="paragraph"><p><strong>upmpdcli</strong> now includes a small application which can list the state of
|
757 |
<div class="paragraph"><p><strong>upmpdcli</strong> now includes a small application which can list the state of
|
784 |
the local <strong>Songcast</strong> Receivers, make a Receiver play from the same URI as
|
758 |
the local <strong>Songcast</strong> Receivers, make a Receiver play from the same URI as
|
785 |
another one (for building multiroom groups), or return a Media Renderer
|
759 |
another one (for building multiroom groups), or return a Media Renderer
|
786 |
from Receiver to normal operation.</p></div>
|
760 |
from Receiver to normal operation.</p></div>
|
787 |
<div class="paragraph"><p>The functions can be accessed either from the <strong>scctl</strong> command line utility,
|
761 |
<div class="paragraph"><p>The functions can be accessed either from the <strong>scctl</strong> command line utility,
|
|
... |
|
... |
789 |
or Mac PC, it would be inconvenient to have to access the Linux command
|
763 |
or Mac PC, it would be inconvenient to have to access the Linux command
|
790 |
line to control the multiroom groups).</p></div>
|
764 |
line to control the multiroom groups).</p></div>
|
791 |
<div class="paragraph"><p>This has only be tested with <strong>upmpdcli</strong> and its <a href="sc2mpd.html">sc2mpd</a>
|
765 |
<div class="paragraph"><p>This has only be tested with <strong>upmpdcli</strong> and its <a href="sc2mpd.html">sc2mpd</a>
|
792 |
<strong>Songcast</strong> auxiliary process as Receiver implementation, but I’d guess that
|
766 |
<strong>Songcast</strong> auxiliary process as Receiver implementation, but I’d guess that
|
793 |
there is a good chance it would work with others.</p></div>
|
767 |
there is a good chance it would work with others.</p></div>
|
794 |
<div class="paragraph"><p>This is very preliminary for now and there are a number of issues, I hope
|
768 |
</div>
|
795 |
to improve them, but for now, this is definitely an <em>early adopters</em> system:</p></div>
|
769 |
</div>
|
|
|
770 |
<div class="sect1">
|
|
|
771 |
<h2 id="_synchronisation_issues">Synchronisation issues</h2>
|
|
|
772 |
<div class="sectionbody">
|
|
|
773 |
<div class="paragraph"><p>The short version is: all sc2mpd instances must be configured to play
|
|
|
774 |
directly to Alsa. See the <a href="sc2mpd.html#Configuration">configuration
|
|
|
775 |
section</a>.</p></div>
|
|
|
776 |
<div class="paragraph"><p>Longer version: Songcast is a real-time audio stream. As the Sender and
|
|
|
777 |
Receiver sample clocks (the 44.1 or 48 KHz clocks) are independant, audio
|
|
|
778 |
reproduction on the two systems will slowly drift. If nothing is done,
|
|
|
779 |
after a time, the Receiver will have to skip samples or add a period of
|
|
|
780 |
silence (depending if its clock is slower or faster), which is quite
|
|
|
781 |
audible and ennoying, and will happen "from time to time", depending of how
|
|
|
782 |
much the clocks differ.</p></div>
|
|
|
783 |
<div class="paragraph"><p>The only way to control this is to adjust the rate of reproduction on the
|
|
|
784 |
Receiver, which can be done in two ways:</p></div>
|
796 |
<div class="ulist"><ul>
|
785 |
<div class="ulist"><ul>
|
797 |
<li>
|
786 |
<li>
|
798 |
<p>
|
787 |
<p>
|
799 |
The initial synchronisation when forming the group is very bad. To
|
788 |
Linn hardware uses timestamps embedded in the audio stream to adjust
|
800 |
resynchronize everything, stop or pause the playing on the PC (from the
|
789 |
their hardware sample clock.
|
801 |
player, e.g. Media Player, not from the Songcast utility), wait for the
|
|
|
802 |
audio to drain, and a few seconds more, then restart playing.
|
|
|
803 |
</p>
|
790 |
</p>
|
804 |
</li>
|
791 |
</li>
|
805 |
<li>
|
792 |
<li>
|
806 |
<p>
|
793 |
<p>
|
807 |
Receivers slowly drift out of sync, especially if they use different
|
794 |
sc2mpd in Alsa mode uses sample rate conversion to adjust the stream.
|
808 |
hardware. I intend to work on this, but it’s a difficult issue.
|
795 |
</p>
|
|
|
796 |
</li>
|
|
|
797 |
</ul></div>
|
|
|
798 |
<div class="paragraph"><p>This is not specific to Songcast of course, all real time audio network
|
|
|
799 |
transports have to do something similar.</p></div>
|
|
|
800 |
<div class="paragraph"><p>Independantly of the clock issue, all Receivers should use approximately
|
|
|
801 |
the same amount of buffering for the audio to be reasonably synchronous
|
|
|
802 |
(with no more shifts than moving around would produce anyway). This is
|
|
|
803 |
impossible to achieve when going through mpd, and the second reason why
|
|
|
804 |
sc2mpd must be set in Alsa mode for multiroom setups. In mpd mode, the
|
|
|
805 |
receivers can be out of sync by several seconds.</p></div>
|
|
|
806 |
</div>
|
|
|
807 |
</div>
|
|
|
808 |
<div class="sect1">
|
|
|
809 |
<h2 id="_setting_things_up">Setting things up</h2>
|
|
|
810 |
<div class="sectionbody">
|
|
|
811 |
<div class="ulist"><ul>
|
|
|
812 |
<li>
|
|
|
813 |
<p>
|
|
|
814 |
Install upmpdcli and sc2mpd on each of the <em>Receiver</em> systems. Edit
|
|
|
815 |
<tt>/etc/upmpdcli.conf</tt> to set:
|
|
|
816 |
</p>
|
|
|
817 |
<div class="ulist"><ul>
|
|
|
818 |
<li>
|
|
|
819 |
<p>
|
|
|
820 |
<tt>friendlyname</tt>, this is quite useful when managing several systems.
|
809 |
</p>
|
821 |
</p>
|
810 |
</li>
|
822 |
</li>
|
811 |
<li>
|
823 |
<li>
|
812 |
<p>
|
824 |
<p>
|
813 |
It’s quite easy to put the system in a confused state where nothing
|
825 |
<tt>scplaymethod</tt> = alsa
|
814 |
seems to work any more. Stopping all Receivers (with <strong>scctl</strong> or the Web
|
|
|
815 |
interface) and restarting the PC will normally get things back to
|
|
|
816 |
sanity, but it will sometimes be necessary to restart everything.
|
|
|
817 |
<strong>Always give the commands a little time to take effect</strong>. Especially,
|
|
|
818 |
it’s quite common that the audio will not begin to play for around
|
|
|
819 |
10 S after activation from the <strong>Songcast</strong> PC interface. Clicking on
|
|
|
820 |
stuff too early is the surest way to get into bad states, always give
|
|
|
821 |
10 S to the system when things seem to not be happening.
|
|
|
822 |
</p>
|
826 |
</p>
|
823 |
</li>
|
827 |
</li>
|
824 |
<li>
|
828 |
<li>
|
825 |
<p>
|
829 |
<p>
|
826 |
<em>The following problem seems to be gone from the latest <strong>Songcast</strong>
|
830 |
<tt>scalsadevice</tt>: use <tt>aplay -L</tt> to chose an appropriate device.
|
827 |
code</em> (which is used by the current <tt>ohbuild.sh</tt> script). Songcast can
|
|
|
828 |
be transported by either unicast or multicast IP. multicast is of
|
|
|
829 |
course much better for the network load, but I seem to have seen random
|
|
|
830 |
<strong>sc2mpd</strong> crashes with it. I am not sure of the cause (may be not linked
|
|
|
831 |
to multicast at all), but if you experience random <strong>sc2mpd</strong> crashes,
|
|
|
832 |
switch <strong>Songcast</strong> to unicast (in the PC Songcast app advanced
|
|
|
833 |
configuration panel. Unicast is the default).
|
|
|
834 |
</p>
|
831 |
</p>
|
835 |
</li>
|
832 |
</li>
|
836 |
</ul></div>
|
833 |
</ul></div>
|
837 |
</div>
|
|
|
838 |
</div>
|
|
|
839 |
<div class="sect1">
|
|
|
840 |
<h2 id="_setting_things_up">Setting things up</h2>
|
|
|
841 |
<div class="sectionbody">
|
|
|
842 |
<div class="paragraph"><p>The following seems to work for me:</p></div>
|
|
|
843 |
<div class="ulist"><ul>
|
|
|
844 |
<li>
|
|
|
845 |
<p>
|
|
|
846 |
Remove libupnpp and upmpdcli packages from the system to avoid confusion
|
|
|
847 |
</p>
|
|
|
848 |
</li>
|
834 |
</li>
|
849 |
<li>
|
835 |
<li>
|
850 |
<p>
|
836 |
<p>
|
851 |
Clone the libupnpp, upmpdcli and sc2mpd repositories from
|
837 |
Activate the web interface on one of the Receivers (or on any machine
|
852 |
<a href="https://github.com/">GitHub</a>
|
838 |
with upmpdcli installed actually). Edit <tt>/etc/default/scweb</tt> to
|
853 |
</p>
|
839 |
configure the interface (see comments in there) and start it with
|
854 |
</li>
|
840 |
<tt>/etc/init.d/scweb-service start</tt>.
|
855 |
<li>
|
|
|
856 |
<p>
|
|
|
857 |
Follow the usual procedure to build. This should just be the usual for
|
|
|
858 |
libupnpp and upmpdcli:
|
|
|
859 |
</p>
|
|
|
860 |
<div class="literalblock">
|
|
|
861 |
<div class="content">
|
|
|
862 |
<pre><tt>sh autogen.sh
|
|
|
863 |
./configure --prefix=/usr
|
|
|
864 |
make
|
|
|
865 |
sudo make install</tt></pre>
|
|
|
866 |
</div></div>
|
|
|
867 |
</li>
|
|
|
868 |
<li>
|
|
|
869 |
<p>
|
|
|
870 |
For sc2mpd, things are a small bit more complicated, see the <em>Building
|
|
|
871 |
sc2mpd</em> section in <a href="sc2mpd.html">this document</a>.
|
|
|
872 |
</p>
|
|
|
873 |
</li>
|
|
|
874 |
<li>
|
|
|
875 |
<p>
|
|
|
876 |
Repeat the above steps on all the machines which you want to be Receivers.
|
|
|
877 |
</p>
|
841 |
</p>
|
878 |
</li>
|
842 |
</li>
|
879 |
<li>
|
843 |
<li>
|
880 |
<p>
|
844 |
<p>
|
881 |
Activate a Receiver from the PC <strong>Songcast</strong> interface. Play something and
|
845 |
Activate a Receiver from the PC <strong>Songcast</strong> interface. Play something and
|
882 |
leave it playing.
|
846 |
leave it playing.
|
883 |
</p>
|
847 |
</p>
|
884 |
</li>
|
848 |
</li>
|
885 |
<li>
|
849 |
<li>
|
886 |
<p>
|
850 |
<p>
|
887 |
Use either <strong>scctl</strong> (<tt>scctl -h</tt> prints a simple help message), or the Web
|
851 |
Connect to the Web interface (host and port chosen above) with a
|
888 |
interface (see further) to associate other Receivers to the same Sender.
|
852 |
browser, and use it to list, activate, or disconnect the Receivers.
|
889 |
</p>
|
|
|
890 |
</li>
|
|
|
891 |
<li>
|
|
|
892 |
<p>
|
|
|
893 |
Stop or Pause the music. Wait 10 S, restart. <strong><em>Multiroom !</em></strong>
|
|
|
894 |
</p>
|
853 |
</p>
|
895 |
</li>
|
854 |
</li>
|
896 |
</ul></div>
|
855 |
</ul></div>
|
897 |
<div class="paragraph"><p>Once the slave Receivers are associated with the Sender, they should stay
|
856 |
<div class="paragraph"><p>Once the slave Receivers are associated with the Sender, they should stay
|
898 |
in this state until you change it. So you can stop/start Songcast on the
|
857 |
in this state until you change it. So you can stop/start Songcast on the
|
899 |
PC, and they will usually just follow.</p></div>
|
858 |
PC, and they will usually just follow.</p></div>
|
900 |
<div class="paragraph"><p>An "associated" Receiver is just one which plays from the same URI, it
|
859 |
<div class="paragraph"><p>An "associated" Receiver is just one which plays from the same URI, it
|
901 |
keeps no other relation to the "Master". Only one Receiver is a bit special
|
860 |
keeps no other relation to the "Master". Only one Receiver is a bit special
|
902 |
because it is the one known from the PC, but there is no specific reason to
|
861 |
because it is the one known from the PC, but there is no specific reason to
|
903 |
use it as Master, the Master is only used to get the URI. Avoid changing
|
862 |
use it as Master, the Master is only used to get the URI. Avoid changing
|
904 |
the state of the "PC"l Receiver from outside the PC <strong>Songcast</strong> interface,
|
863 |
the state of the "PC"'s Receiver from outside the PC <strong>Songcast</strong> interface,
|
905 |
this can only confuse things.</p></div>
|
864 |
this can only confuse things.</p></div>
|
906 |
<div class="paragraph"><p>Every time you change the group configuration, you need to resynchronize
|
|
|
907 |
the audio by pausing, waiting, restarting.</p></div>
|
|
|
908 |
<div class="paragraph"><p>I do know that the whole thing is not very solid, this is a prototype and I
|
|
|
909 |
hope to improve some of the issues in the future: constructive problem
|
|
|
910 |
reports are more than welcome, but no flaming (for now) please :)</p></div>
|
|
|
911 |
</div>
|
865 |
</div>
|
912 |
</div>
|
866 |
</div>
|
913 |
<div class="sect1">
|
867 |
<div class="sect1">
|
914 |
<h2 id="_controlling_the_songcast_groups_from_the_web_interface">Controlling the Songcast groups from the Web interface</h2>
|
868 |
<h2 id="_more_detail_about_the_web_interface">More detail about the Web interface</h2>
|
915 |
<div class="sectionbody">
|
869 |
<div class="sectionbody">
|
916 |
<div class="paragraph"><p>To avoid having to access the command line interface to control the
|
870 |
<div class="paragraph"><p>To avoid having to access the command line interface to control the
|
917 |
<strong>Songcast</strong> groups, <strong>upmpdcli</strong> comes with a small Web server which uses
|
871 |
<strong>Songcast</strong> groups, <strong>upmpdcli</strong> comes with a small Web server which uses
|
918 |
<strong>scctl</strong> to actually do the work. This is found inside the <tt>web/</tt>
|
872 |
<strong>scctl</strong> to actually do the work. This is found inside the <tt>web/</tt>
|
919 |
subdirectory inside the <strong>upmpdcli</strong> source tree.</p></div>
|
873 |
subdirectory inside the <strong>upmpdcli</strong> source tree.</p></div>
|
920 |
<div class="paragraph"><p>The server is based on the
|
874 |
<div class="paragraph"><p>The server is based on the
|
921 |
<a href="http://bottlepy.org/docs/dev/index.html">Bottle Python Web Framework</a>
|
875 |
<a href="http://bottlepy.org/docs/dev/index.html">Bottle Python Web Framework</a>
|
922 |
and it only depends on Python (version 2 and 3 are supported by <strong>Bottle</strong>,
|
876 |
and it only depends on Python (version 2 and 3 are supported by <strong>Bottle</strong>,
|
923 |
but the current app only works with Python 2).</p></div>
|
877 |
but the current app only works with Python 2).</p></div>
|
924 |
<div class="paragraph"><p>I’ll find ways to autostart the server in the future, but for now,
|
878 |
<div class="paragraph"><p>You can use the <tt>scweb-standalone.py</tt> script to manually start the
|
925 |
use the <tt>scweb-standalone.py</tt> script to manually start it:</p></div>
|
879 |
interface:</p></div>
|
926 |
<div class="literalblock">
|
880 |
<div class="literalblock">
|
927 |
<div class="content">
|
881 |
<div class="content">
|
928 |
<pre><tt>python2 ./scweb-standalone.py</tt></pre>
|
882 |
<pre><tt>python2 ./scweb-standalone.py</tt></pre>
|
929 |
</div></div>
|
883 |
</div></div>
|
930 |
<div class="paragraph"><p>This will start a server on localhost, on port 8777 which is good for
|
884 |
<div class="paragraph"><p>This will start a server on localhost, on port 8780 by default which is
|
931 |
testing, but not very useful. Use the -a 0.0.0.0 option to let the server
|
885 |
good for testing, but not very useful. Use the -a 0.0.0.0 option to let the
|
932 |
answer on all local addresses (or specify the address to use a specific
|
886 |
server answer on all local addresses (or specify the address to use a
|
933 |
interface):</p></div>
|
887 |
specific interface):</p></div>
|
934 |
<div class="literalblock">
|
888 |
<div class="literalblock">
|
935 |
<div class="content">
|
889 |
<div class="content">
|
936 |
<pre><tt>python2 ./scweb-standalone.py -a 0.0.0.0</tt></pre>
|
890 |
<pre><tt>python2 ./scweb-standalone.py -a 0.0.0.0</tt></pre>
|
937 |
</div></div>
|
891 |
</div></div>
|
938 |
<div class="paragraph"><p>-p can be used to specify a port.</p></div>
|
892 |
<div class="paragraph"><p>-p can be used to specify a port.</p></div>
|
|
... |
|
... |
942 |
</div>
|
896 |
</div>
|
943 |
</div>
|
897 |
</div>
|
944 |
<div id="footnotes"><hr /></div>
|
898 |
<div id="footnotes"><hr /></div>
|
945 |
<div id="footer">
|
899 |
<div id="footer">
|
946 |
<div id="footer-text">
|
900 |
<div id="footer-text">
|
947 |
Last updated 2015-04-29 14:50:56 CEST
|
901 |
Last updated 2015-05-06 10:18:31 CEST
|
948 |
</div>
|
902 |
</div>
|
949 |
</div>
|
903 |
</div>
|
950 |
</body>
|
904 |
</body>
|
951 |
</html>
|
905 |
</html>
|