<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.6.7" />
<title>sc2mpd: helper for upmpdcli Songcast support</title>
<style type="text/css">
/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
/* Default font. */
body {
font-family: Georgia,serif;
}
/* Title font. */
h1, h2, h3, h4, h5, h6,
div.title, caption.title,
thead, p.table.header,
#toctitle,
#author, #revnumber, #revdate, #revremark,
#footer {
font-family: Arial,Helvetica,sans-serif;
}
body {
margin: 1em 5% 1em 5%;
}
a {
color: blue;
text-decoration: underline;
}
a:visited {
color: fuchsia;
}
em {
font-style: italic;
color: navy;
}
strong {
font-weight: bold;
color: #083194;
}
h1, h2, h3, h4, h5, h6 {
color: #527bbd;
margin-top: 1.2em;
margin-bottom: 0.5em;
line-height: 1.3;
}
h1, h2, h3 {
border-bottom: 2px solid silver;
}
h2 {
padding-top: 0.5em;
}
h3 {
float: left;
}
h3 + * {
clear: left;
}
h5 {
font-size: 1.0em;
}
div.sectionbody {
margin-left: 0;
}
hr {
border: 1px solid silver;
}
p {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
ul, ol, li > p {
margin-top: 0;
}
ul > li { color: #aaa; }
ul > li > * { color: black; }
pre {
padding: 0;
margin: 0;
}
#author {
color: #527bbd;
font-weight: bold;
font-size: 1.1em;
}
#email {
}
#revnumber, #revdate, #revremark {
}
#footer {
font-size: small;
border-top: 2px solid silver;
padding-top: 0.5em;
margin-top: 4.0em;
}
#footer-text {
float: left;
padding-bottom: 0.5em;
}
#footer-badges {
float: right;
padding-bottom: 0.5em;
}
#preamble {
margin-top: 1.5em;
margin-bottom: 1.5em;
}
div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.admonitionblock {
margin-top: 2.0em;
margin-bottom: 2.0em;
margin-right: 10%;
color: #606060;
}
div.content { /* Block element content. */
padding: 0;
}
/* Block element titles. */
div.title, caption.title {
color: #527bbd;
font-weight: bold;
text-align: left;
margin-top: 1.0em;
margin-bottom: 0.5em;
}
div.title + * {
margin-top: 0;
}
td div.title:first-child {
margin-top: 0.0em;
}
div.content div.title:first-child {
margin-top: 0.0em;
}
div.content + div.title {
margin-top: 0.0em;
}
div.sidebarblock > div.content {
background: #ffffee;
border: 1px solid #dddddd;
border-left: 4px solid #f0f0f0;
padding: 0.5em;
}
div.listingblock > div.content {
border: 1px solid #dddddd;
border-left: 5px solid #f0f0f0;
background: #f8f8f8;
padding: 0.5em;
}
div.quoteblock, div.verseblock {
padding-left: 1.0em;
margin-left: 1.0em;
margin-right: 10%;
border-left: 5px solid #f0f0f0;
color: #888;
}
div.quoteblock > div.attribution {
padding-top: 0.5em;
text-align: right;
}
div.verseblock > pre.content {
font-family: inherit;
font-size: inherit;
}
div.verseblock > div.attribution {
padding-top: 0.75em;
text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
text-align: left;
}
div.admonitionblock .icon {
vertical-align: top;
font-size: 1.1em;
font-weight: bold;
text-decoration: underline;
color: #527bbd;
padding-right: 0.5em;
}
div.admonitionblock td.content {
padding-left: 0.5em;
border-left: 3px solid #dddddd;
}
div.exampleblock > div.content {
border-left: 3px solid #dddddd;
padding-left: 0.5em;
}
div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }
dl {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
dt {
margin-top: 0.5em;
margin-bottom: 0;
font-style: normal;
color: navy;
}
dd > *:first-child {
margin-top: 0.1em;
}
ul, ol {
list-style-position: outside;
}
ol.arabic {
list-style-type: decimal;
}
ol.loweralpha {
list-style-type: lower-alpha;
}
ol.upperalpha {
list-style-type: upper-alpha;
}
ol.lowerroman {
list-style-type: lower-roman;
}
ol.upperroman {
list-style-type: upper-roman;
}
div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
tfoot {
font-weight: bold;
}
td > div.verse {
white-space: pre;
}
div.hdlist {
margin-top: 0.8em;
margin-bottom: 0.8em;
}
div.hdlist tr {
padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
font-weight: bold;
}
td.hdlist1 {
vertical-align: top;
font-style: normal;
padding-right: 0.8em;
color: navy;
}
td.hdlist2 {
vertical-align: top;
}
div.hdlist.compact tr {
margin: 0;
padding-bottom: 0;
}
.comment {
background: yellow;
}
.footnote, .footnoteref {
font-size: 0.8em;
}
span.footnote, span.footnoteref {
vertical-align: super;
}
#footnotes {
margin: 20px 0 20px 0;
padding: 7px 0 0 0;
}
#footnotes div.footnote {
margin: 0 0 5px 0;
}
#footnotes hr {
border: none;
border-top: 1px solid silver;
height: 1px;
text-align: left;
margin-left: 0;
width: 20%;
min-width: 100px;
}
div.colist td {
padding-right: 0.5em;
padding-bottom: 0.3em;
vertical-align: top;
}
div.colist td img {
margin-top: 0.3em;
}
@media print {
#footer-badges { display: none; }
}
#toc {
margin-bottom: 2.5em;
}
#toctitle {
color: #527bbd;
font-size: 1.1em;
font-weight: bold;
margin-top: 1.0em;
margin-bottom: 0.1em;
}
div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
margin-top: 0;
margin-bottom: 0;
}
div.toclevel2 {
margin-left: 2em;
font-size: 0.9em;
}
div.toclevel3 {
margin-left: 4em;
font-size: 0.9em;
}
div.toclevel4 {
margin-left: 6em;
font-size: 0.9em;
}
span.aqua { color: aqua; }
span.black { color: black; }
span.blue { color: blue; }
span.fuchsia { color: fuchsia; }
span.gray { color: gray; }
span.green { color: green; }
span.lime { color: lime; }
span.maroon { color: maroon; }
span.navy { color: navy; }
span.olive { color: olive; }
span.purple { color: purple; }
span.red { color: red; }
span.silver { color: silver; }
span.teal { color: teal; }
span.white { color: white; }
span.yellow { color: yellow; }
span.aqua-background { background: aqua; }
span.black-background { background: black; }
span.blue-background { background: blue; }
span.fuchsia-background { background: fuchsia; }
span.gray-background { background: gray; }
span.green-background { background: green; }
span.lime-background { background: lime; }
span.maroon-background { background: maroon; }
span.navy-background { background: navy; }
span.olive-background { background: olive; }
span.purple-background { background: purple; }
span.red-background { background: red; }
span.silver-background { background: silver; }
span.teal-background { background: teal; }
span.white-background { background: white; }
span.yellow-background { background: yellow; }
span.big { font-size: 2em; }
span.small { font-size: 0.6em; }
span.underline { text-decoration: underline; }
span.overline { text-decoration: overline; }
span.line-through { text-decoration: line-through; }
div.unbreakable { page-break-inside: avoid; }
/*
* xhtml11 specific
*
* */
tt {
font-family: "Courier New", Courier, monospace;
font-size: inherit;
color: navy;
}
div.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
div.tableblock > table {
border: 3px solid #527bbd;
}
thead, p.table.header {
font-weight: bold;
color: #527bbd;
}
p.table {
margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
border-style: none;
}
div.tableblock > table[frame="hsides"] {
border-left-style: none;
border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
border-top-style: none;
border-bottom-style: none;
}
/*
* html5 specific
*
* */
.monospaced {
font-family: "Courier New", Courier, monospace;
font-size: inherit;
color: navy;
}
table.tableblock {
margin-top: 1.0em;
margin-bottom: 1.5em;
}
thead, p.tableblock.header {
font-weight: bold;
color: #527bbd;
}
p.tableblock {
margin-top: 0;
}
table.tableblock {
border-width: 3px;
border-spacing: 0px;
border-style: solid;
border-color: #527bbd;
border-collapse: collapse;
}
th.tableblock, td.tableblock {
border-width: 1px;
padding: 4px;
border-style: solid;
border-color: #527bbd;
}
table.tableblock.frame-topbot {
border-left-style: hidden;
border-right-style: hidden;
}
table.tableblock.frame-sides {
border-top-style: hidden;
border-bottom-style: hidden;
}
table.tableblock.frame-none {
border-style: hidden;
}
th.tableblock.halign-left, td.tableblock.halign-left {
text-align: left;
}
th.tableblock.halign-center, td.tableblock.halign-center {
text-align: center;
}
th.tableblock.halign-right, td.tableblock.halign-right {
text-align: right;
}
th.tableblock.valign-top, td.tableblock.valign-top {
vertical-align: top;
}
th.tableblock.valign-middle, td.tableblock.valign-middle {
vertical-align: middle;
}
th.tableblock.valign-bottom, td.tableblock.valign-bottom {
vertical-align: bottom;
}
/*
* manpage specific
*
* */
body.manpage h1 {
padding-top: 0.5em;
padding-bottom: 0.5em;
border-top: 2px solid silver;
border-bottom: 2px solid silver;
}
body.manpage h2 {
border-style: none;
}
body.manpage div.sectionbody {
margin-left: 3em;
}
@media print {
body.manpage div#toc { display: none; }
}
</style>
<script type="text/javascript">
/*<![CDATA[*/
var asciidoc = { // Namespace.
/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////
/* Author: Mihai Bazon, September 2002
* http://students.infoiasi.ro/~mishoo
*
* Table Of Content generator
* Version: 0.4
*
* Feel free to use this script under the terms of the GNU General Public
* License, as long as you do not remove or alter this notice.
*/
/* modified by Troy D. Hanson, September 2006. License: GPL */
/* modified by Stuart Rackham, 2006, 2009. License: GPL */
// toclevels = 1..4.
toc: function (toclevels) {
function getText(el) {
var text = "";
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
text += i.data;
else if (i.firstChild != null)
text += getText(i);
}
return text;
}
function TocEntry(el, text, toclevel) {
this.element = el;
this.text = text;
this.toclevel = toclevel;
}
function tocEntries(el, toclevels) {
var result = new Array;
var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
// Function that scans the DOM tree for header elements (the DOM2
// nodeIterator API would be a better technique but not supported by all
// browsers).
var iterate = function (el) {
for (var i = el.firstChild; i != null; i = i.nextSibling) {
if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
var mo = re.exec(i.tagName);
if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
}
iterate(i);
}
}
}
iterate(el);
return result;
}
var toc = document.getElementById("toc");
if (!toc) {
return;
}
// Delete existing TOC entries in case we're reloading the TOC.
var tocEntriesToRemove = [];
var i;
for (i = 0; i < toc.childNodes.length; i++) {
var entry = toc.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div'
&& entry.getAttribute("class")
&& entry.getAttribute("class").match(/^toclevel/))
tocEntriesToRemove.push(entry);
}
for (i = 0; i < tocEntriesToRemove.length; i++) {
toc.removeChild(tocEntriesToRemove[i]);
}
// Rebuild TOC entries.
var entries = tocEntries(document.getElementById("content"), toclevels);
for (var i = 0; i < entries.length; ++i) {
var entry = entries[i];
if (entry.element.id == "")
entry.element.id = "_toc_" + i;
var a = document.createElement("a");
a.href = "#" + entry.element.id;
a.appendChild(document.createTextNode(entry.text));
var div = document.createElement("div");
div.appendChild(a);
div.className = "toclevel" + entry.toclevel;
toc.appendChild(div);
}
if (entries.length == 0)
toc.parentNode.removeChild(toc);
},
/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////
/* Based on footnote generation code from:
* http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
*/
footnotes: function () {
// Delete existing footnote entries in case we're reloading the footnodes.
var i;
var noteholder = document.getElementById("footnotes");
if (!noteholder) {
return;
}
var entriesToRemove = [];
for (i = 0; i < noteholder.childNodes.length; i++) {
var entry = noteholder.childNodes[i];
if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
entriesToRemove.push(entry);
}
for (i = 0; i < entriesToRemove.length; i++) {
noteholder.removeChild(entriesToRemove[i]);
}
// Rebuild footnote entries.
var cont = document.getElementById("content");
var spans = cont.getElementsByTagName("span");
var refs = {};
var n = 0;
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnote") {
n++;
var note = spans[i].getAttribute("data-note");
if (!note) {
// Use [\s\S] in place of . so multi-line matches work.
// Because JavaScript has no s (dotall) regex flag.
note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
spans[i].innerHTML =
"[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
spans[i].setAttribute("data-note", note);
}
noteholder.innerHTML +=
"<div class='footnote' id='_footnote_" + n + "'>" +
"<a href='#_footnoteref_" + n + "' title='Return to text'>" +
n + "</a>. " + note + "</div>";
var id =spans[i].getAttribute("id");
if (id != null) refs["#"+id] = n;
}
}
if (n == 0)
noteholder.parentNode.removeChild(noteholder);
else {
// Process footnoterefs.
for (i=0; i<spans.length; i++) {
if (spans[i].className == "footnoteref") {
var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
href = href.match(/#.*/)[0]; // Because IE return full URL.
n = refs[href];
spans[i].innerHTML =
"[<a href='#_footnote_" + n +
"' title='View footnote' class='footnote'>" + n + "</a>]";
}
}
}
},
install: function(toclevels) {
var timerId;
function reinstall() {
asciidoc.footnotes();
if (toclevels) {
asciidoc.toc(toclevels);
}
}
function reinstallAndRemoveTimer() {
clearInterval(timerId);
reinstall();
}
timerId = setInterval(reinstall, 500);
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
else
window.onload = reinstallAndRemoveTimer;
}
}
asciidoc.install();
/*]]>*/
</script>
</head>
<body class="article">
<div id="header">
<h1>sc2mpd: helper for upmpdcli Songcast support</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p>The <strong>sc2mpd</strong> auxiliary process implements part of Linn <strong>Songcast</strong> support
for the <strong>upmdcli</strong> UPnP MPD front-end. Specifically, it implements a
<strong>Songcast</strong> <em>Receiver</em> service, managed by <strong>upmpdcli</strong>.</p></div>
<div class="paragraph"><p><strong><em>This has mostly been tested with 16 bits sound but a recent change seems
to have fixed 24 bits sound, so this should be now usable for MACs. This
needs mpd 0.19 on the renderer. Still be a bit careful as this is quite new
and there is a risk of strange noises !</em></strong></p></div>
<div class="paragraph"><p><strong><em>Do not try 24 bits sound with MPD 0.18 !</em></strong> (or turn the volume very
low…). Using Songcast from a Mac (24 bits audio) needs <strong>mpd 0.19</strong>,
configured with <tt>--disable-audiofile</tt>.</p></div>
<div class="paragraph"><p>As Debian and Ubuntu tend to lag quite bit on MPD progresses, I have setup
<a href="downloads.html#mpd">backport repositories</a> for recent mpd versions
(currently 0.19.9), for Ubuntu, Debian i386/amd64 and Raspbian.</p></div>
<div class="paragraph"><p><strong>NEW: Debian packages for sc2mpd:</strong> as the procedure for building sc2mpd is
not completely obvious and automatic, I have also added <strong>sc2mpd</strong> packages
to the <strong>upmpdcli</strong> Debian repository. Packages exist for architectures i386,
amd64 and Raspberry Pi. You can follow the procedure on the
<a href="downloads.html">upmpdcli download page</a> to add the repository, then
just use the following to install sc2mpd:</p></div>
<div class="literalblock">
<div class="content">
<pre><tt>sudo apt-get install sc2mpd</tt></pre>
</div></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">For rebuilding from the source package: the installed binary has a
static link to the OpenHome libraries. This means that, in order to rebuild
from the source package, you need to follow the normal procedure to build
the OpenHome libs first (see the ohbuild.sh script further down). The build
tree should be located under /opt/openhome for the package rebuild to work.</td>
</tr></table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_what_is_songcast">What is Songcast</h2>
<div class="sectionbody">
<div class="paragraph"><p>Songcast is a protocol for transporting audio streams across the
network. This is independant from the UPnP framework which mostly deals
with URLs and audio files (usually, but not necessarily, compressed).</p></div>
<div class="paragraph"><p>The streams transported by Songcast are actual real-time audio data, which
can go straight to an audio card for playing.</p></div>
<div class="paragraph"><p>Controlling the streams on the renderer (connecting, starting, stopping) is
done through an UPnP service named OpenHome <em>Receiver</em>.</p></div>
<div class="paragraph"><p>The typical use of Songcast is to have an audio driver on a Windows or OS X
desktop capture and forward the audio stream to a remote Songcast device.</p></div>
<div class="paragraph"><p>Any application on the desktop will (be compelled to) transparently play to
the remote device, without need to know anything about Songcast.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_implementation_of_songcast_support_in_upmpdcli">Implementation of Songcast support in upmpdcli</h2>
<div class="sectionbody">
<div class="paragraph"><p><strong>upmpdcli</strong> implements the <em>Receiver</em> service, and uses an auxiliary process
(<strong>sc2mpd</strong>) for transporting the audio data. <strong>sc2mpd</strong> is a slight
modification of the sample program which comes with the Linn Songcast
open-source implementation, with the addition of an HTTP interface (based
on <em>libmicrohttpd</em>) to forward the data to <strong>mpd</strong>.</p></div>
<div class="paragraph"><p>Setting up a connection happens as follows:</p></div>
<div class="ulist"><ul>
<li>
<p>
If it finds an executable <strong>sc2mpd</strong> command in the PATH when starting up,
<strong>upmpdcli</strong> advertises a <em>Receiver</em> service.
</p>
</li>
<li>
<p>
The Songcast implementation from the desktop finds out about the
<em>Receiver</em> through the normal UPnP mechanisms and can be instructed to
use it. It then tells the <em>Receiver</em> in <strong>upmpdcli</strong> to start playing.
</p>
</li>
<li>
<p>
<strong>upmdpcli</strong> starts the <strong>sc2mpd</strong> process, which gets ready to receive data
through Songcast, and make it available through HTTP.
</p>
</li>
<li>
<p>
<strong>upmpdcli</strong> instructs <strong>mpd</strong> to play the URL for the <strong>sc2mpd</strong> output.
</p>
</li>
</ul></div>
<div class="paragraph"><p>There is currently a 10-12 S delay between the connection request and the
moment the audio starts playing. This is not normal, but I could not find
the reason for it, so it’s an unavoidable inconvenience at the moment.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_configuration">Configuration</h2>
<div class="sectionbody">
<div class="paragraph"><p>No configuration is necessary by default: if <strong>sc2mpd</strong> is present,
<strong>upmpdcli</strong> will advertise the Songcast capability, and any host with a
Songcast sender installed should be able to use it.</p></div>
<div class="paragraph"><p>However, you can set a number of values in the upmpdcli configuration file
(you <strong>must</strong> set the <strong>upmpdcli</strong> <tt>-c</tt> option for <strong>sc2mpd</strong> to see them, the
environment variable will not work):</p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
sclogfilename
</dt>
<dd>
<p>
Name of the file which will receive <strong>sc2mpd</strong> log messages. <tt>stderr</tt> by
default. This <em>can’t be</em> the same file used by <strong>upmpdcli</strong>.
</p>
</dd>
<dt class="hdlist1">
scloglevel
</dt>
<dd>
<p>
Log verbosity.
</p>
</dd>
<dt class="hdlist1">
schttpport
</dt>
<dd>
<p>
HTTP port used by <strong>mpd</strong> to connect to <strong>sc2mpd</strong>. 8888 by default. This must
be an available port on <tt>localhost</tt>, and it will only accept connections from
<tt>localhost</tt>.
</p>
</dd>
<dt class="hdlist1">
sc2mpd
</dt>
<dd>
<p>
Path for the <strong>sc2mpd</strong> executable file (e.g. <tt>/usr/local/bin/sc2mpd</tt>). Only
useful if <strong>sc2mpd</strong> was not installed to a location in the executable $PATH
set for the init scripts. Typically only <tt>/bin</tt> and <tt>/usr/bin</tt> are in
there.
</p>
</dd>
</dl></div>
</div>
</div>
<div class="sect1">
<h2 id="_building_sc2mpd">Building sc2mpd</h2>
<div class="sectionbody">
<div class="paragraph"><p>There are two parts in building <strong>sc2mpd</strong>:</p></div>
<div class="ulist"><ul>
<li>
<p>
Building the Openhome libraries
</p>
</li>
<li>
<p>
Building <strong>sc2mpd</strong> proper
</p>
</li>
</ul></div>
<div class="paragraph"><p>First clone the <strong>sc2mpd</strong> Github repository:
<a href="http://www.github.com/medoc92/sc2mpd">http://www.github.com/medoc92/sc2mpd</a>.</p></div>
<div class="paragraph"><p><strong>sc2mpd</strong> depends on the microhttpd library. Install the development and
runtime packages which are currently named <em>libmicrohttpd-dev</em> and
<em>libmicrohttpd10</em> on Debian-derived systems (use <em>libmicrohttpd</em> and
<em>libmicrohttpd-devel</em> for Fedora).</p></div>
<div class="paragraph"><p>Building the Openhome libraries is a bit of a black art, and the <strong>sc2mpd</strong>
source comes with an <em>ohbuild.sh</em> script which will try to clone the
Openhome Git repositories and build the libs:</p></div>
<div class="literalblock">
<div class="content">
<pre><tt>cd sc2mpd
mkdir /my/place/for/openhome
sh ohbuild.sh /my/place/for/openhome</tt></pre>
</div></div>
<div class="paragraph"><p>Miscellaneous error messages will be displayed during the build. Hope for
the best…</p></div>
<div class="paragraph"><p>When this is done, build <strong>sc2mpd</strong>, using the following commands inside the
<em>sc2mpd</em> directory:</p></div>
<div class="literalblock">
<div class="content">
<pre><tt>sh autogen.sh
./configure --prefix=/usr --with-openhome=/my/place/for/openhome
make
sudo make install</tt></pre>
</div></div>
<div class="paragraph"><p>The build uses static Openhome libraries, so you can move the executable to
another machine without needing the Openhome directory (don’t forget to
install the <em>libmicrohttpd</em> runtime though).</p></div>
<div class="paragraph"><p>After restarting <strong>upmpdcli</strong>, it should advertise the <em>Receiver</em> service and
appear in the Songcast Sender menus.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_miscellaneous_remarks">Miscellaneous remarks</h2>
<div class="sectionbody">
<div class="paragraph"><p>Songcast is probably best transported over a wired connection. If you are
doing this over WIFI and experiencing glitches, the wireless is the first
suspect.</p></div>
</div>
</div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated 2015-04-07 16:20:40 CEST
</div>
</div>
</body>
</html>