<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>A Tasty Pixel » Blog &#187; Tutorial</title>
	<atom:link href="http://atastypixel.com/blog/tag/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://atastypixel.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 06 Feb 2012 15:08:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Automatically Track App Sale Referrals</title>
		<link>http://atastypixel.com/blog/automatically-track-app-sale-referrals/</link>
		<comments>http://atastypixel.com/blog/automatically-track-app-sale-referrals/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 11:40:56 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[App Store]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Stats]]></category>
		<category><![CDATA[Tracking]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/?p=2275</guid>
		<description><![CDATA[I recently came across an article on Mobile Orchard about connecting click-throughs to app sales, which is a rather ingenious idea using the affiliate program LinkShare to create trackable links. As Apple record and report orders that come via these referral links, you can actually see the number of sales (not just views of the [...]]]></description>
			<content:encoded><![CDATA[<p>I recently came across an article on Mobile Orchard about <a href="http://mobileorchard.com/connecting-click-throughs-to-app-sales/">connecting click-throughs to app sales</a>, which is a rather ingenious idea using the affiliate program <a href="http://linkshare.com">LinkShare</a> to create trackable links.  As Apple record and report orders that come via these referral links, you can actually see the number of sales (not just views of the App Store page) that resulted from follows of the link. Plus you get a 5% cut of the sale!</p>

<p>I&#8217;m doing some experiments with advertising my live looper app <a href="http://loopyapp.com">Loopy</a> lately, and want a way to track the success of various approaches.  It occurred to me that the totally freeform nature of the LinkShare &#8220;signature&#8221; field (which you can use to track traffic sources) lends itself to an even more flexible approach than that presented in the Mobile Orchard article.</p>

<p>Here&#8217;s a way to use that signature field to report the domain name of any referrer who links either to the app page, or to a download link (like, say, http://loopyapp.com/download).</p>

<p>This way, if, say, TUAW link to your app site, if someone clicks through then clicks the download link on your app site and buys, the resulting order will be reported as coming from TUAW.  If someone clicks through from your Facebook page, it&#8217;ll come up as coming from Facebook.  You can even modify the script further to report more precise details (like the path), if you like.</p>

<p>It assumes you&#8217;re using PHP, but the principle&#8217;s the same for any other language (BYO code, though ;-)).</p>

<h3>Step 1: Sign up to LinkShare</h3>

<p>First, if you haven&#8217;t already, <a href="http://click.linksynergy.com/fs-bin/click?id=/yGrgMJzFG0&amp;offerid=7097&amp;type=3&amp;subid=0">Sign up to the LinkShare program</a> &#8212; Once you&#8217;ve created a LinkShare account, join the <a href="http://cli.linksynergy.com/cli/publisher/programs/advertiser_detail.php?oid=146261&amp;mid=13508&amp;offerNid=1&amp;controls=1:1:3:0:0:1">Apple affiliate program</a> via the &#8220;Programs&#8221; tab.  After 3 days, you&#8217;ll get an email welcoming you to the program, and you&#8217;ll be good to go.</p>

<h3>Step 2: Create a product link</h3>

<p>Once you&#8217;re admitted to the program, open up the &#8220;My Advertisers&#8221; sub-tab from the LinkShare Programs tab, and open the &#8220;Link Maker Tool&#8221;. This lets you search for products, and create a link that will open up your app&#8217;s App Store page, and will be associated with your LinkShare account.</p>

<p><img style="display:block; margin-left:auto; margin-right:auto;" class="aligncenter" src="http://atastypixel.com/blog/wp-content/uploads/2011/09/Screen-Shot-2011-09-13-at-13.17.31.png" alt="Screen Shot 2011 09 13 at 13 17 31" title="Screen Shot 2011-09-13 at 13.17.31.png" border="0" width="600" height="475" /></p>

<h3>Step 3: Create a download redirection script</h3>

<p>Now we&#8217;re going to set up a script on your app site which will redirect the visitor to the URL you just created (which in turn, redirects straight to the App Store page).  It&#8217;ll add a &#8220;signature&#8221; parameter to the URL, which corresponds to the original referrer, so you can track where orders came from.</p>

<p>Create a file called &#8216;download.php&#8217; in the root of your app site, with the following content, with your LinkShare URL inserted where indicated:</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">// Replace the following URL with the LinkShare URL you created</span>
<span style="color: #000088;">$linkshare_url</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;http://click.linksynergy.com/fs-bin/stat?id=/yGrgMJzFG0&amp;offerid=146261&amp;type=3&amp;subid=0&amp;tmpid=1826&amp;RD_PARM1=http%253A<span style="color: #009933; font-weight: bold;">%252F</span><span style="color: #009933; font-weight: bold;">%252F</span>itunes.apple.com<span style="color: #009933; font-weight: bold;">%252F</span>app<span style="color: #009933; font-weight: bold;">%252F</span>loopy<span style="color: #009933; font-weight: bold;">%252F</span>id300257824<span style="color: #009933; font-weight: bold;">%253F</span>mt%253D8<span style="color: #009933; font-weight: bold;">%2526u</span>o%253D4%2526partnerId%253D30&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$referer</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'original_referer'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #000088;">$referer</span> <span style="color: #009900;">&#41;</span> <span style="color: #000088;">$referer</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;HTTP_REFERER&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$referer</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$signature</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;@https?://(?:www\.)?([^/]+?)(?:\.com)?/.*@&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$referer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$signature</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;@^(?:www\.)?(.+?)(?:\.com)?$@&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #006699; font-weight: bold;">$1</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;HTTP_HOST&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$signature</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;@[^a-zA-Z0-9]@&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$signature</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Location: &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$linkshare_url</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;&amp;u1=&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$signature</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>


<p>This script looks for the <em>original</em> referrer in a session variable (which we&#8217;ll set up in the next step), so that the domain of the site that links to your app site is used, not just your app site&#8217;s domain.  Then it creates a properly-formatted signature parameter (just alphanumeric), appends it to your LinkShare URL, and sends the viewer onwards.</p>

<p><em>Bonus points</em>: I prefer to get rid of the &#8216;php&#8217; extension to make the URL a bit cleaner.  Pop the following into your .htaccess file to access &#8216;download.php&#8217; as just &#8216;download&#8217;:</p>

<p><pre>
&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule . %{REQUEST_FILENAME}.php [L]
&lt;/IfModule&gt;
</pre></p>

<h3>Step 4: Remember the referrer</h3>

<p>Now, on the landing page script for your app site (or the site header), pop this in at the very start:</p>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;original_referer&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #000088;">$_SESSION</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;original_referer&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;HTTP_REFERER&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>


<p>This stores the original referrer URL in a session variable, to use when we actually link the viewer through to the App Store.</p>

<h3>Step 5: Test it</h3>

<p>To make sure everything&#8217;s working properly, open download.php again, and replace &#8220;header&#8221; at the bottom with &#8220;echo&#8221;, so that instead of redirecting the browser, we just print out the URL where we would be redirecting to.</p>

<p>Open your <em>appsite</em>/download URL, and make sure the URL ends with &#8220;&amp;u1=<em>appsite</em>&#8220;.  That&#8217;s for direct visitors.  Now, click through to your app site from another site, then click your &#8220;download&#8221; link.  You should now see the name of the original site you linked from as the &#8220;u1&#8243; parameter at the end of the URL.</p>

<p>Once you&#8217;re satisfied that you&#8217;re good to go, make sure you replace &#8220;echo&#8221; with &#8220;header&#8221; again.</p>

<h3>Step 6: Track</h3>

<p>Now that you&#8217;re ready to track referrals, you can give out your <em>http://yourappsite/download</em> URL as your app&#8217;s direct iTunes download link (to reviewers, in your press releases, etc).</p>

<p>You can view a report showing clicks and orders associated with each referrer on the LinkShare page &#8212; create an advanced report by clicking the &#8220;Advanced Reports&#8221; sub-tab, then select your desired date range (I use &#8220;Since Last Payment&#8221;, and under &#8220;Report Type&#8221;, select &#8220;Signature Activity&#8221;.  Hit &#8220;View Report&#8221;, and you&#8217;ll see your clicks and sales versus each referrer (&#8220;Member ID&#8221;, on the report).</p>

<p>Voila! Omnipotence achieved.</p>

<p><em>Addendum: This technique works for tracking referrers, but if you&#8217;re wanting to track the performance of ads (say, with AdMob), you&#8217;ll want to use your original LinkShare URL, with a custom &#8220;&amp;u1&#8243; signature parameter.  As ad platforms like AdMob link directly (and don&#8217;t, as far as I know, send a referer parameter), this script won&#8217;t pick up that it&#8217;s from your ad platform.</em></p>

<p><em>Addendum 2: LinkShare&#8217;s reports don&#8217;t distinguish between products, so if you&#8217;ve multiple apps, you might want to add a prefix to your signature parameter to tell &#8216;em apart. You could, say, replace that <code>header("Location: ".$linkshare_url."&amp;u1=".$signature);</code> line with something like <code>header("Location: ".$linkshare_url."&amp;u1=myapp".$signature);</code>.</em></p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=2275" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/automatically-track-app-sale-referrals/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing audio in time using Remote IO</title>
		<link>http://atastypixel.com/blog/playing-audio-in-time-using-remote-io/</link>
		<comments>http://atastypixel.com/blog/playing-audio-in-time-using-remote-io/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 20:46:38 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Loopy]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/playing-audio-in-time-using-remote-io/</guid>
		<description><![CDATA[I got an email today with a question about how to handle playback of audio in time, synchronised with a clock. My &#8216;musical notepad&#8217; app Loopy does this, and I thought I&#8217;d briefly explain how. Any app that makes use of the Remote IO audio unit framework (which is generally necessary for the kind of [...]]]></description>
			<content:encoded><![CDATA[<p>I got an email today with a question about how to handle playback of audio in time, synchronised with a clock.  My &#8216;musical notepad&#8217; app <a href="http://atastypixel.com/products/loopy">Loopy</a> does this, and I thought I&#8217;d briefly explain how.</p>

<p>Any app that makes use of the <a href="http://atastypixel.com/blog/using-remoteio-audio-unit/">Remote IO</a> audio unit framework (which is generally necessary for the kind of responsiveness required in a realtime musical app) provides audio to the hardware via a callback, which is periodically called when the hardware is ready for more.</p>

<p>The trick here is to provide the right chunk of samples in this callback for the current time position.</p>

<p>Loopy achieves this by:</p>

<h3>1. Keeping track of where in the timeline we are at the time the callback is called</h3>

<p>This is easily accomplished by keeping a record of the time the clock was started, subtracting this from the current time, and possibly performing a modulus with the tempo.  For example:</p>

<ul>
<li><code>(now - startTime) % timePerBar</code> gives the number of time units into the current bar (lets call it <code>timeIntoBar</code>).  </li>
<li><code>timeIntoBar / (timePerBar/beatsPerBar)</code> gives the number of beats into the current bar, and </li>
<li><code>timeIntoBar % (timePerBar/beatsPerBar)</code> gives us the time into the current beat.</li>
</ul>

<h3>2. Determining first if we should be playing audio at this time, and if so, which samples should be playing</h3>

<p>This involves first converting our time units from step 1 into samples.  For instance, you can convert microseconds to samples by dividing your time by <code>1000000/yourSampleRate</code>.  Aside: Of course, you can convert back from samples to time by multiplying instead of dividing.</p>

<p>Next, in the case of Loopy&#8217;s metronome, for example, we test for whether <code>samplesIntoBeat &lt; sound.lengthInSamples</code>.  If so, that means we should be playing audio.  If the sound was a loop, of course, we could be always playing.</p>

<p>The offset into the sound, in samples, is just samplesIntoBeat, in the case of the simple metronome.  In the case of a loop, you probably will be more interested in the number of samples into your loop &#8212; so instead of determining <code>(now - startTime) % timePerBar</code>, you may be interested in <code>(now - startTime) % timePerLoop</code>.</p>

<p>So, we want to return the requested number of samples starting from this offset into the sample array representing our audio.</p>

<h3>3. Returning smooth audio in time</h3>

<p>Note that if you just go returning any old set of samples, willy-nilly, you&#8217;re going to get nasty clicks and pops from discontinuities you get by not matching the start of your next buffer to the last one.</p>

<p>To ensure smoothness, Loopy keeps track of the offset of the last samples we returned, and just return the immediately following bunch of samples &#8212; unless we&#8217;re more than some threshold number of samples out of time, in which case we&#8217;ll suffer the pop in order to stay synchronised.  Actually, you can even generally avoid the pop if you smoothly blend buffers over a short time, removing any discontinuity.</p>

<h3>Final words</h3>

<p>The example above was a relatively trivial one, for a metronome sound.  For longer audio that may span multiple bars, you&#8217;ll probably want to perform a modulus by the length of your audio clip, possibly quantised to your time signature, and possibly using a per-loop time base, so you can start the loop at any point in your timeline and have it begin from the start.  This is something Loopy doesn&#8217;t currently do &#8212; Loopy will keep your loops synchronised so when you start a loop playing, it&#8217;ll play whatever part corresponds to the current timeline, not from the start of the loop. Maybe it&#8217;ll be an option in the future?</p>

<p>I wrote a little about the timing of loops in my <a href="http://atastypixel.com/blog/developing-loopy-part-2-implementation/">second article on Loopy&#8217;s implementation</a>.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1993" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/playing-audio-in-time-using-remote-io/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Making of Talkie: Multi-interface broadcasting and multicast</title>
		<link>http://atastypixel.com/blog/the-making-of-talkie-multi-interface-broadcasting-and-multicast/</link>
		<comments>http://atastypixel.com/blog/the-making-of-talkie-multi-interface-broadcasting-and-multicast/#comments</comments>
		<pubDate>Sun, 02 May 2010 12:52:38 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Broadcast]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Multicast]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Talkie]]></category>
		<category><![CDATA[Talkie-for-Mac]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/?p=1901</guid>
		<description><![CDATA[Part 2 Talkie is my newest product, a Walkie Talkie for iPhone and Mac. In Part 1 of this series, I wrote about basic broadcasting. This works fine with one network device, but it&#8217;s worth discussing how to send through all devices, so you can communicate with others connected via, say, Ethernet and WiFi simultaneously. [...]]]></description>
			<content:encoded><![CDATA[<h2>Part 2</h2>

<p><img src="http://atastypixel.com/media/images/products/talkie/icon-medium.jpg" width="183" height="148" alt="Talkie" style="float:right;" /><a href="http://atastypixel.com/products/talkie">Talkie</a> is my newest product, a Walkie Talkie for iPhone and Mac.</p>

<p>In <a href="http://atastypixel.com/blog/2010/03/11/the-making-of-talkie-broadcasting/">Part 1</a> of this series, I wrote about basic broadcasting.  This works fine with one network device, but it&#8217;s worth discussing how to send through all devices, so you can communicate with others connected via, say, Ethernet and WiFi simultaneously.</p>

<p>So, in Part 2 I&#8217;ll write about the approach I took in Talkie for broadcasting from all network devices (a.k.a. network interfaces), so that one can communicate with others connected via WiFi, Ethernet (on a Mac), and any other network devices simultaneously.</p>

<p><span id="more-1901"></span></p>

<h2>Bind them</h2>

<p>From Part 1, we have a <a href="http://atastypixel.com/blog/2010/03/11/the-making-of-talkie-broadcasting/">working broadcast mechanism</a>, but it will only send through the default interface &#8212; whatever you&#8217;re connected to the network via.  This is often sufficient, but if you have more than one device that you communicate through, like Ethernet and WiFi, then you will find that it only works with one.</p>

<p>In order to send through <em>all</em> your connected network interfaces, we need to create one socket for each interface, and <em>bind</em> the socket to its corresponding interface.</p>

<p>Here&#8217;s how:</p>

<p>First, we need to obtain a list of all network interfaces with <code>getifaddrs</code>.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#include &lt;ifaddrs.h&gt;</span>
...
<span style="color: #a61390;">struct</span> ifaddrs <span style="color: #002200;">*</span>addrs;
<span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> getifaddrs<span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addrs<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
  <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now, <code>addrs</code> is a list of interfaces that we can iterate over.  We now do so, picking out those devices that support broadcasting, and that aren&#8217;t loopback or point-to-point devices &#8212; loopback is an internal interface that is provided for your computer&#8217;s inner dialogue, and point-to-point (ppp) devices include dialup interfaces, 3G modems and the like.  We can exclude those guys.</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">const</span> <span style="color: #a61390;">struct</span> ifaddrs <span style="color: #002200;">*</span>cursor <span style="color: #002200;">=</span> addrs;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span> cursor <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">-</span>&gt;sa_family <span style="color: #002200;">==</span> AF_INET 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_LOOPBACK<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_POINTOPOINT<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_BROADCAST<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// We will do some stuff in here</span>
&nbsp;
  <span style="color: #002200;">&#125;</span>
  cursor <span style="color: #002200;">=</span> cursor<span style="color: #002200;">-</span>&gt;ifa_next;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now, for each interface that meets our criteria, we create a socket (which we covered in <a href="http://atastypixel.com/blog/2010/03/11/the-making-of-talkie-broadcasting/">Part 1</a>), then <code>bind</code> the socket to the network interface, to force transmission from that particular device.  Finally, as we did in Part 1, we enable broadcasting using <code>setsockopt</code> with <code>SO_BROADCAST</code>.</p>

<p>We want to store the sockets we create in an array, so we can access them later.  If we assume a maximum number of interfaces we will support (lets call it <code>kMaxSockets</code>), we can just use an array of that length.  So, putting it together:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kMaxSockets 16</span>
...
<span style="color: #a61390;">int</span> sock_fds<span style="color: #002200;">&#91;</span>kMaxSockets<span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">int</span> number_sockets <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
&nbsp;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span> cursor <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span> <span style="color: #002200;">&amp;&amp;</span> number_sockets &lt; kMaxSockets <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">-</span>&gt;sa_family <span style="color: #002200;">==</span> AF_INET 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_LOOPBACK<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_POINTOPOINT<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_BROADCAST<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Create socket</span>
    sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span> <span style="color: #002200;">=</span> socket<span style="color: #002200;">&#40;</span>AF_INET, SOCK_DGRAM, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span> <span style="color: #002200;">==</span> <span style="color: #002200;">-</span><span style="color: #2400d9;">1</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #11740a; font-style: italic;">// Error occurred</span>
      <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Create address from which we want to send, and bind it</span>
    <span style="color: #a61390;">struct</span> sockaddr_in addr;
    <span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    addr.sin_family <span style="color: #002200;">=</span> AF_INET;
    addr.sin_addr <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr_in <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span>&gt;sin_addr;
    addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span><span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> bind<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #11740a; font-style: italic;">// Error occurred</span>
      <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Enable broadcast</span>
    <span style="color: #a61390;">int</span> flag <span style="color: #002200;">=</span> <span style="color: #2400d9;">1</span>;
    result <span style="color: #002200;">=</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span>, SOL_SOCKET, SO_BROADCAST, <span style="color: #002200;">&amp;</span>flag, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>flag<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result <span style="color: #002200;">!=</span> <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
      <span style="color: #11740a; font-style: italic;">// Error occurred</span>
      <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
    <span style="color: #002200;">&#125;</span>
&nbsp;
    number_sockets<span style="color: #002200;">++</span>;
  <span style="color: #002200;">&#125;</span>
  cursor <span style="color: #002200;">=</span> cursor<span style="color: #002200;">-</span>&gt;ifa_next;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Finally, as before, we can setup a broadcast address to send to, and use <code>sendto</code> to broadcast, this time for each socket we created:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Initialise broadcast address</span>
<span style="color: #a61390;">struct</span> sockaddr_in addr;
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
addr.sin_family <span style="color: #002200;">=</span> AF_INET;
addr.sin_addr.s_addr <span style="color: #002200;">=</span> INADDR_BROADCAST;
addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span>kPortNumber<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Send through each interface</span>
<span style="color: #a61390;">int</span> i;
<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i&lt;number_sockets; i<span style="color: #002200;">++</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> sendto<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>i<span style="color: #002200;">&#93;</span>, data, length, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Error occurred</span>
    <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Note that the receive routine only needs a single socket, as we can receive on any interface when we use <code>INADDR_ANY</code>.  So, the receive routine needs no changes from the single-interface version we saw in Part 1.</p>

<p>Here&#8217;s the test app with the above modification: <a href="http://atastypixel.com/blog/wp-content/uploads/2010/05/broadcast_sample_all_interfaces.c" title="broadcast_sample_all_interfaces.c">broadcast_sample_all_interfaces.c</a></p>

<p>Again, compile by opening Terminal, and typing <code>make broadcast_sample_all_interfaces</code> or <code>cc -o broadcast_sample_all_interfaces broadcast_sample_all_interfaces.c</code>, then run it with <code>./broadcast_sample_all_interfaces "Message to send"</code> to send, or just <code>./broadcast_sample_all_interfaces</code> with no arguments to listen.</p>

<p>You may notice that multiple messages may be received: These have probably arrived via multiple network interfaces, virtual or otherwise.  It&#8217;s usually a good idea to check for duplicate messages, if this is an issue for program operation, by including a sequence number into the message &#8212; this will be discussed in Part 3.</p>

<p>It also may be a good idea to ignore your own messages, which may find their way back to you.  One way to accomplish this is to examine the source address (<code>addr</code> in the example above) and compare it with your local interface addresses (stored in <code>addrs</code>, above).  If you get a match, the message came from you, and you can drop it.</p>

<h2>Multicast</h2>

<p>Broadcast is fine when everyone on the local network is interested in what you have to say.  If this isn&#8217;t the case, though (lets face it, those Chuck Norris jokes aren&#8217;t for everyone), effort is wasted delivering to those who aren&#8217;t particularly interested.</p>

<p>Multicast works by using a specific address that one &#8216;subscribes&#8217; to in order to receive messages sent to that address.  So, it&#8217;s opt-in, allowing for better efficiency and one day, Internet-wide support for &#8216;to-many&#8217; communications.</p>

<p>Well, in theory.  Actually, multicast is still quite new, and for the most part &#8212; from what I understand &#8212; it behaves pretty much like broadcast on a local area network.  However, support can only increase, and given that many services already use it &#8212; Multicast DNS (mDNS), also known as Bonjour, being one of the most well-known examples &#8212; it seems a good idea to follow their lead.  Note also that IPv6, the successor to IP as we know it, and our saviour-to-be from our little Internet overpopulation problem (among other things), doesn&#8217;t even have broadcast provisions &#8212; the future is all multicast.</p>

<p>So, for these reasons, Talkie speaks multicast, instead of plain ol&#8217; broadcast.</p>

<p>Making use of multicast is relatively straightforward: To receive, you join a multicast group using <code>setsockopt</code> with <code>IP_ADD_MEMBERSHIP</code>, and the address of the multicast group, which is in the range 224.0.0.0-239.255.255.255 (for IPv4, of course).  To send, you just use <code>sendto</code> to transmit data to a multicast group address.</p>

<p>Using multicast on all network interfaces is just a little more complicated.  Here&#8217;s how it&#8217;s done with Talkie:</p>

<h3>Sending</h3>

<p>The send routine is very similar to the one above, using broadcast.  However, instead of using <code>bind</code> to specify the outgoing network interface and enabling broadcast, we assign a multicast interface using <code>setsockopt</code> with <code>IP_MULTICAST_IF</code>.  And, instead of transmitting to the broadcast address, we transmit to the multicast group address.</p>

<p>Again, we loop through all network interfaces.  This time, we pick out those that support multicast (<code>ifa_flags &amp; IFF_MULTICAST</code>):</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">const</span> <span style="color: #a61390;">struct</span> ifaddrs <span style="color: #002200;">*</span>cursor <span style="color: #002200;">=</span> addrs;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span> cursor <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">-</span>&gt;sa_family <span style="color: #002200;">==</span> AF_INET 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_LOOPBACK<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_POINTOPOINT<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_MULTICAST<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// We will do some stuff in here</span>
&nbsp;
  <span style="color: #002200;">&#125;</span>
  cursor <span style="color: #002200;">=</span> cursor<span style="color: #002200;">-</span>&gt;ifa_next;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>And, after creating the socket, we assign the interface:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span>, IPPROTO_IP, IP_MULTICAST_IF, <span style="color: #002200;">&amp;</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr_in <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span>&gt;sin_addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> in_addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">!=</span> <span style="color: #2400d9;">0</span>  <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
  <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Finally, as a nicety, we can disable loopback so that we don&#8217;t receive our own messages.  This isn&#8217;t 100% reliable, as certain network conditions can result in the local machine still receiving its outgoing messages, but it can improve efficiency:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">u_char loop <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>number_sockets<span style="color: #002200;">&#93;</span>, IPPROTO_IP, IP_MULTICAST_LOOP, <span style="color: #002200;">&amp;</span>loop, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>loop<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">!=</span> <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
  <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now that our sockets are set up, we can prepare to send to the multicast address:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kMulticastAddress &quot;224.0.0.123&quot;</span>
...
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
addr.sin_family <span style="color: #002200;">=</span> AF_INET;
addr.sin_addr.s_addr <span style="color: #002200;">=</span> inet_addr<span style="color: #002200;">&#40;</span>kMulticastAddress<span style="color: #002200;">&#41;</span>;
addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span>kPortNumber<span style="color: #002200;">&#41;</span>;</pre></div></div>


<p>And, as before, we send through each of the sockets we created:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">int</span> i;
<span style="color: #a61390;">for</span> <span style="color: #002200;">&#40;</span> i<span style="color: #002200;">=</span><span style="color: #2400d9;">0</span>; i&lt;number_sockets; i<span style="color: #002200;">++</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> sendto<span style="color: #002200;">&#40;</span>sock_fds<span style="color: #002200;">&#91;</span>i<span style="color: #002200;">&#93;</span>, data, length, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #11740a; font-style: italic;">// Error occurred</span>
    <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
  <span style="color: #002200;">&#125;</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<h3>Receiving</h3>

<p>Receiving messages from a multicast group on several network interfaces is a little more involved than doing so with broadcast: We need to subscribe to the multicast group from each network interface, explicitly.  If we were to just specify no device in particular, the system would choose a single interface for us, neglecting the others.</p>

<p>Joining the multicast group for each interface takes place in a now-familiar loop:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">const</span> <span style="color: #a61390;">struct</span> ifaddrs <span style="color: #002200;">*</span>cursor <span style="color: #002200;">=</span> addrs;
<span style="color: #a61390;">while</span> <span style="color: #002200;">&#40;</span> cursor <span style="color: #002200;">!=</span> <span style="color: #a61390;">NULL</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">-</span>&gt;sa_family <span style="color: #002200;">==</span> AF_INET 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_LOOPBACK<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span> <span style="color: #002200;">!</span><span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_POINTOPOINT<span style="color: #002200;">&#41;</span> 
          <span style="color: #002200;">&amp;&amp;</span>  <span style="color: #002200;">&#40;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_flags <span style="color: #002200;">&amp;</span> IFF_MULTICAST<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// We will do some stuff in here</span>
&nbsp;
  <span style="color: #002200;">&#125;</span>
  cursor <span style="color: #002200;">=</span> cursor<span style="color: #002200;">-</span>&gt;ifa_next;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>For each network device, we use the <code>IP_ADD_MEMBERSHIP</code> property with <code>setsockopt</code> to join &#8212; thereby subscribing to any messages sent to the multicast group address that reach that network interface.</p>

<p>First, we prepare the join request structure.  This provides the multicast group address, and the network interface:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">struct</span> ip_mreq multicast_req;
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>multicast_req, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>multicast_req<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
multicast_req.imr_multiaddr.s_addr <span style="color: #002200;">=</span> inet_addr<span style="color: #002200;">&#40;</span>kMulticastAddress<span style="color: #002200;">&#41;</span>;
multicast_req.imr_interface <span style="color: #002200;">=</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr_in <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>cursor<span style="color: #002200;">-</span>&gt;ifa_addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">-</span>&gt;sin_addr;</pre></div></div>


<p>Now we use this structure to join the group:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, <span style="color: #002200;">&amp;</span>multicast_req, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>multicast_req<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span> &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
  <span style="color: #a61390;">return</span> <span style="color: #2400d9;">0</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now, a caveat: While it&#8217;s perfectly legal to join the same multicast group on more than one network interface, and up to 20 memberships may be added to the same socket (see <a href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man4/ip.4.html">ip(4)</a>), for some reason, OS X spews &#8216;Address already in use&#8217; errors when we actually attempt it.</p>

<p>As a workaround, we can &#8216;drop&#8217; the membership first, which would normally have no effect, as we have not yet joined on this interface.  However, it enables us to perform the subsequent join, without dropping prior memberships.</p>

<p>So, before we perform the above <code>IP_ADD_MEMBERSHIP</code>, we do a <code>IP_DROP_MEMBERSHIP</code> first:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;">setsockopt<span style="color: #002200;">&#40;</span>sock_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, <span style="color: #002200;">&amp;</span>multicast_req, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>multicast_req<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;</pre></div></div>


<p>This sets up our socket to receive messages sent to the multicast group that are received via any interface.</p>

<p>Here it is all put together: <a href="http://atastypixel.com/blog/wp-content/uploads/2010/05/multicast_sample.c" title="multicast_sample.c">multicast_sample.c</a></p>

<p>Compile by opening Terminal, and typing <code>make multicast_sample</code> or <code>cc -o multicast_sample multicast_sample .c</code>, then run it with <code>./multicast_sample "Message to send"</code> to send, or just <code>./multicast_sample</code> with no arguments to listen.</p>

<h2>Still to come</h2>

<p>So, now we mostly have networking covered.  There&#8217;s one obvious omission, though, for an iPhone app: Bluetooth.  In Part 3, I&#8217;ll discuss how to perform communications over Bluetooth on the iPhone, in a way that&#8217;s compatible with the above generic network communications.  I&#8217;ll also talk about how to connect to other devices automatically, without user intervention &#8212; This is one particularly popular feature of Talkie that allows it to behave more like a real walkie-talkie.</p>

<p>I promised in Part 1 that I&#8217;d talk about packet formats.   We&#8217;ve covered a lot of ground in Part 2, however, so it shall be postponed to Part 3 &#8212; I&#8217;ll discuss how to ensure you get messages in the correct order by using sequence numbers, as well as providing for versioning and a few other bits and pieces.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1901" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/the-making-of-talkie-multi-interface-broadcasting-and-multicast/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Making of Talkie: Broadcasting</title>
		<link>http://atastypixel.com/blog/the-making-of-talkie-broadcasting/</link>
		<comments>http://atastypixel.com/blog/the-making-of-talkie-broadcasting/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 00:31:59 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Broadcast]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Talkie]]></category>
		<category><![CDATA[Talkie-for-Mac]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/?p=1854</guid>
		<description><![CDATA[Part 1 Talkie is my newest product, the result of a collaboration with a good designer friend, Tim Churchward, who did the user interface. Talkie is a little different from many of the other walkie talkie applications on the App Store (aside from the fact that much of it was written by me from our [...]]]></description>
			<content:encoded><![CDATA[<h2>Part 1</h2>

<p><img src="http://atastypixel.com/media/images/products/talkie/icon-medium.jpg" width="183" height="148" alt="Talkie" style="float:right;" /><a href="http://atastypixel.com/products/talkie">Talkie</a> is my newest product, the result of a collaboration with a good designer friend, Tim Churchward, who did the user interface.</p>

<p>Talkie is a little different from many of the other walkie talkie applications on the App Store (aside from the fact that much of it was written by me from our motorhome in <a href="http://michael.tyson.id.au/2010/01/26/down-time-in-hammamet/">Tunisia</a>!), and I thought I&#8217;d write a little about some of the tech underpinning the app, and some of the choices we made.   Along the way it may get a little tutorial-esque.</p>

<ul>
<li>This first part will introduce our initial motivations, and will talk about basic broadcast communications &#8212; the broadcast communications part may be very familiar to some, in which case it may be worth skipping to the next instalment.</li>
<li>In the <a href="http://atastypixel.com/blog/the-making-of-talkie-broadcasting/">second part</a>, I&#8217;ll continue the theme of networking, and will talk about what I ended up with for Talkie&#8217;s network code after addressing a couple of things, including switching to multicast.  </li>
<li>Finally, I&#8217;ll talk audio, dual platform development, and anything else I think of along the way (Actually, I&#8217;m aching to talk about one particular upcoming feature that had me jumping up and down when I first thought of it, but for now, mum&#8217;s the word on that one.)<span id="more-1854"></span>## Inspiration</li>
</ul>

<p><img src="http://atastypixel.com/media/images/products/talkie/screen-iphone.jpg" width="187" height="400" alt="Talkie screenshot" style="float:right;" />Right from the start, we wanted a product that brought back the fun walkie talkie experience we remember from our childhoods.  I&#8217;m talking colourful plastic, whip antennas and hiding in tree-houses.   This was mostly Tim&#8217;s domain, so I shall leave it to him to discuss how he found that in the user interface.</p>

<p>It also meant stepping back from traditional voice chat, with manual call initialisation and termination and simple one-to-one calls.  We wanted to mimic a radio, so that meant broadcasting as soon as you hit &#8220;Talk&#8221; &#8212; whereupon anyone in the neighbourhood would hear you.</p>

<p>Basically, we wanted to get as close to the real thing as was practical.  This included the addition of a prominent &#8216;morse code&#8217; button, of course, as well as a &#8216;squelch&#8217; control for &#8216;fine tuning&#8217;, which simulated the static of bad reception.</p>

<h2>Going dual-platform</h2>

<p><img src="http://atastypixel.com/media/images/products/talkie-for-mac/screenshot.jpg" width="232" height="190" alt="Talkie for Mac" style="float:left;" />Soon after I started developing Talkie, I realised I wanted a version for the Mac too.</p>

<p>Having Talkie both on the iPhone and on the Mac made sense, as we envisioned that a fairly common usage pattern would involve communication between a desktop and a handheld &#8212; say, someone wandering a campus with the iPhone in their pocket, staying in touch with friends at their desks.</p>

<p>We wanted to offer good value with Talkie, which is why we made Talkie for Mac available for free, when it&#8217;s used with Talkie for iPhone.</p>

<p>One of the very convenient things about developing for both iPhone and Mac is that the platforms are so similar, porting code is usually effortless.  So, going dual-platform was an easy decision.</p>

<h2>Finding common ground</h2>

<p>The result of all of this was the need to develop or find a communication protocol and codec that would work across the iPhone and the Mac, over both Bluetooth for iPhone-iPhone communication, and Wifi, for communication between iPhones and iPhones, and iPhones and Macs.</p>

<p>Version 3.0 of the iPhone SDK introduced the GameKit framework and as part of it, <code>GKVoiceChatService</code>, which provides two person voice chat straight out of the box.  Immediately it was clear that it wouldn&#8217;t serve our purposes &#8212; two person is not broadcast.  I was also keen to provide a Mac version of Talkie, and given that GameKit is iPhone-only, it was time to go off the beaten track.</p>

<p>There are a variety of voice communication protocols out there, with varying licences and varying complexity and feature sets.  I could&#8217;ve spent a week or two researching the options and evaluating them against our need for broadcast functionality, figuring out compilation and linking on the iPhone, resolving any compatibility or performance issues that arose, etc.</p>

<p>Or, I could spend a day putting together a few big building blocks provided by Apple (and the underlying Unix system) and have an easily tweakable working solution that precisely meets our needs and provides for future features.</p>

<p>It may not have been the most scientific approach, but the core of Talkie&#8217;s functionality was up and running on our home wi-fi network within about four hours, and it was working well.</p>

<h2>Getting from a to b (and c, d, e, and f)</h2>

<p>For those unfamiliar with the ins and outs of TCP/IP (the most common communication protocol &#8212; or rather, set of protocols &#8212; between computers, and the fundamental building block of the Internet), communication between computers can be connection-oriented, or connectionless.</p>

<p>Connection-oriented (a.k.a. &#8216;reliable&#8217;) communications are most common: They&#8217;re used when you open up a website, connect to iChat, or check your email.  This is the TCP part of TCP/IP, and includes niceties like built-in guaranteed delivery via retransmission (providing your cat hasn&#8217;t eaten your network cable, of course) and packet ordering so you receive the messages in the right order.  This only works between two computers, though &#8211; you and the server.</p>

<p>Connectionless (or &#8216;unreliable&#8217;) communications are much more open &#8212; it&#8217;s basically just a spray of messages: The data isn&#8217;t carefully ushered along, it&#8217;s just spat out and left to fend for itself.  This is UDP, and is commonly used for time-sensitive applications like audio communication, network gaming, etc., where once a packet arrives late, it&#8217;s useless: No point mucking about re-sending lost data that&#8217;s going to be past its use-by date by the time it arrives.  The other thing about UDP is that, because there&#8217;s no co-operation required from the destination (to acknowledge receipt, etc.), it lends itself to one-to-many communications &#8212; broadcast.</p>

<p>Just what we&#8217;re after.</p>

<p>So, we use connectionless communications (UDP) to send messages containing the audio, and anyone who receives them unpackages and plays the audio within.</p>

<p>The basic mechanics of this are fairly simple, once you get past the arguably cryptic C syntax.</p>

<p>Here&#8217;s how it works.</p>

<h3>Sending</h3>

<p>On the transmission end, on startup, you create a socket using the <code>socket</code> call:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#include &lt;sys/socket.h&gt;</span>
<span style="color: #6e371a;">#include &lt;netinet/in.h&gt;</span>
<span style="color: #6e371a;">#include &lt;arpa/inet.h&gt;</span>
...
<span style="color: #a61390;">int</span> sock_fd <span style="color: #002200;">=</span> socket<span style="color: #002200;">&#40;</span>AF_INET, SOCK_DGRAM, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> sock_fd &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>The socket, identified by <code>sock_fd</code>, will be created using the IPv4 domain (<code>AF_INET</code>), a &#8216;datagram&#8217; type (<code>SOCK_DFRAM</code>: that&#8217;s connectionless communication &#8212; if we wanted connection-oriented, we could put in <code>SOCK_STREAM</code> here instead), using protocol 0, which is IP.</p>

<p>Then, we enable broadcasting:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">int</span> flag <span style="color: #002200;">=</span> <span style="color: #2400d9;">1</span>;
<span style="color: #a61390;">int</span> result <span style="color: #002200;">=</span> setsockopt<span style="color: #002200;">&#40;</span>sock_fd, SOL_SOCKET, SO_BROADCAST, <span style="color: #002200;">&amp;</span>flag, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>flag<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>That is, we set the <code>SO_BROADCAST</code> option at the <code>SOL_SOCKET</code> level to 1 (via the <code>flag</code> variable, which we pass in as a pointer), thereby requesting permission from the operating system kernel to broadcast.</p>

<p>Now we have the carrier pigeon coop at our disposal, we can start dispatching pigeons.  First, we fill out the address:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kPortNumber 1234</span>
...
<span style="color: #a61390;">struct</span> sockaddr_in addr;
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
addr.sin_family <span style="color: #002200;">=</span> AF_INET;
addr.sin_addr.s_addr <span style="color: #002200;">=</span> INADDR_BROADCAST;
addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span>kPortNumber<span style="color: #002200;">&#41;</span>;</pre></div></div>


<p>(Note, <code>htons</code> converts <code>kPortNumber</code> into a format that can be understood by any computer, regardless of the way it represents numbers internally.)</p>

<p>Now, send:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #400080;">NSData</span> <span style="color: #002200;">*</span>dataToSend;
result <span style="color: #002200;">=</span> sendto<span style="color: #002200;">&#40;</span>sock_fd, <span style="color: #002200;">&#91;</span>data bytes<span style="color: #002200;">&#93;</span>, <span style="color: #002200;">&#91;</span>data length<span style="color: #002200;">&#93;</span>, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<h3>Receiving</h3>

<p>That takes care of outgoing messages.  To receive them, we want another socket:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">int</span> sock_fd <span style="color: #002200;">=</span> socket<span style="color: #002200;">&#40;</span>AF_INET, SOCK_DGRAM, <span style="color: #2400d9;">0</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> sock_fd &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Now we specify where we want to receive messages from, by &#8216;binding&#8217; the socket:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">struct</span> sockaddr_in addr;
<span style="color: #a61390;">memset</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #2400d9;">0</span>, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
addr.sin_family <span style="color: #002200;">=</span> AF_INET;
addr.sin_addr.s_addr <span style="color: #002200;">=</span> INADDR_ANY;
addr.sin_port <span style="color: #002200;">=</span> htons<span style="color: #002200;">&#40;</span>kPortNumber<span style="color: #002200;">&#41;</span>;
result <span style="color: #002200;">=</span> bind<span style="color: #002200;">&#40;</span>sock_fd, <span style="color: #002200;">&#40;</span><span style="color: #a61390;">struct</span> sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> result &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
  <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>And we pass a buffer to <code>recvfrom</code> to fill up with tasty morsels of data:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kBufferSize 1024</span>
...
<span style="color: #a61390;">char</span> buffer<span style="color: #002200;">&#91;</span>kBufferSize<span style="color: #002200;">&#93;</span>;
<span style="color: #a61390;">int</span> addr_len <span style="color: #002200;">=</span> <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>addr<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">int</span> bytes_received <span style="color: #002200;">=</span> recvfrom<span style="color: #002200;">&#40;</span>sock_fd, buffer, kBufferSize, <span style="color: #2400d9;">0</span>, <span style="color: #002200;">&#40;</span>struck sockaddr<span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span><span style="color: #002200;">&amp;</span>addr, <span style="color: #002200;">&amp;</span>addr_len<span style="color: #002200;">&#41;</span>;
<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span> bytes_received &lt; <span style="color: #2400d9;">0</span> <span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
   <span style="color: #11740a; font-style: italic;">// Error occurred</span>
<span style="color: #002200;">&#125;</span></pre></div></div>


<p>Voila, we have <code>bytes_received</code> bytes sitting in <code>buffer</code> for us to do something with.  Note also that <code>addr</code> now also contains the address of the sender.  Now we can loop and continue to receive data as it comes in, passing the data off to some other part of the application to deal with.</p>

<p>We can put it all together into a simple test app: <a href="http://atastypixel.com/blog/wp-content/uploads/2010/03/broadcast_sample.c" title="broadcast_sample.c">broadcast_sample.c</a></p>

<p>Compile it by opening up Terminal, and typing <code>make broadcast_sample</code> (or <code>cc -o broadcast_sample broadcast_sample.c</code>, if you like), then run it with <code>./broadcast_sample "Message to send"</code>, or just <code>./broadcast_sample</code> to listen.</p>

<p><pre>
$ ./broadcast_sample 
Listening...
Hello world!
</pre></p>

<p><pre>
$ ./broadcast_sample 'Hello world!'
"Hello world!" transmitted.
</pre></p>

<h2>Coming next</h2>

<p>This will work happily between computers with just one network interface. But, if you have more than one (say, wireless, and an Ethernet connection too), you&#8217;ll notice that it will only communicate through one of the interfaces.  That&#8217;s because just the default interface is used.  You have to explicitly attend to each interface, to broadcast out of each one, and listen on each one.</p>

<p>In the <a href="http://atastypixel.com/blog/the-making-of-talkie-broadcasting/">next part of this series</a>, I&#8217;ll write about how I addressed that, and about multicast, which is used in things like Bonjour (MDNS).  I&#8217;ll also write about designing packet formats.</p>

<p>Thanks for reading!</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1854" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/the-making-of-talkie-broadcasting/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using RemoteIO audio unit</title>
		<link>http://atastypixel.com/blog/using-remoteio-audio-unit/</link>
		<comments>http://atastypixel.com/blog/using-remoteio-audio-unit/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 14:36:31 +0000</pubDate>
		<dc:creator>Michael Tyson</dc:creator>
				<category><![CDATA[Geekspeak]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://atastypixel.com/blog/2008/10/27/using-remoteio-audio-unit/</guid>
		<description><![CDATA[I&#8217;ve had nasty old time trying to get some audio stuff going on the iPhone, no thanks to Apple&#8217;s lack of documentation. If you&#8217;re an iPhone developer interested in getting RemoteIO/IO Remote/whatever it&#8217;s called working on the iPhone&#8230; Do I have good news for you. Read on. Drop me a line if you find this [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had nasty old time trying to get some audio stuff going on the iPhone, no thanks to Apple&#8217;s lack of documentation. If you&#8217;re an iPhone developer interested in getting RemoteIO/IO Remote/whatever it&#8217;s called working on the iPhone&#8230; Do I have good news for you.  Read on.</p>

<p>Drop me a line if you find this helpful.</p>

<p><span id="more-1003"></span></p>

<div style="border: 1px solid #aaa; border-radius: 20px; -moz-border-radius: 20px; -webkit-border-radius: 20px; padding: 10px; margin: 30px;">
<h2>TPAudioController iOS engine now available</h2>

<img src="http://atastypixel.com/blog/wp-content/uploads/2011/12/icon-medium.jpg" alt="Icon medium" title="icon-medium.jpg" border="0" width="183" height="147" style="float:right; margin-bottom: 100px;" class="alignright" />

<p style="font-weight: bold;">If you&#8217;d rather not worry about this stuff, I&#8217;ve released <a href="http://atastypixel.com/code/TPAudioController">TPAudioController</a>, the iOS audio engine library that takes all the work out of creating an audio app.</p>
<p>TPAudioController is a flexible, easy-to-use and complete audio engine for iOS, built upon Core Audio. It handles all setup and management of the low-level Remote IO audio unit system, with support for capturing input via the microphone, automatic mixing of multiple audio signals with per-channel volume and pan controls, and capturing audio system output for session recording.</p>
<p><a href="http://atastypixel.com/code/TPAudioController/">Read more, and download the sample app or evaluation framework here</a>.</p>
</div>

<p><strong>Update: Thanks to <a href="http://tinyco.de">Joel Reymont</a>, we now have an <a href="http://tinyco.de/2009/02/12/solution-for-crashifclientprovidedbogusaudiobufferlist-in-iphone-simulator.html">explanation</a> for the &#8220;CrashIfClientProvidedBogusAudioBufferList&#8221; iPhone simulator bug: The simulator doesn&#8217;t like mono audio. Thanks, Joel!</strong></p>

<p><strong>Update: Happily, Apple have now created some <a href="http://developer.apple.com/library/ios/#documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/Introduction/Introduction.html%23//apple_ref/doc/uid/TP40009492-CH1-SW1">excellent documentation on Remote IO</a>, with some good <a href="http://developer.apple.com/library/ios/#samplecode/aurioTouch/Introduction/Intro.html%23//apple_ref/doc/uid/DTS40007770">sample projects</a>.  I recommend using that as a resource, now that it&#8217;s there, as that will continue to be updated.</strong></p>

<p><strong>Update: Tom Zicarelli has created a very extensive <a href="http://zerokidz.com/audiograph/Home.html">sample app that demonstrates the use of AUGraph</a>, with all sorts of goodies.</strong></p>

<p>So, we need to obtain an instance of the RemoteIO audio unit, configure it, and hook it up to a recording callback, which is used to notify you that there is data ready to be grabbed, and where you pull the data from the audio unit.</p>

<p><br /></p>

<h3>Overview</h3>

<ol>
  <li>Identify the audio component (kAudioUnitType_Output/ kAudioUnitSubType_RemoteIO/ kAudioUnitManufacturerApple)</li>

  <li>Use AudioComponentFindNext(NULL, &amp;descriptionOfAudioComponent) to obtain the AudioComponent, which is like the factory with which you obtain the audio unit<br /></li>

  <li>Use AudioComponentInstanceNew(ourComponent, &amp;audioUnit) to make an instance of the audio unit<br /></li>

  <li>Enable IO for recording and possibly playback with AudioUnitSetProperty<br /></li>

  <li>Describe the audio format in an AudioStreamBasicDescription structure, and apply the format using AudioUnitSetProperty<br /></li>

  <li>Provide a callback for recording, and possibly playback, again using AudioUnitSetProperty<br /></li>

  <li>Allocate some buffers<br /></li>

  <li>Initialise the audio unit<br /></li>

  <li>Start the audio unit<br /></li>

  <li>Rejoice<br /></li>
</ol>

<p>Here&#8217;s my code: I&#8217;m using both recording and playback. Use what applies to you!</p>

<h3>Initialisation</h3>

<p>Initialisation looks like this. We have a member variable of type AudioComponentInstance which will contain our audio unit.</p>

<p>The audio format described below uses SInt16 for samples (i.e. signed, 16 bits per sample)</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #6e371a;">#define kOutputBus 0</span>
<span style="color: #6e371a;">#define kInputBus 1</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// ...</span>
&nbsp;
&nbsp;
OSStatus status;
AudioComponentInstance audioUnit;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Describe audio component</span>
AudioComponentDescription desc;
desc.componentType <span style="color: #002200;">=</span> kAudioUnitType_Output;
desc.componentSubType <span style="color: #002200;">=</span> kAudioUnitSubType_RemoteIO;
desc.componentFlags <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
desc.componentFlagsMask <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
desc.componentManufacturer <span style="color: #002200;">=</span> kAudioUnitManufacturer_Apple;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Get component</span>
AudioComponent inputComponent <span style="color: #002200;">=</span> AudioComponentFindNext<span style="color: #002200;">&#40;</span><span style="color: #a61390;">NULL</span>, <span style="color: #002200;">&amp;</span>desc<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Get audio units</span>
status <span style="color: #002200;">=</span> AudioComponentInstanceNew<span style="color: #002200;">&#40;</span>inputComponent, <span style="color: #002200;">&amp;</span>audioUnit<span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Enable IO for recording</span>
UInt32 flag <span style="color: #002200;">=</span> <span style="color: #2400d9;">1</span>;
status <span style="color: #002200;">=</span> AudioUnitSetProperty<span style="color: #002200;">&#40;</span>audioUnit, 
                              kAudioOutputUnitProperty_EnableIO, 
                              kAudioUnitScope_Input, 
                              kInputBus,
                              <span style="color: #002200;">&amp;</span>flag, 
                              <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>flag<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Enable IO for playback</span>
status <span style="color: #002200;">=</span> AudioUnitSetProperty<span style="color: #002200;">&#40;</span>audioUnit, 
                              kAudioOutputUnitProperty_EnableIO, 
                              kAudioUnitScope_Output, 
                              kOutputBus,
                              <span style="color: #002200;">&amp;</span>flag, 
                              <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>flag<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Describe format</span>
audioFormat.mSampleRate			<span style="color: #002200;">=</span> <span style="color: #2400d9;">44100.00</span>;
audioFormat.mFormatID			<span style="color: #002200;">=</span> kAudioFormatLinearPCM;
audioFormat.mFormatFlags		<span style="color: #002200;">=</span> kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket	<span style="color: #002200;">=</span> <span style="color: #2400d9;">1</span>;
audioFormat.mChannelsPerFrame	<span style="color: #002200;">=</span> <span style="color: #2400d9;">1</span>;
audioFormat.mBitsPerChannel		<span style="color: #002200;">=</span> <span style="color: #2400d9;">16</span>;
audioFormat.mBytesPerPacket		<span style="color: #002200;">=</span> <span style="color: #2400d9;">2</span>;
audioFormat.mBytesPerFrame		<span style="color: #002200;">=</span> <span style="color: #2400d9;">2</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Apply format</span>
status <span style="color: #002200;">=</span> AudioUnitSetProperty<span style="color: #002200;">&#40;</span>audioUnit, 
                              kAudioUnitProperty_StreamFormat, 
                              kAudioUnitScope_Output, 
                              kInputBus, 
                              <span style="color: #002200;">&amp;</span>audioFormat, 
                              <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>audioFormat<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;
status <span style="color: #002200;">=</span> AudioUnitSetProperty<span style="color: #002200;">&#40;</span>audioUnit, 
                              kAudioUnitProperty_StreamFormat, 
                              kAudioUnitScope_Input, 
                              kOutputBus, 
                              <span style="color: #002200;">&amp;</span>audioFormat, 
                              <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>audioFormat<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;
&nbsp;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Set input callback</span>
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc <span style="color: #002200;">=</span> recordingCallback;
callbackStruct.inputProcRefCon <span style="color: #002200;">=</span> self;
status <span style="color: #002200;">=</span> AudioUnitSetProperty<span style="color: #002200;">&#40;</span>audioUnit, 
                              kAudioOutputUnitProperty_SetInputCallback, 
                              kAudioUnitScope_Global, 
                              kInputBus, 
                              <span style="color: #002200;">&amp;</span>callbackStruct, 
                              <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>callbackStruct<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Set output callback</span>
callbackStruct.inputProc <span style="color: #002200;">=</span> playbackCallback;
callbackStruct.inputProcRefCon <span style="color: #002200;">=</span> self;
status <span style="color: #002200;">=</span> AudioUnitSetProperty<span style="color: #002200;">&#40;</span>audioUnit, 
                              kAudioUnitProperty_SetRenderCallback, 
                              kAudioUnitScope_Global, 
                              kOutputBus,
                              <span style="color: #002200;">&amp;</span>callbackStruct, 
                              <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>callbackStruct<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// Disable buffer allocation for the recorder (optional - do this if we want to pass in our own)</span>
flag <span style="color: #002200;">=</span> <span style="color: #2400d9;">0</span>;
status <span style="color: #002200;">=</span> AudioUnitSetProperty<span style="color: #002200;">&#40;</span>audioUnit, 
                              kAudioUnitProperty_ShouldAllocateBuffer,
                              kAudioUnitScope_Output, 
                              kInputBus,
                              <span style="color: #002200;">&amp;</span>flag, 
                              <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>flag<span style="color: #002200;">&#41;</span><span style="color: #002200;">&#41;</span>;
&nbsp;
<span style="color: #11740a; font-style: italic;">// TODO: Allocate our own buffers if we want</span>
&nbsp;
<span style="color: #11740a; font-style: italic;">// Initialise</span>
status <span style="color: #002200;">=</span> AudioUnitInitialize<span style="color: #002200;">&#40;</span>audioUnit<span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>Then, when you&#8217;re ready to start:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">OSStatus status <span style="color: #002200;">=</span> AudioOutputUnitStart<span style="color: #002200;">&#40;</span>audioUnit<span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>And to stop:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">OSStatus status <span style="color: #002200;">=</span> AudioOutputUnitStop<span style="color: #002200;">&#40;</span>audioUnit<span style="color: #002200;">&#41;</span>;
checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>Then, when we&#8217;re finished:</p>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;">AudioUnitUninitialize<span style="color: #002200;">&#40;</span>audioUnit<span style="color: #002200;">&#41;</span>;</pre></td></tr></table></div>


<p>And now for our callbacks.</p>

<h4>Recording</h4>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">static</span> OSStatus recordingCallback<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>inRefCon, 
                                  AudioUnitRenderActionFlags <span style="color: #002200;">*</span>ioActionFlags, 
                                  <span style="color: #a61390;">const</span> AudioTimeStamp <span style="color: #002200;">*</span>inTimeStamp, 
                                  UInt32 inBusNumber, 
                                  UInt32 inNumberFrames, 
                                  AudioBufferList <span style="color: #002200;">*</span>ioData<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// TODO: Use inRefCon to access our interface object to do stuff</span>
    <span style="color: #11740a; font-style: italic;">// Then, use inNumberFrames to figure out how much data is available, and make</span>
    <span style="color: #11740a; font-style: italic;">// that much space available in buffers in an AudioBufferList.</span>
&nbsp;
    AudioBufferList <span style="color: #002200;">*</span>bufferList; <span style="color: #11740a; font-style: italic;">// &lt;- Fill this up with buffers (you will want to malloc it, as it's a dynamic-length list)</span>
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Then:</span>
    <span style="color: #11740a; font-style: italic;">// Obtain recorded samples</span>
&nbsp;
    OSStatus status;
&nbsp;
    status <span style="color: #002200;">=</span> AudioUnitRender<span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>audioInterface audioUnit<span style="color: #002200;">&#93;</span>, 
                             ioActionFlags, 
                             inTimeStamp, 
                             inBusNumber, 
                             inNumberFrames, 
                             bufferList<span style="color: #002200;">&#41;</span>;
    checkStatus<span style="color: #002200;">&#40;</span>status<span style="color: #002200;">&#41;</span>;
&nbsp;
    <span style="color: #11740a; font-style: italic;">// Now, we have the samples we just read sitting in buffers in bufferList</span>
    DoStuffWithTheRecordedAudio<span style="color: #002200;">&#40;</span>bufferList<span style="color: #002200;">&#41;</span>;
    <span style="color: #a61390;">return</span> noErr;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<h4>Playback</h4>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">static</span> OSStatus playbackCallback<span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span> <span style="color: #002200;">*</span>inRefCon, 
                                  AudioUnitRenderActionFlags <span style="color: #002200;">*</span>ioActionFlags, 
                                  <span style="color: #a61390;">const</span> AudioTimeStamp <span style="color: #002200;">*</span>inTimeStamp, 
                                  UInt32 inBusNumber, 
                                  UInt32 inNumberFrames, 
                                  AudioBufferList <span style="color: #002200;">*</span>ioData<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>    
    <span style="color: #11740a; font-style: italic;">// Notes: ioData contains buffers (may be more than one!)</span>
    <span style="color: #11740a; font-style: italic;">// Fill them up as much as you can. Remember to set the size value in each buffer to match how</span>
    <span style="color: #11740a; font-style: italic;">// much data is in the buffer.</span>
    <span style="color: #a61390;">return</span> noErr;
<span style="color: #002200;">&#125;</span></pre></td></tr></table></div>


<p>Finally, rejoice with me in this discovery ;)</p>

<p>Resources that helped</p>

<ul>
<li><a href="http://pastie.org/pastes/219616">http://pastie.org/pastes/219616</a></li>
<li><a href="http://developer.apple.com/samplecode/CAPlayThrough/listing8.html">http://developer.apple.com/samplecode/CAPlayThrough/listing8.html</a></li>
<li><a href="http://listas.apesol.org/pipermail/svn-libsdl.org/2008-July/000797.html">http://listas.apesol.org/pipermail/svn-libsdl.org/2008-July/000797.html</a></li>
</ul>

<p>No thanks at all to Apple for their lack of accessible documentation on this topic &#8211; They really have a long way to go here! Also boo to them with their lack of search engine, and refusal to open up their docs to Google. It&#8217;s a jungle out there!</p>

<p><strong>Update</strong>: You can adjust the latency of RemoteIO (and, in fact, any other audio framework) by setting the <code>kAudioSessionProperty_PreferredHardwareIOBufferDuration</code> property:</p>


<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #a61390;">float</span> aBufferLength <span style="color: #002200;">=</span> <span style="color: #2400d9;">0.005</span>; <span style="color: #11740a; font-style: italic;">// In seconds</span>
AudioSessionSetProperty<span style="color: #002200;">&#40;</span>kAudioSessionProperty_PreferredHardwareIOBufferDuration, 
                        <span style="color: #a61390;">sizeof</span><span style="color: #002200;">&#40;</span>aBufferLength<span style="color: #002200;">&#41;</span>, <span style="color: #002200;">&amp;</span>aBufferLength<span style="color: #002200;">&#41;</span>;</pre></div></div>


<p>This adjusts the length of buffers that&#8217;re passed to you &#8211; if buffer length was originally, say, 1024 samples, then halving the number of samples halves the amount of time taken to process them.</p>
 <img src="http://atastypixel.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=1003" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://atastypixel.com/blog/using-remoteio-audio-unit/feed/</wfw:commentRss>
		<slash:comments>195</slash:comments>
		</item>
	</channel>
</rss>

