<?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>Synthetic Bits Blog</title>
	<atom:link href="http://syntheticbits.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://syntheticbits.com/blog</link>
	<description>Apps, Programming, Games, Music</description>
	<lastBuildDate>Fri, 09 Mar 2012 20:49:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Little MIDI Machine version 3.0 update released!</title>
		<link>http://syntheticbits.com/blog/?p=1556</link>
		<comments>http://syntheticbits.com/blog/?p=1556#comments</comments>
		<pubDate>Fri, 09 Mar 2012 20:49:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Free Stuff]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=1556</guid>
		<description><![CDATA[Good things come to those who wait, and, well, you all have been waiting a long time for this one. Version 3.0 of our Little MIDI Machine step sequencer app is now available in the App Store! Sorry it took so long! Here&#8217;s an overview of some of the new features: Virtual MIDI with audio [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://syntheticbits.com/blog/wp-content/uploads/2012/03/iPad_Screen_1.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2012/03/iPad_Screen_1.jpg" alt="" title="Little MIDI Machine v3.0" width="560" height="420" class="aligncenter size-full wp-image-1562" /></a></p>
<p>Good things come to those who wait, and, well, you all have been waiting a long time for this one. Version 3.0 of our <a href="http://click.linksynergy.com/fs-bin/stat?id=hrETtA2loq0&#038;offerid=146261&#038;type=3&#038;subid=0&#038;tmpid=1826&#038;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fus%252Fapp%252Flittle-midi-machine%252Fid394018004%253Fmt%253D8%2526uo%253D4%2526partnerId%253D30">Little MIDI Machine step sequencer</a> app is now available in the App Store! Sorry it took so long!</p>
<p>Here&#8217;s an overview of some of the new features:</p>
<p><strong>Virtual MIDI with audio background</strong></p>
<p>This is a big one, it lets you sequence other synth apps on your iPad or iPhone with Little MIDI Machine! No longer do you need to hook up a hardware interface or a network MIDI connection to make some groovy synth music. Just load up AniMoog, Arctic Keys, iVoxel, NLogSynth Pro, Sunrizer or any other synth app that has virtual MIDI and audio backgrounding support. Since Little MIDI can sequence two channels at once, if you have an iPad 2 (or the upcoming iPad 3!) you can sequence two different synth apps with Little MIDI plus sync up a drum machine app, all at the same time. Sweet!</p>
<p><a href="http://syntheticbits.com/blog/wp-content/uploads/2012/03/omac_switch_v3.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2012/03/omac_switch_v3.jpg" alt="" title="LMM v3 fast switch" width="560" height="420" class="aligncenter size-full wp-image-1563" /></a></p>
<p><strong>OMAC fast app switching</strong></p>
<p>This feature works hand in hand with the Virtual MIDI support, it lets you assign a button on the main Little MIDI page to another app, so that you can quickly switch over to that app without having to double press the home key and go through the active apps in the menu bar. You can set which app to assign to which button (each sequence gets its own button) in the Settings menu. Currently there aren&#8217;t a ton of apps that support this, so if you don&#8217;t see your favorite synth app in the list, bug the developer to add this feature! Arctic Keys, Beatmaker 2, NLog Synth and ThumbJam currently support it, and it makes it much easier to move to those apps to tweak the synth parts being sequenced by Little MIDI.</p>
<p><a href="http://syntheticbits.com/blog/wp-content/uploads/2012/03/iPhone_green_v3.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2012/03/iPhone_green_v3.jpg" alt="" title="LMM iPhone green v3.0" width="480" height="320" class="aligncenter size-full wp-image-1565" /></a></p>
<p><strong>Sequencer improvements</strong></p>
<p>Sequencer improvements, oh yeah! The first big one was to add a second sequence to the iPhone/Touch version, to match it up feature-wise with the iPad version. Your iPhone can now sequence in both orange and green! Whoa, crazy colors, man&#8230;</p>
<p>Little MIDI v3 also now lets you sequence Note Length as well as Pitch and Velocity, so you can vary the length of each note in your sequences for more expression and feel. You can also now un-link the Pitch, Velocity, and Note Length parts of the sequence: this means you can set skip, random, and reverse separately for the three parts which can make the sequences much more interesting! For example, you could have a normal 16 note sequence of pitches, that uses random velocity values for each step, and a 13 step note length sequence so that the note length times are sequential but constantly varying with relation to the pitch. Cool!</p>
<p>Also added is a new super-sequence mode. This lets you gang together the 4 16 step sub-sequences (A B C D) into one big 64 step sequence, so you can have one nice long complicated sequence rather than 4 separate ones. You can also use this with the un-link feature described above in this mode!</p>
<p><strong>New MIDI Input modes</strong></p>
<p>Little MIDI now supports MIDI input to both record notes into your sequences, and transpose your sequences on the fly! Input record mode works when your sequence is stopped, it lets you enter in the note values of your sequence manually using an external MIDI keyboard or another CoreMIDI music app. Transpose mode works when your sequence is running, it takes the MIDI notes you input and transposes your sequence so that the note you enter is equivalent to the center slider value. This lets you, for instance, change the key of your sequence to match overall key changes in a song. Rad!</p>
<p><a href="http://syntheticbits.com/blog/wp-content/uploads/2012/03/MIDI_config_screen_v3.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2012/03/MIDI_config_screen_v3.jpg" alt="" title="LMM v3 config" width="560" height="420" class="aligncenter size-full wp-image-1564" /></a></p>
<p><strong>Improved MIDI configuration</strong></p>
<p>Getting things set up and working is one of the biggest hassles of iOS MIDI, so we&#8217;ve overhauled the way you set up your MIDI configuration to make it (hopefully!) easier to use and more powerful. Easier on the eyes too! Check it out in the Settings Menu.</p>
<p><strong>iCloud support</strong></p>
<p>Little MIDI can now save your sequences in the cloud! If you have iCloud active on your iOS devices, any sequences you save to the iCloud area will be accessible to all of your other devices. This is especially useful in combination with the virtual MIDI feature: come up with a dope sequence on your iPhone at work using AniMoog (during, uh, lunch hour or something&#8230;), get home later that night and that sequence is right there on your studio iPad to sequence your Moog Little Phatty. Whoa, man! The future is here, like, now, man!</p>
<p><strong>Other stuff</strong></p>
<p>There&#8217;s more stuff too, like support for using a footswitch to start your sequences, the ability to clear your sequences with random data instead of zeroing it, a variable MIDI latency setting so you can reduce lag when you&#8217;re using virtual MIDI, and more.</p>
<p>And it&#8217;s still completely and totally free! Wow!! Why is it free? Well, basically because we&#8217;re idiots. Wait, no, I mean because we love you! Yes, that second one, free love, baby, yeah! And uh, okay, maybe a little bit of the first one too. Anyway, have fun with Little MIDI Machine v3, and please use it responsibly to make some groovy far out music! Whoa&#8230;</p>
<p><a href="http://click.linksynergy.com/fs-bin/stat?id=hrETtA2loq0&#038;offerid=146261&#038;type=3&#038;subid=0&#038;tmpid=1826&#038;RD_PARM1=http%253A%252F%252Fitunes.apple.com%252Fus%252Fapp%252Flittle-midi-machine%252Fid394018004%253Fmt%253D8%2526uo%253D4%2526partnerId%253D30">Little MIDI Machine v3.0</a>, available now in the App Store!</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=1556</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Little MIDI Machine teaching kids about music</title>
		<link>http://syntheticbits.com/blog/?p=1549</link>
		<comments>http://syntheticbits.com/blog/?p=1549#comments</comments>
		<pubDate>Sat, 14 Jan 2012 18:30:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Cool Links]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=1549</guid>
		<description><![CDATA[Biophilia Educational Program in Iceland 2011 from Biophilia Educational Program on Vimeo. Little MIDI Machine is being used as part of Bjork&#8217;s Biophilia education program to teach kids about music and science. You can see it being used at 2:10 in the video to control one of Bjork&#8217;s custom musical instruments. &#8220;Here you can explore [...]]]></description>
			<content:encoded><![CDATA[<p><iframe src="http://player.vimeo.com/video/33938841?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
<p><a href="http://vimeo.com/33938841">Biophilia Educational Program in Iceland 2011</a> from <a href="http://vimeo.com/user9705162">Biophilia Educational Program</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<p>Little MIDI Machine is being used as part of Bjork&#8217;s Biophilia education program to teach kids about music and science. You can see it being used at 2:10 in the video to control one of Bjork&#8217;s custom musical instruments.</p>
<p>&#8220;Here you can explore spatial and structural similarities in crystals and music, hear how viruses behave like generative music, see how the full moon governs the tide which then rations water into a music sequencer, there is a simon says method in learning differences in scales, DNA multiplying shows us how time signature and speed changes songs, an algorithm of gravity pulls a pendulum into natural counterpoint and the tectonic plates rub against each other and behave like chords.&#8221; -Björk</p>
<p>We are big fans of Bjork and are very interested in getting kids excited about music and science, so we were really happy to see one of our apps playing a small part in this very cool program!</p>
<p>If you haven&#8217;t already, be sure to check out her <a href="http://itunes.apple.com/us/app/bjork-biophilia/id434122935?mt=8">Biophilia app</a> for iOS. It contains a bunch of interesting interactive music instrument apps based on her music, and also supports CoreMIDI so you can use the instruments to control your own synths.</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=1549</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using the iPhone as our Video Camera</title>
		<link>http://syntheticbits.com/blog/?p=1504</link>
		<comments>http://syntheticbits.com/blog/?p=1504#comments</comments>
		<pubDate>Wed, 28 Dec 2011 08:11:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Recap]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=1504</guid>
		<description><![CDATA[Here&#8217;s our latest video, showing our FunkBox and Little MIDI Machine apps using an iRig MIDI interface and a bunch of other hardware and software to record an electronic music track. To make our last two app videos we used an iPhone 4S to shoot the raw video. So far we&#8217;ve been very happy with [...]]]></description>
			<content:encoded><![CDATA[<p><iframe width="560" height="315" src="http://www.youtube.com/embed/VS2lD9ZjA0c" frameborder="0" allowfullscreen></iframe></p>
<p>Here&#8217;s our latest video, showing our <a href="http://syntheticbits.com/funkbox.html">FunkBox</a> and <a href="http://syntheticbits.com/littlemidi.html">Little MIDI Machine</a> apps using an <a href="http://www.ikmultimedia.com/irigmidi/features/">iRig MIDI interface</a> and a bunch of other hardware and software to record an electronic music track.</p>
<p>To make our last two app videos we used an iPhone 4S to shoot the raw video. So far we&#8217;ve been very happy with the results, and we currently plan to shoot all our future videos this way. In addition to giving us some experience working with video on iOS, there is a certain appeal to doing as much of our iOS work as possible using the actual devices and their apps.</p>
<div id="attachment_1505" class="wp-caption aligncenter" style="width: 460px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/12/iphonecam.jpg"><img class="size-full wp-image-1505" title="iPhone 4S in the tripod" src="http://syntheticbits.com/blog/wp-content/uploads/2011/12/iphonecam.jpg" alt="" width="450" height="538" /></a><p class="wp-caption-text">iPhone 4S nestled snug in the tripod</p></div>
<p>Previously we used a Canon S95 digital camera in video mode, so the transition was pretty easy. The S95 is a pretty basic camera, so while the iPhone camera and its app don&#8217;t have a lot of fancy features, for our purposes they work pretty much the same: point, light, focus, shoot. All we needed to do was find a way to get the iPhone mounted on a tripod, and then just swap the S95 out for the iPhone. </p>
<div id="attachment_1506" class="wp-caption aligncenter" style="width: 410px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/12/glifclip.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/12/glifclip.jpg" alt="" title="Glif tripod clip for the 4S" width="400" height="206" class="size-full wp-image-1506" /></a><p class="wp-caption-text">Glif tripod clip for the 4S</p></div>
<p>We used the <a href="http://www.studioneat.com/products/glif-for-iphone-4">Glif tripod clip</a> to mount the iPhone on the tripod, which works great. The only downside is the iPhone can&#8217;t be in a case, so if you do use a case with your phone you&#8217;ll need to find one that lets you slip it in and out quickly and easily. Other than that, the iPhone fits in snugly to the <a href="http://www.studioneat.com/products/glif-for-iphone-4">Glif</a> and works perfectly on top of the tripod.</p>
<p>We haven&#8217;t yet gotten to the point where we edit and publish the final videos on the iPhone or an iPad. For now we attach the iPhone to a Mac, import the raw video, and edit and polish things up with <a href="http://www.apple.com/finalcutpro/">Final Cut Pro X</a>. In the future we hope to do even more of the work on the devices.</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=1504</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Boston Music Hack Day</title>
		<link>http://syntheticbits.com/blog/?p=1477</link>
		<comments>http://syntheticbits.com/blog/?p=1477#comments</comments>
		<pubDate>Wed, 16 Nov 2011 21:48:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Recap]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=1477</guid>
		<description><![CDATA[I recently spent the weekend of November 5-6 at Boston Music Hack Day. The idea behind these hack days is everybody who participates has 24 hours to come up with a &#8220;hack&#8221; project, build it and get it working, and then demo it to everyone else. 24 hours isn&#8217;t long enough to get anything super [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1482" class="wp-caption aligncenter" style="width: 510px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/11/midisyncer.jpg"><img class="size-full wp-image-1482" title="MidiSyncer setup" src="http://syntheticbits.com/blog/wp-content/uploads/2011/11/midisyncer.jpg" alt="" width="500" height="500" /></a><p class="wp-caption-text">My overly complicated hardware setup for my Boston Music Hack Day hack.</p></div>
<p>I recently spent the weekend of November 5-6 at <a href="http://boston.musichackday.org/2011/">Boston Music Hack Day</a>. The idea behind these hack days is everybody who participates has 24 hours to come up with a &#8220;hack&#8221; project, build it and get it working, and then demo it to everyone else. 24 hours isn&#8217;t long enough to get anything super complicated done, and isn&#8217;t enough time to make things look pretty, but it is enough time to try out something new and cool. The beginning is always the fun part of any project, where you&#8217;re first brainstorming ideas, sketching the app out, and writing the &#8220;fun&#8221; code to handle the normal cases, so this seemed like a fun way to spend a weekend!</p>
<p>My hack involved getting songs on your iPhone/iPod&#8217;s music library to sync up with MIDI. I came up with this idea while listening to the <a href="http://the.echonest.com/">Echo Nest</a> talk about their database of music info, in particular the beat analysis data they&#8217;ve generated for millions of songs. I figured I could take their detailed information about the position of the beats in a song, hook that up to some of the <a href="http://syntheticbits.com/blog/?p=1213">MIDI clock sync code</a> I&#8217;ve worked on before, and get something that would let you sync up a drum machine to any old song playing on your iPhone/iPod. Cool in theory, but would it work? By the end of the weekend I did indeed have it mostly working &#8212; some songs better than others, sometimes with some adjustments required &#8212; but my little app would play a song and send out a MIDI clock for it. Pretty cool! Here&#8217;s a quick video demo:</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/gbp-wCSd-t4" frameborder="0" allowfullscreen></iframe></p>
<p><span id="more-1477"></span></p>
<p>I spent most of my time working with the <a href="http://developer.echonest.com/client_libraries.html">Echo Nest iOS client library</a>. Under normal circumstances, I&#8217;d say this library is extremely easy to learn and use. Under the time pressure of getting something working within 24 hours, it was a little bit more stressful learning a new API and deciphering the data that came back from it! The basic process for querying and using the Echo Nest went like this:</p>
<p>Initialize Echo Nest library with my developer API key<br />
Query for a track ID using the song and artist name of the music the user picks from their iPhone library<br />
Use that track ID to retrieve a big chunk of beat analysis data from Echo Nest<br />
Parse through nested structures of NSDictionary, NSArray and NSTimeInterval objects to get to the beat timestamps<br />
Throw those timestamps into a simple consecutive array of times that I used to trigger MIDI clock messages</p>
<p>Once I had the data in a form I could use, I just needed to add the MIDI portion, which given <a href="http://syntheticbits.com/blog/?p=1213">my previous app work with CoreMIDI</a> wasn&#8217;t too bad. Send a MIDI start message when the song starts, send 48ppq MIDI clock messages while it&#8217;s playing, and a MIDI stop message when the song stops. Receiving MIDI clock would have been a bit more complicated, so I left it out for this quick hack, but in theory that would be possible too so that you could slave the tempo of the song to your drum machine.</p>
<p>Finally I tested the now sort-of working app with various songs, and added a few tweaks to get it working better with some of the songs it had problems with. The tweaks were basically just allowing the user to manually shift the beat offset, so the bars in the song would sync up with the bars playing on the synced drum machine. These didn&#8217;t always automatically match because of weird little intro sections that didn&#8217;t match the rest of the song, or intro fade ins that only contained part of the measure, or various other reasons.</p>
<p>If I&#8217;d had more time, the first thing I would have done is improve these beat offset controls even more. I also would have liked to play with the pitch information that Echo Nest has embedded in their analysis data, so I could add a MIDI arpeggiator you could attach to a synth that would play appropriate not-terrible sounding notes for that portion of the song. Finally I would have liked to give the user the option to rearrange the parts of the song playing on their iPhone, so they could extend, repeat, or remove individual sections. All of these things would let the app become a full fledged MIDI remixer rather than just a syncer.</p>
<p>I have no plans for now to make this into a &#8220;real&#8221; app, but I could definitely see using some of this beat syncing technology in other apps like games or graphics toys that relied on the user&#8217;s music library. I&#8217;ll keep playing with the hack though, and if I can figure out a way to make it work a little better, and a little easier, maybe we&#8217;ll release it in some form.</p>
<p>A few of the other projects people worked on at the Hack Day that I particularly liked:<br />
<a href="http://wiki.musichackday.org/index.php?title=Bohemian_Rhapsichord">Bohemian Rhapsichord</a><br />
<a href="http://wiki.musichackday.org/index.php?title=Kinect_BeatWheel">Kinect BeatWheel</a><br />
<a href="http://wiki.musichackday.org/index.php?title=Grain_nest">Grain Nest</a><br />
<a href="http://wiki.musichackday.org/index.php?title=Neurofeedback">Neurofeedback</a><br />
<a href="http://drinkify.org/submodern">Drinkify</a></p>
<p>And here&#8217;s a <a href="http://wiki.musichackday.org/index.php?title=Boston_2011_Hacks">full list of all the hacks</a> from the weekend.</p>
<p>Overall the weekend was a fun time, and I definitely recommend signing up for a <a href="http://musichackday.org/">Music Hack Day</a> in your city if they have one! It&#8217;s a great chance to meet local developers working on music related things and a really nice way to force yourself to make something in just 24 hours. Thank you to <a href="http://twitter.com/#!/plamere">@plamere</a> and <a href="http://twitter.com/#!/elissab">@elissab</a> of <a href="http://the.echonest.com/">the Echo Nest</a> for organizing the Boston event!</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=1477</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FunkBox is an App Store &#8220;Staff Favorite&#8221; and &#8220;Retro App&#8221;!</title>
		<link>http://syntheticbits.com/blog/?p=1465</link>
		<comments>http://syntheticbits.com/blog/?p=1465#comments</comments>
		<pubDate>Thu, 25 Aug 2011 21:01:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Recap]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=1465</guid>
		<description><![CDATA[FunkBox was included in the &#8220;Staff Favorites&#8221; sections of both the iPhone and iPad U.S. App Stores this week. This is the first time one of our apps has been picked for this feature, and we really appreciate it. Thanks Apple! Looks like FunkBox was also included in an iPhone and iPad feature called &#8220;Retro [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/stafffavorites.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/stafffavorites.jpg" alt="" title="FunkBox in the Staff Favorites section, 8/25/11" width="580" height="280" class="aligncenter size-full wp-image-1466" /></a></p>
<p><a href="http://itunes.apple.com/us/app/funkbox-drum-machine/id350437349?mt=8">FunkBox</a> was included in the &#8220;Staff Favorites&#8221; sections of both the iPhone and iPad U.S. App Stores this week. This is the first time one of our apps has been picked for this feature, and we really appreciate it. Thanks Apple!</p>
<p><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/retroapps.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/retroapps.jpg" alt="" title="Retro Apps Feature" width="580" height="162" class="aligncenter size-full wp-image-1473" /></a></p>
<p>Looks like <a href="http://itunes.apple.com/us/app/funkbox-drum-machine/id350437349?mt=8">FunkBox</a> was also included in an iPhone and iPad feature called &#8220;Retro Apps&#8221; this week! Really cool!</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=1465</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CoreMIDI Brain Dump, Part 3: Clocks and Threads</title>
		<link>http://syntheticbits.com/blog/?p=1213</link>
		<comments>http://syntheticbits.com/blog/?p=1213#comments</comments>
		<pubDate>Fri, 12 Aug 2011 04:55:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Dev Info]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=1213</guid>
		<description><![CDATA[This is part three in a series of five blog posts discussing the use of CoreMIDI in iOS music apps. These five posts are being written to help celebrate five years of the Palm Sounds blog. You might have noticed that part three has taken a long time to write, and I apologize for that. [...]]]></description>
			<content:encoded><![CDATA[<p>This is part three in a series of five blog posts discussing the use of CoreMIDI in iOS music apps. These five posts are being written to help celebrate five years of the <a href="http://the-palm-sound.blogspot.com/">Palm Sounds</a> blog. You might have noticed that part three has taken a long time to write, and I apologize for that. It turns out that writing these posts has required a lot more time and effort than I anticipated, and part three in particular is the point where things are going to start getting less fun and more serious. Let’s just hope I can actually finish writing parts four and five by the time <a href="http://the-palm-sound.blogspot.com/">Palm Sounds</a> year six rolls around&#8230;</p>
<p><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/coremidititle.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/coremidititle.jpg" alt="" title="CoreMIDI title" width="500" height="180" class="alignnone size-full wp-image-1226" /></a></p>
<p>Welcome back to our series of blog posts about CoreMIDI. In <a href="http://syntheticbits.com/blog/?p=508">part one</a> we talked about setting up and playing around with CoreMIDI, and in <a href="http://syntheticbits.com/blog/?p=878">part two</a> we discussed the basics of how to add CoreMIDI to your app using <a href="http://goodliffe.blogspot.com/2011/02/pgmidi-updated.html">Pete Goodliffe’s PGMidi sample project</a>. This time we’re going to make some tweaks to PGMidi to improve MIDI timing, improve MIDI performance, and add MIDI clock features.</p>
<p>Before we start, be sure to check out the latest <a href="http://developer.apple.com/videos/">WWDC videos</a> at Apple’s iOS development portal. There is one video in particular that discusses audio and music in Lion and iOS 5, including some bits about CoreMIDI, that you will find very useful.</p>
<p>Second, check out <a href="http://www.finger-pro.com/docs/avoiding-the-pitfalls-of-coremidi-programming-for-developers.html">three CoreMIDI tips from Finger</a> apps, makers of the first two apps to fully use CoreMIDI clock sync, <a href="http://itunes.apple.com/us/app/modrum-synthesis-based-drum/id408872480?mt=8">MoDrum</a> and <a href="http://itunes.apple.com/us/app/bassline-analog-modeling-synthesizer/id298147000?mt=8">BassLine</a>. If these tips don&#8217;t completely make sense now, read them again after going through this blog post, since they are covering the same ground.</p>
<p>I also recommend buying and reading the draft version of Chris Adamson and Kevin Avila&#8217;s <a href="http://my.safaribooksonline.com/9780321636973">&#8220;Core Audio&#8221; book</a> if you find you need help with figuring out how to query Core Audio/MIDI properties, and also just to get some good insight into Core Audio and MIDI in general. Good information on these topics is scarce, for whatever reason, but this book is really great and I wish it had existed (even in draft form!) when I was starting work on my music apps.</p>
<p><span id="more-1213"></span></p>
<p><strong>TIMING IS EVERYTHING</strong></p>
<p>Okay, let’s begin with a quick look at how MIDI clock works. The basics of sending or receiving a MIDI clock are actually pretty straightforward. You have one master clock device that sets the tempo, and one or more slave clock devices that receive and lock to the master device’s tempo. When the master device is ready to begin, it sends a simple MIDI Start message that tells all the slave devices to start. It then sends a series of evenly spaced MIDI Clock messages at a rate of 24 per quarter note. The rate of these messages will tell the slave devices what the tempo is: each time the master clock sequencer clocks through a quarter note worth of song, it will have sent 24 of those clock messages. Which means each eighth note it would have sent 12 clock messages, each sixteenth note it has sent 6 messages, etc. In this way the master device is telling the slave devices both tempo and song/bar position: average tempo based on how fast the clock messages are coming in, and song/bar position based on how many total clock messages have been received since the start message.</p>
<p>If the master tempo changes, the master device will adjust the rate it sends its MIDI Clock messages by the appropriate amount, so the slave devices will notice those clock messages coming in at a different rate and will adjust their tempo also. Finally, when the master device stops its clock, it sends a MIDI Stop message to tell all the slave devices to stop playing.</p>
<p>So, to implement a basic MIDI clock you are going to need to send or receive three types of MIDI messages: MIDI Start to get things started, MIDI Clock messages at regular intervals to keep things going, and a MIDI Stop to stop everything. Easy enough, right? If you refer back to the <a href="http://home.roadrunner.com/~jgglatt/tech/midispec.htm">MIDI reference page</a> I mentioned in part 2, you’ll see that the actual MIDI packets are formatted like this:</p>
<ul>
MIDI Start: status byte 0xFA<br />
MIDI Clock: status byte 0xF9<br />
MIDI Stop: status byte 0xFC
</ul>
<p>You’ll notice that these messages are very simple and only contain the one status byte that identifies the MIDI message type. They don’t have any MIDI channel associated with them and don’t have anything identifying where they are coming from. When you send a Start message, you are telling everything connected to your MIDI outputs to Start. When you send Clock messages, you are broadcasting that same stream of clock ticks to everyone listening. And if you are the one listening, you assume only one device, the master tempo clock, is sending you this information. If for some reason two devices are both doing it at the same time on the same interface, you’ll receive twice as many Clock messages as you expect, and the raw MIDI packets will all look the same so your only option will be to go twice as fast.</p>
<p><strong>TICKING AWAY THE MOMENTS THAT MAKE UP A LONG DAY</strong></p>
<p>We talked about creating MIDI packets in <a href="http://syntheticbits.com/blog/?p=878">part 2</a>, and saw how Pete created note on and note off messages. Modifying that code to create MIDI Start, Clock, and Stop messages is pretty easy:</p>
<div id="attachment_1280" class="wp-caption aligncenter" style="width: 345px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/pgmidinote.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/pgmidinote.jpg" alt="" title="pgmidinote" width="335" height="56" class="size-full wp-image-1280" /></a><p class="wp-caption-text">PGMidi creating MIDI packet data for note messages</p></div>
<div id="attachment_1281" class="wp-caption aligncenter" style="width: 272px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/startmessage.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/startmessage.jpg" alt="" title="startmessage" width="262" height="34" class="size-full wp-image-1281" /></a><p class="wp-caption-text">Modify that to create a MIDI Start message</p></div>
<div id="attachment_1282" class="wp-caption aligncenter" style="width: 278px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/clockmessage.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/clockmessage.jpg" alt="" title="clockmessage" width="268" height="34" class="size-full wp-image-1282" /></a><p class="wp-caption-text">...or a MIDI Clock message...</p></div>
<div id="attachment_1283" class="wp-caption aligncenter" style="width: 266px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/stopmessage.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/stopmessage.jpg" alt="" title="stopmessage" width="256" height="34" class="size-full wp-image-1283" /></a><p class="wp-caption-text">...or a MIDI Stop message</p></div>
<p>You can put a very basic MIDI clock out in your app with just this. Send that MIDI Start, send 24 MIDI Clock messages evenly spaced in time for every quarter note, and finish it off with a MIDI Stop when you’re done. For now, you can just use a simple NSTimer to do the clock timing, or call it from your sequencer every 1/24 of a quarter note. For a quick first-try experiment, modify PGMidi&#8217;s sendMidiDataInBackground: method to run a simple clock in a separate background thread using sleep() like this:</p>
<div id="attachment_1286" class="wp-caption aligncenter" style="width: 395px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/backgroundclock.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/backgroundclock.jpg" alt="" title="backgroundclock" width="385" height="272" class="size-full wp-image-1286" /></a><p class="wp-caption-text">Modifying PGMidi project&#039;s sendMidiDataInBackground to send MIDI clock instead</p></div>
<p>If you do this, you’ll note that the tempo on the receiving side should be approximately the tempo that you’re sending out. But you’ll also probably notice that the exact tempo on the receiving end, especially if you’re talking over a WiFi network connection, will be fluctuating back and forth by at least a few BPMs. This is due to a couple things.</p>
<p>First, there is some lag due to CoreMIDI and your MIDI connection. There is a variable amount of time between when you’re telling CoreMIDI to send those packets and when the other side is receiving them, because it takes time for the packets to be sent by CoreMIDI, then be transmitted over the physical connection, and finally to be received and get decoded on the other end.</p>
<p>Second, since you’re relying on the timing of the not-always-rock-solid NSTimer or sleep(), some of that variation could also due to your clock function not always firing off at the perfect consistent time you asked it to. This will especially be true when your app’s main thread is currently busy trying to handle UI or other events.</p>
<p><strong>WHAT TIME IS IT? IT’S TIME TO GET ILL</strong></p>
<p>A flaky clock is no good, we want solid steady timing. So how can we tighten this timing up? Luckily, CoreMIDI provides us a great solution in the form of putting timestamps on our MIDI packets.</p>
<div id="attachment_1244" class="wp-caption aligncenter" style="width: 349px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/midipacketadd.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/midipacketadd.jpg" alt="" title="midipacketadd" width="339" height="370" class="size-full wp-image-1244" /></a><p class="wp-caption-text">CoreMIDI&#039;s MidiPacketListAdd() function</p></div>
<p>You’ll remember back in <a href="http://syntheticbits.com/blog/?p=878">part 2</a> we discussed CoreMIDI’s <strong>MIDIPacketListAdd()</strong> function, which creates a MIDI packet list that is then sent by the MIDISend() function. <strong>MIDIPacketListAdd()</strong> has a time parameter of type <strong>MIDITimestamp</strong>. At the time, we mentioned if you just use a zero for the timestamp then the packet will be sent immediately. That’s exactly what PGMidi currently does. This is easy and works, but obviously the Apple engineers put that timestamp parameter in there for a reason. And happily enough, the reason they did it is to solve our current problem.</p>
<p>Using the timestamp parameter, we can hand off our MIDI packets to CoreMIDI a little bit early, with a timestamp set to a little bit into the future. This means the CoreMIDI code gets the packet ahead of time, giving it some advance time to handle it properly and get everything ready early, while still knowing exactly when you want that data to be sent. CoreMIDI can then hand the packet off to another app or the Camera Connection Kit or a WiFi network at exactly the right time.</p>
<p>From your perspective, this means if you are willing and able to give CoreMIDI your MIDI packets a little early, you will in return be rewarded by them being sent with extremely accurate and consistent timing. Which means you will get a clock that is seen as very steady and accurate by the receiving MIDI device.</p>
<p>That sounds great, right? But there was that little catch about sending those packets early&#8230;</p>
<p>Which leads us to an important question: exactly how early do we need to send these packets? Unfortunately, the answer to that isn’t going to make you very happy because it’s one you’ve heard many times before, usually when things are about to start getting ugly. “It depends”.</p>
<p><strong>WHAT TIME IS LOVE?</strong></p>
<p>One of the nice things about CoreMIDI is that it abstracts away the actual MIDI connection and hides the specifics of how packets are physically transmitted to and from you. Well, okay, most of the time that’s true; we’ll discuss some important but odd little differences with inter-app MIDI communication in part 5. For now, though, we’ll pretend that CoreMIDI lets you treat a MIDI connection the same whether it be connected via USB, over a network via WiFi, or another app running on the same device. Just hand your packets off to CoreMIDI and let it magically deal with all the details.</p>
<p>In theory this is great, it means you don’t generally need to worry about what sort of connection you’re using. You just focus on sending or receiving MIDI to and from various identical ports. The place it breaks down is unfortunately the same place we find ourselves right now: trying to figure out how early we need to send things to properly account for latency, so that our packets arrive right on time, every time. The reason it breaks down is that different connection types will require very different buffer amounts to account for their connection latency.</p>
<p>Sending MIDI packets to another app running on the same device requires extremely little latency. The next time that app gets a slice of processing time, which unless you are locking up the device should be very soon, it will be able to use that packet. We are talking on the order of single digit milliseconds. It is close to the amount of latency you’d expect between different parts of your own app.</p>
<p>Sending MIDI packets out the USB port is a little trickier, but should still be quite fast. I admit the nitty gritty details of USB driver latency are not my area of expertise. However, on the music making user side, both with iOS and on the Mac, I have personally experienced some flaky and jittery behavior from USB MIDI interfaces. It’s pretty safe to assume this connection will require more of a buffer than app to app. I would still guess it would be in the low 10-20 millisecond range at the most, though.</p>
<p>Sending MIDI packets out over the network via WiFi is the worst case. It just flat out sucks, and there is no point in sugar coating that. What makes it particularly terrible is that it is so variable: one day, on one network, you could send things 50 milliseconds early and it will work perfectly, rock solid. The next day on that same network using the same devices with that same latency value, it will be horrible and everything will sound noticeably off. I have personally found that if I up the latency buffer to around 200ms or so, it is pretty reliable almost all of the time. That is a lot of latency though, and only certain types of music applications (specifically, sequencers and clocks) will be able to send things that early.</p>
<div id="attachment_1247" class="wp-caption aligncenter" style="width: 596px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/latencycalc.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/latencycalc.jpg" alt="" title="latencycalc" width="586" height="66" class="size-full wp-image-1247" /></a><p class="wp-caption-text">Querying CoreMIDI for latency amount of a MIDI endpoint</p></div>
<p>So having said all that, what value should you use? Well, the first approach you should take is to ask CoreMIDI. As Finger apps mentioned in their CoreMIDI clock tips, each connection has a property named <strong>kMIDIPropertyAdvanceScheduleTimeMuSec</strong> that you can query which will tell you the latency value it thinks you should use. With WiFi networks, it will (as of iOS 4.3) always return 50ms. This is why you see the MIDI setup pages in <a href="http://itunes.apple.com/us/app/bassline-analog-modeling-synthesizer/id298147000?mt=8">BassLine</a>, <a href="http://itunes.apple.com/us/app/modrum-synthesis-based-drum/id408872480?mt=8">MoDrum</a> and <a href="http://itunes.apple.com/us/app/molten-drum-machine/id398933969?mt=8">Molten</a> add 50ms of latency when you turn on network connections: they are querying CoreMIDI to see what latency compensation amount they need to use for each endpoint, and then they use the largest of those values as their overall latency amount. </p>
<div id="attachment_1261" class="wp-caption aligncenter" style="width: 520px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/modrum50ms.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/modrum50ms.jpg" alt="" title="modrum50ms" width="510" height="306" class="size-full wp-image-1261" /></a><p class="wp-caption-text">Using a network MIDI destination in MoDrum sets latency at 50ms</p></div>
<p>That’s great, it gives us something to start with, but does it work in practice? Does CoreMIDI really know best? In my experience&#8230; ummm, not really. I’m not sure how they picked that 50ms value, but I’ve personally found that sometimes it really just is not large enough. My advice is to play with different values, at different times, on different networks, until you find something that works enough that you’re happy with it. I know it is frustrating to hear that, but it is what it is. You are going to have to abandon theory and bang your head against the wall of reality for a while if you really want it to work well.</p>
<p>For now, when you’re just starting and trying things out, you might as well give the 50ms (or whatever other value that query returns) value a shot. As an added bonus, this means you can pass the buck and blame Apple if it doesn’t work, which is always nice. Once you get things working, I recommend you experiment with different values under different conditions and figure out what works best for your app, and use CoreMIDI&#8217;s suggested value as a minimum value.</p>
<p><strong>THIS COULD BE THE LAST TIME, MAYBE THE LAST TIME, I DON&#8217;T KNOW. OH NO.</strong></p>
<p>So, we’ve decided we’re going to hand things off to CoreMIDI a little early to tighten up our timing. And we&#8217;ve started thinking about exactly how early we&#8217;ll need to send them for it to work right. So now we actually have to figure out how to do all of that. First let’s take a look at how we use CoreMIDI’s <strong>MIDIPacketListAdd()</strong> function in the first part of our PGMidi <strong>sendBytes:</strong> method:</p>
<div id="attachment_1275" class="wp-caption aligncenter" style="width: 499px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/sendbytes.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/sendbytes.jpg" alt="" title="sendbytes" width="489" height="148" class="size-full wp-image-1275" /></a><p class="wp-caption-text">PGMidi&#039;s sendBytes method</p></div>
<p>As you can see and as we’ve discussed before, PGMidi is currently using a 0 for the timestamp when it hands its MIDI packets off to <strong>MIDIPacketListAdd()</strong>. As we’ve talked about, this means they will be sent immediately. All we have to do to queue things up earlier is give it a real time instead of that 0. Let’s quickly modify sendBytes: and make a new method called <strong>sendQueuedMidi:</strong> to do just that:</p>
<div id="attachment_1270" class="wp-caption aligncenter" style="width: 595px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/sendqueuedmidi.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/sendqueuedmidi.jpg" alt="" title="sendqueuedmidi" width="585" height="151" class="size-full wp-image-1270" /></a><p class="wp-caption-text">Our new modified sendQueuedMidi: method</p></div>
<p>A quick and easy modification to give us our timestamps: just add another parameter to the method that allows the caller to attach a timestamp to their MIDI packet, and then pass that MIDI packet on to <strong>MIDIPacketListAdd()</strong> which will do all the hard work of scheduling it for you. Done and done! Well, okay, almost done. What exactly were we supposed to put in that timestamp parameter again? UInt64, you say, eh? Okay, well, exactly what sort of UInt64 then, and how do you calculate it?</p>
<p>The simplest answer is that when you call the system function <strong>mach_absolute_time()</strong>, iOS will give you the actual current time in a UInt64 form. Yes, the same sort of UInt64 that this timestamp is looking for. Essentially you could replace the 0 timestamp in PGMidi’s original <strong>sendBytes:</strong> with a <strong>mach_absolute_time()</strong> timestamp, and you would get the same result: the packet would be sent immediately, at the current time. The question then becomes how to convert your sequencer’s time format to this other time format&#8230;</p>
<div id="attachment_1250" class="wp-caption aligncenter" style="width: 340px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/audiotimestamp.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/audiotimestamp.jpg" alt="" title="audiotimestamp" width="330" height="216" class="size-full wp-image-1250" /></a><p class="wp-caption-text">CoreAudio&#039;s AudioTimeStamp data structure</p></div>
<p>When writing an audio app, you deal with a number of different ways of keeping track of time. As shown in the <strong>AudioTimestamp</strong> format above, CoreAudio will give you several of the formats in every audio unit render callback, and you likely already use at least one of those in conjunction with your sequencer code. In order to translate between the type of time you use in your render callback and the UIInt64 time, you will want to use that mHostTime format that the AudioTimestamp provides.</p>
<p>For more detailed info about audio host time, check out the timestamp link from Finger&#8217;s CoreMIDI tips: <a href="http://developer.apple.com/library/ios/qa/qa1643/">Apple&#8217;s Technical Q&#038;A QA1643</a>.</p>
<p>One thing to remember is that an audio unit render callback is giving you the timestamp for the audio data it is requesting, which is a little bit ahead of time. It tells you that those audio packets will be played at that time, but you want to use <strong>mach_absolute_time()</strong> to know the actual current time. Another thing to remember is that you do not want to be making your CoreMIDI calls directly from that audio unit render callback, since it is running in its high priority Core Audio thread with tight deadlines. I&#8217;m only using the timestamp format used in the render callback as an example, since your sequencer timing code should be interacting with it already, and you should have some idea of how to translate between the two. Please don&#8217;t call these CoreMIDI functions directly from that Core Audio render callback after grabbing the time there, that&#8217;s very bad!</p>
<p>So hopefully you should be able to figure out how to translate your sequencer&#8217;s time units into CoreMIDI timestamp units without too much fuss. We also talked earlier about deciding how big you will want to make your MIDI latency buffer in milliseconds. So we also need to convert milliseconds units to this UInt64 format. This conversion will be a little trickier than it might seem, since the UInt64 can change depending on the platform/processor/etc you are running it on. You probably have already dealt with this sort of conversion in your sequencer or audio code. If not, here’s a link talking about how to do the conversion:</p>
<p><a href="http://stackoverflow.com/questions/1450737/what-is-mach-absolute-time-based-on-on-iphone">How to convert mach_absolute_time to milliseconds</a></p>
<p>So, the first thing you need to do is decide how early you want to send packets. You do this by querying the CoreMIDI interface latency amount property, by letting the user set it, or just through your own trial and error experiments. You will then have a value in milliseconds for your buffer, since that’s how normal people keep track of time. You then convert this millisecond value to a UInt64 amount using the conversion above.</p>
<p>Next, you want to convert your sequencer’s timing format to this same UInt64 format, if you aren’t already using it. You will have to figure out how to do this based on how the timing in your sequencer is set up. You want to know the time, in audio host UInt64 form, when the first equivalent audio packet to your MIDI packet will be fed to the render function. For example the time of the first audio packet in a note is equivalent to when you want to send a MIDI note on, so that is the time you need to calculate in audio host UInt64 form to know when to tell CoreMIDI that the note should be sent. Again, you are probably already doing something like this so you can tell your audio unit exactly when to start playing a sound, but you might not be using the audio host UInt64 as your base time reference format. You’ll need to either convert to and from it, or change your sequencer code to also keep track of and use it.</p>
<p>Finally, you calculate when you will need to give the packet to CoreMIDI by taking the actual time that event is supposed to trigger, and subtracting your buffer amount, since you want to give it to CoreMIDI early. This will be the point in time when you will hand off the MIDI packet to CoreMIDI, a bit before the actual event so it has time to process it. When the actual event occurs, your audio event will trigger and CoreMIDI will handle the MIDI portion based on the timestamp you gave it.</p>
<p>To summarize:</p>
<ol>
<li>At time X you give your MIDI packet to CoreMIDI, with a timestamp of X+Y, with Y being the buffer amount</li>
<li>At approximately time X+Y, you will be doing your equivalent audio processing in your render callback for that event</li>
<li>At approximately time X+Y, CoreMIDI will also be sending your MIDI packet out</li>
</ol>
<p>To get back to MIDI clock, as mentioned before you will be sending out 24 clock messages per quarter note. You want to send them out early by the amount of your latency buffer, and put a timestamp on each one. Ideally, your sequencer will have a timing resolution small enough to send these messages out individually. If your sequencer’s smallest resolution is greater than 24PPQ, you have a couple options: increase the timing resolution, or send out multiple messages at each of your smallest ticks.</p>
<p>The second option will work perfectly fine, you just queue up multiple Clock messages using <strong>MIDIPacketListAdd()</strong>, tagging each packet with an equally spaced timestamp, and then send them all out with <strong>MIDISend()</strong>. If for example your smallest clock resolution is a 1/16th note, which is 1/4 of a quarter note, you would then queue up 24/4 or 6 MIDI Clock messages at a time. You would calculate out the theoretical delta time between those packets based on a 1/96 (1/24 for each 1/4) note at your current tempo, we’ll call that Z. Given our X and Y times as described above in the summarize section, at time X with buffer Y (meaning you want that first Clock packet to be sent by CoreMIDI at time X+Y) you would queue up and hand off six MIDI Clock packets with timestamps X+Y, X+Y+Z, X+Y+2Z, X+Y+3Z, X+Y+4Z, and X+Y+5Z.</p>
<p>You hand off multiple Clock messages to CoreMIDI ahead of time, it sends each of them out at precisely the time you tell it to, resulting in the receiving device/app seeing an extremely stable MIDI clock.</p>
<p><strong>TIME&#8230; IS ON MY SIDE&#8230; YES IT IS<br />
</strong></p>
<p>MIDI Clock and MIDI Note messages are both MIDI messages, but they are obviously very different. Clocks are sent regularly with an identical packet format, Notes may be sent irregularly and have several fields such as channel and note value that will not be the same for different messages. You may find that you want to send your Clock messages and Note messages early by separate amounts to account for these differences. Clock messages require very precise timing, but are very regular and predictable, and their timing won’t change unless the tempo changes. Note messages, on the other hand, will need to be filled out depending on how the user modifies the note sequence, and how early you want to send those notes depends on how willing you are to tolerate lag versus how responsive you want to be to user changes.</p>
<p>If you use too large a latency when sending out MIDI Notes, the user will notice that the changes they make to the note sequences take a while to actually be heard, but the notes will arrive with perfect timing. A shorter latency value allows user changes to take effect more quickly, but the notes coming out may occasionally glitch. A good way to test this is to send out a long series of identical 1/16 or 1/32 notes under various conditions. You will quickly hear those glitches.</p>
<p>A large latency in clock values will be heard as a slightly lagged response to tempo changes, which depending on how dramatic those changes are might be much less noticeable. A shorter latency will again make jitter very apparent. In my experience, unless your app specifically needs to react to continuous and significant tempo changes, you can use much larger latency values on the clock to ensure it is extremely steady without losing too much in responsiveness. As mentioned before, I&#8217;ve used values of up to 200ms for network WiFi situations, resulting in a very stable clock even under terrible conditions.</p>
<p>For a third case, one thing that we can’t send early is anything that happens in real time: notes played on a virtual keyboard, real time taps on a drum pad, control data from a finger drag on an X-Y pad, etc. All of these happen in real time after being triggered by the user, and since we can’t reliably predict the future, we can’t know what the user is going to do ahead of time, and can’t send these messages early. They should always just be sent immediately, and if they do lag, there’s literally nothing that can be done about it.</p>
<p>This can also be a problem for our clock and sequenced data if they are affected in any way by real time user input. A primary example would be adjusting a slider that changes the tempo. In this case, we have clock and note data that needs to be sent early to correct for connection lag, but the data is being directly affected by real time input. Again, it is impossible for us to predict the future to know when the user will change the tempo. The end result is the tempo change will end up lagging by the size of your buffer. You will need to decide how important it is to track real time tempo changes versus how important it is to have rock solid consistent timing when setting the size of the buffer.</p>
<p>One very nice thing about CoreMIDI’s event handling is that you can send it multiple packets at different times with timestamps that are out of order and it will sort everything out for you. So if you are up for dealing with the complexity on your end, you can send it your clock messages 250ms early, your notes 100ms early, and your control data immediately as it happens, and CoreMIDI will sort all the timestamps out and send things out to their destination at their proper time, no matter when it received those various types of packets from you.</p>
<p>One last tricky thing to tackle when dealing with our MIDI clock is how to handle starting things up when we use large latency buffer values. For example, let&#8217;s say we have a clock buffer of 100ms, a tempo of 120BPM, and the user hits the start button on our app. We have two choices here, we can either:</p>
<li>Add 100ms of latency to the user&#8217;s start action, and just queue all MIDI messages normally 100ms in advance
</li>
<li>Send MIDI Start immediately, and immediately queue up MIDI Clock messages sent less than 100ms early until we&#8217;ve queued up more than 100ms worth of them, then queue all subsequent Clock messages normally 100ms in advance.
</li>
<p>The first option is the easiest, but with large latency buffers on the order of 100ms-200ms the user isn&#8217;t going to be very happy if they are trying to do something like manually sync the app to the sound of a record playing. On the other hand, we&#8217;re the master clock so if they are only trying to sync to connected MIDI slaved devices, this approach will work fine.</p>
<p>The second option is a bit more complicated, because it requires you to handle your clock in two separate phases: the startup phase where it&#8217;s catching up to the buffer by sending MIDI messages in real time or close to real time, and the normal phase where it&#8217;s sending out clock messages with the regular latency buffer. During the startup phase, we are not buffering by the full amount so the clock might be a bit jittery, however since this phase won&#8217;t last long it may not be a big deal. This is the approach I&#8217;ve taken with my apps, because I have DJ users who do want to manually beat match along to separate un-synced audio tracks. Having a 100-200ms delay may also just be a bit disconcerting to musicians who are sensitive to timing. Again, a latency vs. solid timing tradeoff will need to be made based on your particular app.</p>
<p><strong>I BELIEVE IT, AND I BELIEVE YOU’RE RECEIVING IT<br />
</strong></p>
<p>By now you should have a pretty good idea about how to set up your app to send MIDI clock and be the clock master device. Next, we need to figure out how we are going to receive MIDI clock so that your app can slave to the clock of a sequencer running on a laptop, an external drum machine, or another app. Again we’ll start with a very basic implementation, figure out where it falls short, and then think a little bit about how to improve it.</p>
<p>You will receive incoming MIDI Clock messages in your MIDIReadProc callback function, as described in <a href="http://syntheticbits.com/blog/?p=878">part two</a>. Per the MIDI spec you should expect to receive 24 MIDI Clock messages per quarter note, so you’ll be receiving a lot of them. As we covered above, these are very simple messages, they are just ticks or pings with no real content in the message itself. What matters to you is when they arrive.</p>
<p>Note that you will probably want to process these MIDI Clock messages differently than other messages since there are so many of them. At 120bpm you’ll be receiving 48 clock messages a second, which is a lot of messages. As we’ve mentioned before though, the messages do not carry any interesting information, you are only interested in the fact that this “ping” has been received at a certain time. All you will need to do is something simple and quick to keep track of them being received, and then you can discard the message.</p>
<p>For example, for a first-try basic implementation, whenever you receive a new MIDI packet in your callback function, instead of doing any complex processing just check the status byte to see if it&#8217;s a MIDI Clock message. If so, increment a count of how many of the MIDI Clock messages have been received. If the packet isn&#8217;t a MIDI Clock message, you&#8217;ll also probably want to check whether it&#8217;s a MIDI Start of MIDI Stop message, and only increment the MIDI ticks when you&#8217;ve received a start but not a stop. If the packet isn&#8217;t any of those messages, forward the packet as you normally would to your MIDI input processing function on another thread.</p>
<p>Elsewhere in your code, where your sequencer does its magic of deciding when to send the next note or calculate tempo to sync your LFOs, check that simple tick counter to see if you need to increment another step in your sequencer. Depending on the lowest resolution/granularity of your sequencer, this could be every 3 or 6 or 12 clock messages. Once you’ve passed that threshold, increment your sequencer another tick and trigger a new note, re-calculate your LFO speed, etc.</p>
<p>If you try this, you’ll find yourself on the other end of the jitter/latency problem we talked about above: your sequencer will increment properly in time with the external clock, but it will likely be to some extent unsteady depending on how long it is taking CoreMIDI to hand each of the Clock messages off to you. If you are talking to another CoreMIDI iOS app that is buffering its clock messages early, you might actually notice this jitter less because the CoreMIDI code on the other side may be handing the CoreMIDI code on your side the packets a bit early, helping to work around the problem! Remember that when you are picking a buffer in the send direction: you can actually improve other apps performance and help them out by choosing a larger buffer.</p>
<p>The bottom line is we need to figure out some way to prevent timing glitches caused by MIDI Clock packets that for whatever reason are given to us a bit late. If an individual packet is delayed, there is no way we can process it before it arrives, since that is physically impossible. So we need to find some way to smooth these incoming Clock messages and anticipate them, even if they arrive too late to trigger our sequencer properly.</p>
<p>Fortunately, with Clock messages we have some good options to accomplish this smoothing. As we&#8217;ve mentioned before, the clock is a regular and somewhat predictable series of ticks, rather than an irregular, unpredictable message to turn a given note on or change the value of a controller. We can’t accurately predict what the next note the user might press and when they’ll do it, that is impossible. But, we can make a guess about when one of those many MIDI Clock messages will probably arrive based on the current tempo, and if it turns out we were wrong, that just means the change in our tempo will lag a little bit.</p>
<p>Smoothing the incoming clock data will involve keeping a running averages of the tempo and song position to try to predict future clock messages, and firing off clock events to your sequencer whether or not a clock message actually arrived when you expected it to. You can think of this as having two separate timing engines: the first is driven by incoming clock messages, and uses the average timing information of those received ticks to output its own steady clock. The second engine is your sequencer, which uses that steady output of the first engine to increment itself step by step. Depending on your implementation, this will likely require keeping a history of received clock messages, including the time when they were received, and using that to calculate the running averages and predict when the next MIDI Clock message should arrive.</p>
<p>One nice thing about CoreMIDI is that incoming MIDI messages contain a very accurate timestamp of when that MIDI message was received at the lowest software driver levels. This allows you to make more accurate timing calculations even if the MIDI packet wasn’t immediately handed to your callback function by CoreMIDI. So one approach to predicting future/current MIDI Clock messages would be to use those very accurate timestamps from earlier packets, plus a running average of the normal delta between Clock packets, and then calculate when each future packet should arrive. When a packet &#8220;should&#8221; arrive, you tell your sequencer that it did, even if you don&#8217;t know for sure if it has yet.</p>
<p>Of course, even the lower levels of CoreMIDI might occasionally receive a packet with an oddball timestamp that throws everything off, for example if the master clock device or the physical connection has a glitch. Since outliers can negatively affect the calculation of an average, you may want to detect and throw them out, using a median approach rather than a strict mean, or just discarding data that is outside the normal bounds you would expect. In general though, your approach will be to keep a history of past packets, and use the average time received and average time between packets to guess when the next packet “should” arrive, and run your internal clock on this model rather than actual received packets.</p>
<p>Averaging methods used to smooth incoming jittery data will rely on predicting current and future packet times based on past packet times. This should work well in a situation where you have a stable, steady clock tempo coming in. The primary drawback is that if the master clock actually is trying to change the tempo, then you will lag those changes a bit since your algorithm will initially assume the tempo change is jitter and try to smooth it. How well you smooth your incoming data will directly affect how much you lag incoming tempo changes, so once again you will need to experiment with different buffer amounts to examine the trade off and determine the best behavior for your app.</p>
<p>Your final challenge will be getting your app to send MIDI clock out while slaved to a MIDI clock in. In theory this should be easy: just forward on any MIDI clock message that you receive. Unfortunately, due to these latency issues we’ve been discussing, that just won’t work: we will have a jittery clock on the receive side unless we smooth it out, combined with a jittery clock on the send side unless we send early. Whether you want to handle this case is up to you. I speak from experience when I say it’s tough to get right, in truth I haven’t really gotten it completely right myself yet. Essentially you will need to be buffering things on both ends, which depending on how you have things set up may or may not result in weird unpredictable results in practice, particularly when the app is first starting up the sync process. Give it a try once you’ve got everything else figured out. If you can get this one working reliably under tough variable latency conditions, you win the iOS MIDI clock grand prize.</p>
<p><strong>IT’S TRICKY, IT’S TRICKY<br />
</strong></p>
<p>Timestamps were one big step towards improving the performance of our MIDI processing. You might still be experiencing intermittent lag and latency when the user interacts with the UI. Try this out by moving a slider around while MIDI data is going in or out. You will probably notice that while you move the slider, your MIDI processing timing gets a lot flakier.</p>
<p>This is because so far we’ve been doing most of our MIDI processing in the main thread, which also handles UI tasks. So if the UI is busy doing something, such as processing a complicated touch event, our MIDI routines might be at the back of the line for processing time and noticeably lag. For some applications that might be okay, but for most it is not acceptable.</p>
<p>What we want is something that sits between CoreMIDI’s super high priority thread where we aren&#8217;t allowed to do very much, and the main thread’s medium priority thread that can get bogged down by UI and other tasks. To do this we will need to create our own thread with a priority in between.</p>
<p>A complete discussion of using threads is beyond the scope of this article. Here are some links to some information about how to set threads up, run code on them, and the sorts of pitfalls that await you when you try to do that:</p>
<p><a href="http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/">Apple&#8217;s documentation on multi-threading</a><br />
<a href="http://stackoverflow.com/questions/1004845/where-can-i-find-a-good-tutorial-on-iphone-objective-c-multithreading">Where can I find a good tutorial on multi-threading in iOS?</a><br />
<a href="http://stackoverflow.com/questions/2584394/iphone-how-to-use-performselectoronthreadwithobjectwaituntildone-method">How to use performSelector:onThread:withObject:waitUntilDone:</a><br />
<a href="http://stackoverflow.com/questions/1338891/nsthread-nstimer-and-autoreleasepools-in-an-iphone-sdk-application">NSThread, NSTimer and AutoreleasePools in an iPhone SDK application</a><br />
<a href="http://stackoverflow.com/questions/4741568/threading-priorities-and-abandonment">Threading priorities and abandonment</a><br />
<a href="http://stackoverflow.com/questions/249022/nsthread-with-nsautoreleasenopool-error">NSThread with _NSAutoreleaseNoPool error</a><br />
<a href="http://developer.apple.com/library/iOS/#documentation/Cocoa/Reference/Foundation/Classes/NSThread_Class/Reference/Reference.html">Apple NSThread Class Reference</a></p>
<p>Also note that the multi-thread approach I will describe below is based on code I wrote for FunkBox, which has a minimum iOS version of 3.0. If you are writing a newer app with a minimum iOS requirement of iOS 4.0 or even 5.0 (I envy you!), be sure to read up on <a href="http://cocoasamurai.blogspot.com/2009/09/guide-to-blocks-grand-central-dispatch.html">blocks</a> and other fun new ways you might be able to do the same thing easier and more safely.</p>
<p>Disclaimers aside, I’ll now cover what we need to do for a simple MIDI thread. First, you need to allocate and initialize an NSThread. Next you need to give it a run loop, in which you need to pay particular attention to setting up an autorelease pool. You can find an example of how to some of this stuff <a href="http://stackoverflow.com/questions/2584394/iphone-how-to-use-performselectoronthreadwithobjectwaituntildone-method">here</a>, again the subject requires much too much depth for me to cover adequately in this article.</p>
<p>Next, you want to set the <strong>threadPriority</strong> nice and high. The whole reason we are doing this is to try to help prevent the UI functions from hogging up processing resources and denying our MIDI processing a chance to run, so the priority needs to be higher than the main thread that is handling those UI functions. Keep in mind when putting things on the MIDI thread, though, that since they are running at a higher priority they should be relatively efficient and not hang up, otherwise you could get the reverse situation where MIDI processing adversely affects your UI performance. On a UI-centric platform like iOS that would be bad, particularly if the data that&#8217;s bogging you down is not important, for example parsing through large amounts of MIDI controller messages on a channel you aren&#8217;t even interested in. Thread priorities go from 0.0 to 1.0, you&#8217;ll want to aim for the high end of the range with this thread.</p>
<p>Finally, if you have never worked with threads before, a healthy amount of caution and even fear is in order. That doesn’t mean don’t use threads, it just means you should always be on your toes and be paranoid that they might be contributing to that weird sometimes-occurring problem that causes your app to crash. Be especially careful with what variables you create, release, and change inside your threads, as this will generally be the root of your problems. When you are working with threads, expect that things will get processed in unintuitive orders and ways. And when writing code that will be run on this thread, think very carefully about how it will interact with all of your other code.</p>
<p>When in doubt, try to treat it like a slightly more forgiving CoreAudio render callback: do as little as possible, as quickly as possible, as safely as possible, and then get out.</p>
<p>Okay, we now have our own nice custom thread up and going! We do still have to be a little careful using it, but it will help us out a lot as far as improving MIDI processing responsiveness. So how do we get the MIDI stuff running on there? Going back to Part 2, you’ll remember that we hand MIDI input processing off to the main thread using <strong>performSelectorOnMainThread:</strong>. We’ll use a similar method to run things on our own custom thread, but instead using <strong>performSelector:onThread:</strong> with a reference to our MIDI thread. We will want to do the same thing on the send side, within our sequencing code, when we have notes or clock data to send out.</p>
<div id="attachment_1267" class="wp-caption aligncenter" style="width: 405px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/performselector.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/performselector.jpg" alt="" title="performselector" width="395" height="87" class="size-full wp-image-1267" /></a><p class="wp-caption-text">Using performSelector:OnThread to run things on your MIDI thread</p></div>
<p>Now try the slider again and you should notice that MIDI performance will no longer be adversely affected when you move the slider continuously, since MIDI data is now being handled in a separate thread with a higher priority. Obviously this could potentially have some drawbacks as well: if you are sending a lot of MIDI data (several continuous controller values continuously cycling through values, such as with a fast LFO for example) the responsiveness of your user interface may suffer. As you&#8217;ve had to do throughout part 3, you&#8217;re going to have to experiment to figure out how much MIDI processing you can get away with while still having acceptable UI app performance. And always keep in mind that things will perform differently on different devices, so be sure to test this on your oldest, slowest device as well as your fastest one, because things that seem to work great on one of them might not work as well, or at all, with slightly slower or faster timing.</p>
<p><strong>TRICKSY MIDI, HE HATES US<br />
</strong></p>
<p>Finally, here are a couple more CoreMIDI functions you might find useful in specific situations:</p>
<div id="attachment_1254" class="wp-caption aligncenter" style="width: 247px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/midirestart.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/midirestart.jpg" alt="" title="midirestart" width="237" height="86" class="size-full wp-image-1254" /></a><p class="wp-caption-text">CoreMIDI&#039;s MIDIRestart() function</p></div>
<p>Sometimes things are going to get a little wonky. Devices have been plugged in or disappeared, network connections are popping in and out, notes are hung. You should in theory be able to handle most of this, but sometimes for whatever reason, things just stop working and it doesn’t really matter why or who’s to blame, they’re just broken. And you and your users just want everything to work again. I’ve found in these situations calling <strong>MIDIRestart()</strong> helps get things back on track. This is good to call if you have a MIDI panic button. It can be good to call if you’re connecting things or disconnecting things, just to make sure everything still works. In general, I just call it whenever I’m changing MIDI configurations, just to be safe.</p>
<div id="attachment_1255" class="wp-caption aligncenter" style="width: 316px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/08/midiflush.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/08/midiflush.jpg" alt="" title="midiflush" width="306" height="145" class="size-full wp-image-1255" /></a><p class="wp-caption-text">CoreMIDI&#039;s MIDIFlushOutput() function</p></div>
<p>As we’ve discussed above, you generally want to send MIDI clock and note messages early. At some point though, you need to stop, and you might want to do that immediately. However, since you were sending things early with timestamps, you might have already queued up a bunch of CoreMIDI messages to be sent. <strong>MIDIFlushOutput()</strong> called on each active MIDI endpoint will, in theory, get rid of those so that you actually do stop when you want to stop. In practice, CoreMIDI appears to send out network MIDI packets early across the network so they are receive at the right time on the other end, so you won’t be able to flush anything that has already left your device. But you should be able to get rid of anything waiting to be sent. </p>
<p><strong>NEXT TIME&#8230;<br />
</strong></p>
<p>If you’ve implemented everything so far, your MIDI-enabled music app should be looking pretty good! You have improved its timing and performance, and can send or receive MIDI clock. For a lot of apps, this might be all you need to implement: most users will be perfectly happy with just these features. But, if you’re interested in adding some more cool stuff to let your app connect to other apps on other devices, or even run alongside and sync up together with other apps running simulatenously on the same device, you’ve still got some more work ahead of you. We’ll cover the first one by talking about how to set up network MIDI connections with other devices next time in part four.</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=1213</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multi-tasking MIDI, with FunkBox, Little MIDI Machine and the MonoTribe</title>
		<link>http://syntheticbits.com/blog/?p=1232</link>
		<comments>http://syntheticbits.com/blog/?p=1232#comments</comments>
		<pubDate>Sun, 31 Jul 2011 03:48:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=1232</guid>
		<description><![CDATA[Here&#8217;s our latest MIDI related video. This shows our FunkBox app synced up via CoreMIDI with our Little MIDI Machine app. They are both running on the same iPad at the same time. Little MIDI Machine is sending notes out to the Studio Electronics Omega 2 hardware synth, you can see it below the iPad, [...]]]></description>
			<content:encoded><![CDATA[<p><object width="560" height="349"><param name="movie" value="http://www.youtube.com/v/gTXdzpAmEYc?version=3&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/gTXdzpAmEYc?version=3&amp;hl=en_US" type="application/x-shockwave-flash" width="560" height="349" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Here&#8217;s our latest MIDI related video. This shows our FunkBox app synced up via CoreMIDI with our Little MIDI Machine app. They are both running on the same iPad at the same time. Little MIDI Machine is sending notes out to the Studio Electronics Omega 2 hardware synth, you can see it below the iPad, it is playing two different synth lines. FunkBox is playing the drum beats, and sending MIDI clock to my new Korg MonoTribe synth on the right to sync it up, using Korg&#8217;s SyncKontrol app running on an iPod Touch.</p>
<p>The multitasking background-audio-capable version of Little MIDI is currently being tested and will be released soon!</p>
<p>The iPad is in an Alesis Studi/o dock, which provides MIDI and audio ins and outs. It works great and really makes iPad music apps feel like actual music hardware.</p>
<p>Also coming soon for the devs is CoreMIDI part 3&#8230; really&#8230; any day now&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=1232</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CoreMIDI Brain Dump, Part 2: Basic MIDI</title>
		<link>http://syntheticbits.com/blog/?p=878</link>
		<comments>http://syntheticbits.com/blog/?p=878#comments</comments>
		<pubDate>Thu, 09 Jun 2011 17:53:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Dev Info]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=878</guid>
		<description><![CDATA[This is part two in a series of five posts discussing the use of CoreMIDI in iOS music apps. These five posts are being written to help celebrate five years of the Palm Sounds blog. As a music app developer you want to stay plugged in to the mobile music app scene, and Palm Sounds [...]]]></description>
			<content:encoded><![CDATA[<p>This is part two in a series of five posts discussing the use of CoreMIDI in iOS music apps. These five posts are being written to help celebrate five years of the <a href="http://the-palm-sound.blogspot.com/">Palm Sounds</a> blog. As a music app developer you want to stay plugged in to the mobile music app scene, and Palm Sounds is a great place to do that, so check it out!<br />
<br />
<a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/coremidititle.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/coremidititle.jpg" alt="" title="CoreMIDI title" width="500" height="180" class="alignnone size-full wp-image-1226" /></a><br />
<br />
<strong>WELCOME BACK MY FRIENDS</strong></p>
<p>Hey there, welcome back to the CoreMIDI brain dump. The last article was about familiarizing yourself with how CoreMIDI is used so you would know what you wanted to do, and would be able to test it. Part two will be about actually getting some basic MIDI functions working in your app, which is really all you were interested in hearing about in the first place, right? Let’s get to it then.<br />
<br />
Here’s what we want your app to be able to do by the end of Part 2:</p>
<ul>
<li>Set up a quick and easy USB and Network CoreMIDI configuration
</li>
<li>Respond to MIDI configuration changes
</li>
<li>Send basic MIDI notes
</li>
<li>Receive basic MIDI notes
</li>
</ul>
<p></p>
<p>Here is what we will <strong>not</strong> be covering in this post, but that you can think about as we talk about the basic stuff:</p>
<ul>
<li>MIDI clock, CC/SYSEX messages (some of that’s next in Part 3)
</li>
<li>Latency compensation and other performance improvements (also Part 3)
</li>
<li>Setting up multi-device configurations (that’s Part 4)
</li>
<li>Setting up multi-tasking configurations (that’s Part 5)
</li>
</ul>
<p>
In order to get this basic setup working, we’re going to be studying Pete Goodliffe’s <a href="http://goodliffe.blogspot.com/2010/10/using-coremidi-in-ios-example.html">PGMidi sample project</a> (with updates <a href="http://goodliffe.blogspot.com/2010/11/sending-midi-through-coremidi.html">here</a> <a href="http://goodliffe.blogspot.com/2011/01/more-ios-midi-using-networked-midi.html">here</a> and <a href="http://goodliffe.blogspot.com/2011/02/pgmidi-updated.html">here</a>) to give us some real code to work with. Pete was the first, and as far as I know is still the only person so far who has been kind enough to release a working CoreMIDI sample project for iOS. If he hadn’t released it, I wouldn’t be writing these posts. You can thank Pete for being awesome and helping us all out by buying his new iOS game <a href="http://itunes.apple.com/us/app/the-enigma-squares/id433136664?mt=8">The Enigma Squares</a>.<br />
<br />
<span id="more-878"></span></p>
<p>If you&#8217;re using Open Frameworks with your app rather than native objective C, and looking at the PGMIDI code has you a little baffled because you&#8217;re not really a Cocoa/Objective C person, be sure to check out <a href="http://michaelaldridge.info/post/7393386507/coremidi-within-openframeworks">Michael Aldridge&#8217;s Sample Code to use CoreMIDI with Open Frameworks</a> which will show you how to integrate PGMIDI with Open Frameworks!</p>
<div id="attachment_958" class="wp-caption aligncenter" style="width: 530px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/simulatormidi.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/simulatormidi.jpg" alt="" title="Debugging network CoreMIDI with the simulator" width="520" height="348" class="size-full wp-image-958" /></a><p class="wp-caption-text">Debugging network CoreMIDI with the simulator</p></div>
<p>Go ahead and grab the <a href="http://gitorious.org/midimonitor/midimonitor">PGMidi sample project</a> code now if you haven’t already, and get it running in the XCode simulator. The PGMidi sample app will enable the CoreMIDI network session when it starts up, so you will be able to debug the app using the simulator. You will need to run Audio MIDI Setup on the same computer and connect to “iPhone Simulator” as seen in the above picture.</p>
<p>Verify this works by also loading up the <a href="http://www.snoize.com/MIDIMonitor/">MIDI Monitor</a> application on your Mac, and then send some MIDI notes from Pete’s app running in the simulator by clicking on the &#8220;Send MIDI&#8221; button in the lower right corner. You should be able to see some actual MIDI Note On and Note Offs messages that were sent from the simulator being received by the Mac. Success! Now we’re ready to kick some ass! Let’s get down to business and&#8230;</p>
<p><strong>FREEZE FRAMEWORK<br />
</strong></p>
<p>&#8230;go back to <a href="http://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/CACoreMIDIRef/_index.html">Apple’s CoreMIDI Framework Reference</a> documentation. “What?!” you say, “but things were just getting cool?!”. Sorry Daniel-san, it’s time to go back to painting the fence.</p>
<p>In <a href="http://syntheticbits.com/blog/?p=508">Part 1</a>, I mentioned that this documentation is not that great to learn from. I still think that is true, it’s one of those documents that makes much more sense once you already mostly know what it’s trying to tell you about. As its name clearly states, it is a good reference, but it is not a guide or tutorial. So let’s look through it and we&#8217;ll try to find the good juicy bits that we’ll later see Pete using in his PGMidi Project.</p>
<div id="attachment_925" class="wp-caption aligncenter" style="width: 537px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/coremidiref.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/coremidiref.jpg" alt="" title="CoreMIDI Framework Reference files" width="527" height="359" class="size-full wp-image-925" /></a><p class="wp-caption-text">Various CoreMIDI Framework Reference parts</p></div>
<p>The stuff on the left is all related to configuring the CoreMIDI network session, so your app can send/receive MIDI over WiFi or Bluetooth. We’ll be looking at these some more in Part 4, but for now, Pete’s only going to use a quick method call to NetworkSession to enable it. So we can forget about these files on the left side for a while. If you decide to peek anyway, you&#8217;ll notice they are all nice familiar Cocoa style objects. Enjoy, because that&#8217;s the last you&#8217;ll be seeing of Cocoa.</p>
<p>The stuff on the right&#8230; well, MidiSetup.h sounds like something we&#8217;d want to use, but actually it isn&#8217;t. MidiThru.h looks cool but I’ve never used it. And none of it looks particularly Cocoa like, does it? It all looks pretty confusing when you start trying to figure out why you&#8217;d want to use it. Let’s just pretend we never clicked over there and ignore those files too for now, and hopefully forever.</p>
<p>That leaves only one documentation file, <strong>MidiServices.h</strong> kicking it by its lonesome in the middle. This file contains the majority of what we’re going to need to use for now. Sweet, eh? Just one file! Can’t be too hard to learn one dumb file! Let’s just click and take a quick glance through it and&#8230; uh, well then. Hmmm, there’s a lot of stuff there, isn&#8217;t there? Oh, and that was just the functions, there&#8217;s data types too? And constants? Okay, this all looks really useful but, uh, where do we start?</p>
<p>For now we just want to focus on figuring out how to do a basic setup, send simple packets, and receive simple packets. But it’s still not immediately obvious what parts of MidiServices.h we should be looking at to figure out how to do that, so I’ll help and point some of them out. Here are some of the important functions and types we’re going to be using to get started using CoreMIDI:</p>
<p>
<strong>MIDIPACKET FEVER, IT&#8217;S DRIVING ME CRAZY<br />
</strong></p>
<div id="attachment_927" class="wp-caption aligncenter" style="width: 335px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midipacket.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midipacket.jpg" alt="" title="MIDIPacket" width="325" height="168" class="size-full wp-image-927" /></a><p class="wp-caption-text">MIDIPacket data structure</p></div>
<p>The MIDIPacket data structure is the heart of what we’re doing here: sending and receiving packets of MIDI data. As you can see from the typedef, it’s a pretty simple structure: timestamp, length, and the actual data.</p>
<p>We’ll talk more about the <strong>timeStamp</strong> in Part 3, for now you only really need to know that it is the exact time you want the packet to go out on the send side, or the time it was received on the receive side. PGMidi just sets this to zero on the send side, which means “send it right now”, and ignores it on the receive side. It gets more complicated when we actually want to use it and have to convert to and from other time formats to do so, but for now we can just ignore it.</p>
<p><strong>length</strong> and <strong>data</strong> don’t need much explanation, you&#8217;re looking at the raw MIDI packet data you want to send and the length of that data in bytes.</p>
<p>MIDIPackets are always sent and received as part of a <strong>MIDIPacketList</strong>, which as you would expect is a list of individual MIDIPackets. To create a MIDIPacket, you actually create the MIDIPacketList first using CoreMIDI&#8217;s MIDIPacketListInit() function, which will initialize the MIDIPacketList and return a pointer to the first MIDIPacket in that list, which you will then use. More packets can be created and added to the list by calling MIDIPacketListAdd(). If this seems a bit confusing, and it is, you can see an example of how to do this in PGMidi.mm&#8217;s sendBytes: method.</p>
<p>To figure out what to put in those raw MIDI packets, you want to go look at the <a href="http://www.midi.org/techspecs/midispec.php">MIDI Specification</a>. This spec comes from a standards organization and costs money. Googling “MIDI Specification” will get you some free and easier to understand explanations of the same thing, I’m partial to <a href="http://home.roadrunner.com/~jgglatt/tech/midispec.htm">this one</a> but they all work and the spec is pretty much set in stone at this point so you don&#8217;t have to worry about conflicting revisions. These are MIDI specifications, not CoreMIDI specifications. They are describing the plain old 1985 style MIDI bits and bytes that were originally sent over wires and that CoreMIDI will send and receive in its data payloads. </p>
<p>Keep in mind that CoreMIDI is only concerned with getting chunks of data to and from a destination. It doesn’t care what&#8217;s in those chunks of MIDI, it doesn&#8217;t know whether they represent note ons and offs, controller messages, program change, etc, and it won’t help you format the packet data. If you hand it completely random and nonsensical data, it will happily pass it on. If the other side of your MIDI connection returns the favor, CoreMIDI will chuckle and dump that random data on you without a second thought.</p>
<p>Bottom line: CoreMIDI is only concerned with making connections, handling timestamps, and exchanging bytes, it is not involved with the actual MIDI data. You are on your own as far as packing up the bits that make the data you send out, and deciphering the incoming MIDI bits you are given. The MIDI specs will tell you how to do that.</p>
<p>
<strong>SHOW ME MIDISEND() THE FLOOR<br />
</strong></p>
<div id="attachment_928" class="wp-caption aligncenter" style="width: 322px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midisend.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midisend.jpg" alt="" title="CoreMIDI&#039;s MIDISend() function" width="312" height="152" class="size-full wp-image-928" /></a><p class="wp-caption-text">CoreMIDI&#039;s MIDISend() function</p></div>
<p>So we have our MIDIPacket and now we want to send it somewhere. Unsurprisingly, the function we use to do that is named <strong>MIDISend()</strong>. MIDISend takes three arguments:</p>
<p><strong>port</strong> is a MIDIPortRef, we&#8217;ll talk about these more later but for now you just need to know that your application has two of them, an input port and an output port. PGMidi will create two of these for your app in its init() method, and you will always use that same output port whenever you want to send data. So when we are calling MIDISend() we will point it to the output port.</p>
<p><strong>dest</strong> is a MIDIEndpointRef, this is an individual destination for MIDI data such as the Network Session, or a USB MIDI interface attached to the Camera Connection Kit. PGMidi manages these endpoints as the application is running, you might plug in a USB cable which will make a new endpoint available, or turn off the Network Session which would mean you would no longer want to send MIDI data there. The key takeaway here is that you will need to call the MIDISend function once for each of the endpoints that you want to send the data to.</p>
<p><strong>*pktlist</strong> points to the MIDIPacketList to be sent.</p>
<p>
<strong>I AIN&#8217;T NO MIDIREADPROC CALLABACK GIRL<br />
</strong></p>
<div id="attachment_930" class="wp-caption aligncenter" style="width: 540px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midireadproc1.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midireadproc1.jpg" alt="" title="CoreMIDI receive MIDI callback" width="530" height="136" class="size-full wp-image-930" /></a><p class="wp-caption-text">CoreMIDI receive MIDI callback</p></div>
<p>Sending stuff went pretty well, now of course we also want to be able to receive MIDI data. This one is a little trickier because we don’t decide when we’re going to receive things, we need to be given this data as soon as it comes in, whenever that is. To do this we need to register a callback function when we’re setting up CoreMIDI, telling it what to call when it has data to give us. The format of this callback function is described in the CoreMIDI documentation in the Callbacks section under <strong>MIDIReadProc</strong>.</p>
<p>PGMidi will register its callback function when it calls CoreMIDI&#8217;s MIDIInputPortCreate() function to create a MIDIPortRef. Remember it’s going to create one input port and one output port for the application, the input port will be linked with this function so that any input is sent there. PGMidi uses a static function called PGMIDIReadProc for its callback, so if you look at that function, you’ll see where received MIDI data is sent first.</p>
<p>An important thing to note about this callback is that it is being called in a high priority CoreMIDI thread. Much like a CoreAudio audio unit render callback, you want to limit the amount of processing here, and avoid allocating and deallocating objects. Any significant processing will need to be done once you’ve handed off the received data to another function running in another lower priority thread.</p>
<p>
<strong>CLIENTS AND ENDPOINTS AND PORTS, OH MY!<br />
</strong></p>
<p>We’ve talked about sending and receiving packets, but before we can do any of that we need to configure CoreMIDI so it knows where it can send to and receive from. This is actually where PGMidi does most of its work, and that’s a good thing, because it’s one of the more confusing parts to figure out without a general overview of how things work.</p>
<p>Glancing through the CoreMIDI framework documentation you’ll see references to ports, endpoints, entities, clients, devices, and there are explanations given for all these, but it’s hard to figure out what’s what in the context of a regular old iOS app. This is because the CoreMIDI docs need to describe what each part can theoretically do for any application, even if a lot of those uses are esoteric or overly abstract from a simple music app developer’s point of view. From the Apple CoreMIDI engineers perspective this makes sense, they are thinking through every different type of use when they develop the framework and need to be sure they have covered every case, especially the unusual ones. From the perspective of you and me, the lack of simple and practical examples can often make it really difficult to figure out what parts are actually important.</p>
<p>Anyway, here’s the quick guide. Like your Physics 101 class in college, my goal here is to get you to have a basic understanding of what&#8217;s going on that you can use to solve simple problems, even if the reality is I’m oversimplifying things in places. From your point of view, this is what these things do:</p>
<p><strong>MIDIClientRef</strong> will be created once when you’re setting up CoreMIDI. You create one of them, and always use the same one when CoreMIDI wants it to know who you are. Think of it as your app’s way of referring to itself when talking to CoreMIDI.</p>
<p><strong>MIDIPortRef</strong> will be used to keep track of your two ports: one input and one output. Once you create your client, you then create your input and an output ports and associate them with the MIDIClientRef, so your app can send and receive MIDI data. Even if you are receiving input from multiple places, it will all come through your one port. Likewise for the output, you may be sending notes over USB and clock over WiFi, but it’s all associated with your output port.</p>
<p><strong>MIDIEndpointRef</strong> is a more specific input or output, it is a specific USB interface or Network Session that you either send to or receive from. It is analogous to a physical MIDI cable that sends or receives 16 channels of MIDI information. You can have multiple endpoints coming in, multiple endpoints to send out to. These endpoints can also come or go as your application is running, if the user plugs in a new USB MIDI interface, for instance.</p>
<p>So let’s say you are sending MIDI data out to three different places: a drum machine attached to a USB MIDI interface, a laptop attached via WiFi, and to another app on the same device through a virtual port. Each of these three destinations will have a MIDIEndpointRef associated with them that you will use when calling MIDISend. Sending to one of the three destination will require you use your applications output MIDIPortRef, along with the specific MIDIEndpointRef of that destination.</p>
<p><strong>MIDIEntityRef</strong> is a collection of MIDIEndpointRefs, for example a simple 2&#215;2 USB MIDI interface will have a two inputs and two outputs, each of which is separate MIDIEndpointRef. The MIDIEntityRef owns all those endpoints, and is used to logically group them together. You don&#8217;t really care about this much for a simple app, but in some functions instead of asking for a MIDIEndpointRef, CoreMIDI will ask for a MIDIEntityRef. All you really need to know here is that if CoreMIDI wants a MIDIEntityRef, you can use CoreMIDI&#8217;s MIDIEndpointGetEntity() function and give it one based on your MIDIEndpointRef.</p>
<p>
<strong>CALIFOR-NOTIFICATION</strong></p>
<p><strong>MIDINotification</strong></p>
<div id="attachment_931" class="wp-caption aligncenter" style="width: 507px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midinotification.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midinotification.jpg" alt="" title="MIDINotification data structure" width="497" height="162" class="size-full wp-image-931" /></a><p class="wp-caption-text">MIDINotification data structure</p></div>
<p>The last CoreMIDI data structure we’re going to look at before getting back to PGMidi is <strong>MIDINotification</strong>. There isn’t much to see here in the structure itself, you just have the messageID and messageSize parameters that you use to figure out what the notification is telling you. The important thing here is that you will be receiving these whenever something changes: a new interface is added, a configuration is changed, an error occurs. When that happens, you’ll be passed a MIDINotification to your notification callback function, and you will need to handle it. That callback function is defined when you create your MIDIClientRef using CoreMIDI&#8217;s MIDIClientCreate() function, which PGMidi will take care of for you in its init() method. </p>
<p>You can see the type of notifications you’ll be sent by checking out the <strong>MIDINotificationMessageID</strong> constant list.</p>
<div id="attachment_932" class="wp-caption aligncenter" style="width: 392px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midinotificationid.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midinotificationid.jpg" alt="" title="MIDINotificationMessageID constants" width="382" height="232" class="size-full wp-image-932" /></a><p class="wp-caption-text">MIDINotificationMessageID constants</p></div>
<p>Alright, enough of that, we now have an idea about some of the lower level CoreMIDI data structures and functions we’ll be using. Let’s go back to Pete’s code and see how to actually put all these various parts together into a project that actually does something.</p>
<p>
<strong>HEY PGMIDI YOU&#8217;RE SO FINE YOU&#8217;RE SO FINE YOU BLOW MY MIND<br />
</strong></p>
<div id="attachment_935" class="wp-caption aligncenter" style="width: 410px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmidimonitor.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmidimonitor.jpg" alt="" title="PGMidi MidiMonitor app" width="400" height="375" class="size-full wp-image-935" /></a><p class="wp-caption-text">PGMidi MidiMonitor app</p></div>
<p>First of all, what is this project supposed to be doing? It is a basic MIDI Monitor that prints out anything that is received so you can test MIDI input. It will also let you send some random MIDI notes so you can test MIDI output. Finally it will set everything up and manage your MIDI connections so that you can react when things are plugged and unplugged. Most of the code is actually dedicated to that last part, setup and configuration, which is nice because it’s probably the part you care least about tweaking right now. The thing you probably want to be able to do at this point is get some MIDI in notes triggering sounds in your synth app, and have your virtual app keyboard triggering MIDI out notes, and you really just want enough configuration to let you do that.</p>
<p>So let’s take a look at the files in Pete’s sample project:</p>
<div id="attachment_938" class="wp-caption aligncenter" style="width: 270px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmidiproject.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmidiproject.jpg" alt="" title="PGMidi Project files" width="260" height="340" class="size-full wp-image-938" /></a><p class="wp-caption-text">PGMidi Project files</p></div>
<p>You&#8217;ll be re-using everything here that starts with PGMidi. You&#8217;ll be using your own code in place of anything that starts with MidiMonitor.</p>
<p>As you might expect, the most important parts of Pete&#8217;s code are located in <strong>PGMidi.mm</strong>. This is where he is doing most of his CoreMIDI setup, managing connections, handling notifications, and sending and receiving MIDI data.</p>
<p>Before we dive into there though, let’s look at what <strong>MidiMonitorAppDelegate.m</strong> and <strong>MidiMonitorViewController.m</strong> are doing, since these are files you won&#8217;t re-use, but are the parts that interface with PGMidi in the same way you will need to in your project. By looking at them, we can figure out what you will need to add to your own app to get it working with PGMidi.</p>
<div id="attachment_940" class="wp-caption aligncenter" style="width: 530px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/appdelegate.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/appdelegate.jpg" alt="" title="Initializing PGMidi in the app delegate" width="520" height="178" class="size-full wp-image-940" /></a><p class="wp-caption-text">Initializing PGMidi in MidiMonitorAppDelegate.m</p></div>
<p>Looking in the didFinishLaunchingWithOptions: method of <strong>MidiMonitorAppDelegate.m</strong>, we can see that he first checks to make sure we’re using a version of iOS that can use CoreMIDI. If so, he allocs and inits the PGMidi object, calls a method to enable the network session, and then links it up to the viewcontroller, which is MidiMonitorViewController. So far so good! Easy enough to do a similar setup in your own app delegate or elsewhere.</p>
<p>Next we will look at <strong>MidiMonitorViewController.m</strong>, first noting that this class is both a PGMidiDelegate and a PGMidiSourceDelegate. The PGMidiDelegate functions will give this class notifications about sources and destinations being added or deleted. The PGMidiSourceDelegate function provides the mechanism for receiving incoming MIDI packets.</p>
<p>One thing you will notice is that the various methods of MidiMonitorViewController.m display everything using the addString: method. This just takes input strings and puts them in a textview. It has nothing to do with CoreMIDI, but it’s the end result of pretty much everything that happens in this class: received MIDI input, errors, notifications, etc will all end up being sent to that textview.</p>
<div id="attachment_939" class="wp-caption aligncenter" style="width: 530px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midireceivedproc.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midireceivedproc.jpg" alt="" title="midiSource:midi midiReceived:packetList" width="520" height="170" class="size-full wp-image-939" /></a><p class="wp-caption-text">midiReceived:packetList delegate method in MidiMonitorViewController.m</p></div>
<p>Next let’s look that the <strong>midiReceived</strong> delegate method, which is where PGMidi is going to pass any MIDI data received from its CoreMIDI callback function. This is the function you will be modifying to do your MIDI input processing. Note that this method is being called in CoreMIDI’s high priority thread, so whenever it calls anything it makes sure to performSelectorOnMainThread to move the processing on to a lower priority thread, in this case the main thread. In Part 3 we&#8217;ll talk about setting up a dedicated MIDI thread for processing so that things like UI handling don&#8217;t cause hiccups in MIDI processing. For now though, we just want to move things out of that high priority CoreMIDI thread.</p>
<p>The other important part here is the for loop. It is processing the received packet list, packet by packet, and handing each one off to addString: to be printed. Unless you are also writing a MIDI monitor app, you will want to process these packets and figure out which are notes, clocks, etc instead of just printing them.</p>
<p>To do your custom processing, you will want to be looking at the raw MIDI information in packet->data[]. Again, you will want to do any significant processing in a lower priority thread, but you might want to peek at the data headers here to decide where to hand off the data. Individual MIDI clock messages, for instance, will be coming in so quickly you might want to process them differently than notes or control changes.</p>
<p>You can determine the type of MIDI data by peeking at the first byte in the packet, which will be in packet->data[0]. A value of 248 here will be a MIDI clock tick message, 250 will be a MIDI start message, etc. Anything more than a quick check of the header needs to be done in a lower priority thread.</p>
<p>Finally, note that while this MidiMonitor sample code does pass the incoming MIDI data off to a lower priority thread, the addString: function used to do so is creating a new string object in the high priority thread, which is probably not a great idea. It works fine but it&#8217;s not recommended to do that in this thread. The first code tweak you might try would be to replace this part by copying the incoming MIDI packet data into some pre-allocated memory and then passing it off to your processing function in another thread to be handled.</p>
<p></p>
<div id="attachment_1048" class="wp-caption aligncenter" style="width: 473px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midisourceadded.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/midisourceadded.jpg" alt="" title="sourceAdded: from MIDIMonitorViewController.mm" width="463" height="166" class="size-full wp-image-1048" /></a><p class="wp-caption-text">sourceAdded: from MIDIMonitorViewController.mm</p></div>
<p>We also see various PGMidiDelegate functions related to changing configurations: <strong>sourceAdded:</strong>, <strong>sourceRemoved:</strong>, <strong>destinationAdded:</strong>, <strong>destinationRemoved:</strong>. The heavy lifting of handling these setup changes is being handled by PGMidi, here we are just printing out some text about what happened. Do note, however, that when <strong>sourceAdded:</strong> is called we need to make ourselves the delegate of that PGMidiSource so that we will receive incoming MIDI input from it.<br />
</p>
<div id="attachment_941" class="wp-caption aligncenter" style="width: 399px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/sendmidibackground.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/sendmidibackground.jpg" alt="" title="sendMidiDataInBackground function" width="389" height="171" class="size-full wp-image-941" /></a><p class="wp-caption-text">sendMidiDataInBackground method in MidiMonitorViewController.m</p></div>
<p>The last thing we’ll look at here is the <strong>sendMidiDataInBackground:</strong> method which is called in a background thread when you press the send midi button in the app. Here he is sending out 20 random MIDI notes. You’ll notice that each note has a note on and then 0.1 seconds later he sends a corresponding note off. Here you also get your first taste of how to create that raw MIDI packet data that you’ll be giving to CoreMIDI. No objects here, son, we&#8217;re packing together raw bits.</p>
<p>As mentioned previously <a href="http://home.roadrunner.com/~jgglatt/tech/midispec.htm">this site</a> is a nice reference for the format of those MIDI packets. If you&#8217;re going to be doing anything complicated, you&#8217;d best be getting your bitwise operator and bit shift skills honed and ready, because you&#8217;ll need &#8216;em.</p>
<p>PGMidi sends all MIDI packets immediately, which is why he is sleeping the background thread for 0.1 seconds before sending a note off message. To send MIDI notes using the standard PGMidi methods you’ll need to do something similar. In Part 3 we’ll talk about how to set the timestamps for MIDIPackets so you can queue things up ahead of time, and hand both the note on and note off to CoreMIDI at the same time. These timestamps are also useful for sending your MIDI packets early to overcome the latency of, for instance, a network connection.</p>
<p>You will be replacing this function with your own code that sends MIDI note ons and offs. Most likely your app won&#8217;t need to send 20 random notes, so when you modify this function the first thing you&#8217;ll want to do is get rid of that for loop. Next, replace the RandomNoteNumber() function with the actual note pitch you want to be sent. For reference, 48 is a nice middle C.</p>
<p>Another thing that can be tweaked is the MIDI channel number: here the 0&#215;90 and 0&#215;80 values are sending note on and note offs to MIDI channel 1. To change it to channel 4, for instance, you would use 0&#215;93 and 0&#215;83. Also, the velocity of the note can be tweak by changing the 127 in the noteOn[] const to the velocity value you desire.</p>
<p>Using this information, you should be able to easily rewrite this function to take a few arguments like note pitch, channel, and velocity, and send PGMidi some useful MIDI data packets instead of the random ones.</p>
<p>
<strong>PGMIDI TREATS OBJECTS LIKE WOMEN, MAN<br />
</strong></p>
<p>Let’s take a look at the <strong>PGMidi.h</strong> and <strong>PGMidi.mm</strong> files:</p>
<div id="attachment_942" class="wp-caption aligncenter" style="width: 350px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmidiobject.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmidiobject.jpg" alt="" title="PGMidi object" width="340" height="108" class="size-full wp-image-942" /></a><p class="wp-caption-text">PGMidi, from PGMidi.h</p></div>
<p>Pete’s MidiMonitor app has one <strong>PGMidi</strong> object, it is created in the app delegate and manages CoreMIDI for the lifetime of the app. It creates a MIDIClientRef, client, that CoreMIDI will use to identify your app. It also creates two MIDIPortRefs, an outputPort and an inputPort, which are used to send/receive all MIDI packet data to/from CoreMIDI. It has a delegate that it will inform of changes to the MIDI configuration, when sources or destinations are added. And finally it has arrays of sources and destinations, which hold PGMidiSource and PGMidiDestination objects that manage your CoreMIDI connections.</p>
<div id="attachment_943" class="wp-caption aligncenter" style="width: 434px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmidimethods.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmidimethods.jpg" alt="" title="PGMidi methods, from PGMidi.h" width="424" height="87" class="size-full wp-image-943" /></a><p class="wp-caption-text">PGMidi methods, from PGMidi.h</p></div>
<p>PGMidi has a few methods that can be called. You should call <strong>enableNetwork:</strong> right after initializing your PGMIDI object to enable the CoreMIDI Network Session, so you can send and receive data over WiFi or Bluetooth. There is really no good reason not to do this, especially if you are a sound source like a synth, since it will allow other apps on other devices to connect to you and send you MIDI data.</p>
<p>In Part 4, we&#8217;ll talk about how your app can look for other devices and connect with them. For now, by enabling the network session we at least allow other apps on iOS devices, and Macs running Audio MIDI Setup, to connect with us. You can verify that by running MidiMonitor on one of your test devices, and <a href="http://itunes.apple.com/us/app/modrum-synthesis-based-drum/id408872480?mt=8">MoDrum</a> on another test device. You&#8217;ll notice the device running the PGMIDI Monitor will show up in MoDrum&#8217;s MIDI Setup connection list as long as the PGMIDI app is running.</p>
<p>The other two methods in PGMidi are <strong>sendBytes:</strong> and <strong>sendPacketList:</strong>, these are useful to broadcast MIDI data to every available output. When you are first putting CoreMIDI in your app, if you don’t want to worry about configuring which outputs to send things to and just want to blast it, call these PGMIDI send methods instead of the ones in the individual PGMidiDestinations.</p>
<p>Peeking in PGMidi&#8217;s init function, you can see it first creating a MIDIClientRef and then setting up two MIDIPortRefs, inputPort and outputPort. Finally it calls the scanExistingDevices method, which will add all available MIDIEndpointRefs to PGMIDI&#8217;s sources and destinations arrays. We&#8217;ll cover this function in a little more depth below.</p>
<p>The remaining private methods defined in <strong>PGMidi.mm</strong> are used to handle notifications, and connect and disconnect sources and destinations. You shouldn’t need to tinker with any of these for now, since PGMidi will let you know what’s happening via the PGMidiDelegate protocol, and then you can just look through the sources and destinations arrays. At some point, once things are working and you&#8217;re feeling more curious, you will want to look through these methods to see how and when PGMidi is calling the lower level CoreMIDI functions to connect and disconnect MIDIEndpoints.</p>
<div id="attachment_944" class="wp-caption aligncenter" style="width: 540px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmididelegatefuncs.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmididelegatefuncs.jpg" alt="" title="PGMidiDelegate methods" width="530" height="116" class="size-full wp-image-944" /></a><p class="wp-caption-text">PGMidiDelegate methods, from PGMidi.h</p></div>
<p>PGMidi has four delegate methods we talked about before that are used to tell its delegate about sources and destinations being added and removed. As you can see above, they are named exactly as you would expect them to be. The part of your app designated as the PGMidiDelegate will need to implement these methods so that it can receive configuration change information from PGMidi.</p>
<p>Let&#8217;s take one more look at PGMidi&#8217;s init function in some more depth to see how it is setting up CoreMIDI for us, and the CoreMIDI functions it calls:</p>
<ul>
<li>1. It creates a MIDIClientRef and sets up PGMIDINotifyProc as a notification callback function using CoreMIDI&#8217;s MIDIClientCreate() function.
</li>
<li>2.It uses that MIDIClientRef to set up two MIDIPortRefs, inputPort and outputPort, using CoreMIDI&#8217;s MIDIInputPortCreate() and MIDIOutputPortCreate() functions. When creating the inputPort it also sets up PGMIDIReadProc as a callback function for incoming MIDI data.
</li>
<li>3.It calls the scanExistingDevices method, which will call CoreMIDI&#8217;s MIDIGetSource() and MIDIGetDestination() functions to get all available MIDIEndpointRefs and set them up as PGMIDISources and PGMIDIDestinations.
</li>
</ul>
<p>Again we see the familiar MIDIClientRef, MIDIPortRefs, and MIDIEndpointRefs. Most of the CoreMIDI set up that PGMidi is doing just involves creating, destroying, configuring, or connecting these for you.</p>
<p>
<strong>YES! NO! I DON&#8217;T WANT TO BE YOUR PGMIDI OBJECT<br />
</strong></p>
<p>The three other PGMidi.mm objects are <strong>PGMidiConnection</strong>, which describes a basic MIDI connection, and <strong>PGMidiSource</strong> and <strong>PGMidiDestination</strong>, which inherit from PGMidiConnection and have specific methods designed for sending or receiving MIDI data.</p>
<div id="attachment_945" class="wp-caption aligncenter" style="width: 367px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmididestination.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/pgmididestination.jpg" alt="" title="PGMidiConnection base class, PGMidi.h" width="357" height="149" class="size-full wp-image-945" /></a><p class="wp-caption-text">PGMidiConnection base class, PGMidi.h</p></div>
<p><strong>PGMidiConnection</strong> contains a link to the PGMidi object, a CoreMIDI MIDIEndpointRef for the connection, a string containing the name, and a boolean that tells you whether this connection is a network connection. Pretty straightforward stuff, you will need that MIDIEndpointRef when you want to send MIDI data, and you’ll use the name to sort through the different connections.</p>
<p><strong>PGMidiSource</strong> inherits everything from PGMidiConnection and adds a delegate for received MIDI data. When the PGMidiSource object receives incoming MIDI data, it will then hand it off to that delegate using -(void) midiSource:(PGMidiSource*)input midiReceived:(const MIDIPacketList *)packetList, which is a PGMidiSourceDelegate delegate method.</p>
<p><strong>PGMidiDestination</strong> inherits everything from PGMidiConnection and adds two methods, sendBytes: and sendPacketList:, which are similar to those same functions in PGMidi but in this case are used to send MIDI data only to this particular destination.</p>
<p>PGMidiSources and PGMidiDestinations are connected and disconnected using the <strong>connectSource:</strong>, <strong>disconnectSource:</strong>, <strong>connectDestination:</strong>, and <strong>disconnectDestination:</strong> methods. These will either be called by the scanExistingDevices() function during init(), or called when PGMidi receives a notification that a configuration change has occurred. If you look at connectSource and disconnectSource you will note that PGMidi is calling CoreMIDI&#8217;s MIDIPortConnectSource() and MIDIPortDisconnectSource() functions to associate (or disassociate) a given MIDIEndpointRef with the inputPort MIDIPortRef. The connectDestination and disconnectDestination do not need to do this, since you give the MIDISend() function a MIDIEndpointRef each time you send data.</p>
<p>The other PGMidixxx files in the project are tools to help find matching source/destination pairs if you&#8217;re trying to speak to one particular device amongst several available ones. For now, I wouldn&#8217;t worry about it but if you have some specific routing needs, check those files out.</p>
<p>
<strong>SUMMARY OF HOW PGMIDI HANDLES SETUP, MIDI SEND, MIDI RECEIVE</strong></p>
<p>Walkthrough of how PGMidi sets up CoreMIDI:</p>
<ul>
<li>PGMidi is alloced and inited in the app delegate, network session enabled
</li>
<li>PGMidi creates MIDIClientRef in init using CoreMIDI&#8217;s MIDIClientCreate() function
</li>
<li>PGMidi creates inputPort and outputPort MIDIPortRefs in init using CoreMIDI&#8217;s MIDIInputPortCreate() and MIDIOutputPortCreate() functions
</li>
<li>PGMidi creates PGMidiConnections with a call to scanExistingDevices: in init. These connections are based on CoreMIDI MIDIEndpointRefs
</li>
<li>After the initial setup, added and removed connections are handled with PGMidiNotifyProc notification callback that was defined in MIDIClientCreate() in PGMidi&#8217;s init
</li>
<li>The PGMidiDelegate (your code) is informed of configuration changes through sourceAdded: sourceRemoved: destinationAdded: destinationRemoved: delegate methods</li>
</ul>
<p>Walkthrough of creating and sending a MIDI packet using PGMidi:</p>
<ul>
<li>Create raw MIDI payload data in your app using the <a href="http://home.roadrunner.com/~jgglatt/tech/midispec.htm">proper MIDI format</a>
</li>
<li>Hand that chunk of data off to PGMidi via sendBytes:</li>
<li>PGMidi will put that data into a MIDIPacket data structure in a MIDIPacketList, using CoreMIDI&#8217;s MIDIPacketListInit() and MIDIPacketListAdd() functions</li>
<li>PGMidi will call the CoreMIDI MIDISend() function with that MIDIPacketList, for each MIDIEndpointRef/PGMidiDestination in its destinations array</li>
<li>MIDI data is sent out by CoreMIDI to its proper destination
</li>
</ul>
<p>Walkthrough of receiving MIDI input data using PGMidi:</p>
<ul>
<li>CoreMIDI calls PGMidiSource’s static PGMIDIReadProc callback function with a MIDIPacketList, in a high priority thread
</li>
<li>MIDIPacketList is passed to PGMidiSource’s non-static midiRead: function, still in that high priority thread
</li>
<li>PGMidiSource passes the MIDIPacketList to the midiRead: function in your PGMidiSource delegate, still in that high priority thread
</li>
<li>You then want to process each MIDIPacket in the MIDIPacketList, handing off the MIDI payload data for each packet to a function in another thread
</li>
</ul>
<p>
<strong>WHAT YOU NEED TO DO<br />
</strong></p>
<p>To summarize what you need to do to in order to get PGMidi working with your app:</p>
<ul>
<li>Add CoreMIDI.framework to your project, linked weakly if you are supporting iOS versions < 4.1</li>
<li>Copy PGMidi, PGMidiAllSources, PGMidiFind files over to your project</li>
<li>Add PGMidi setup code similar to MidiMonitorAppDelegate.m to your app delegate</li>
<li>Add PGMidi delegate functions to the object in your project that is handling configuration notifications, similar to the sourceAdded: sourceRemoved: etc code in MidiMonitorViewController.mm</li>
<li>Add the midiReceived: PGMidiSource delegate function to the object in your project that is handling MIDI input, modified from the midiReceived: code in MidiMonitorViewController.mm</li>
<li>Create your own new SendMIDINote function that calls PGMidi&#8217;s sendBytes: to send out MIDI notes, modified from the sendMidiDataInBackground code in MidiMonitorViewController.mm</li>
</ul>
<p>So that&#8217;s PGMidi in a nutshell. Once you&#8217;ve done all the above, your app should now have basic CoreMIDI support that enables it to set everything up, and allows it to send and receive basic MIDI notes. A great start!</p>
<p><strong>POTENTIAL SAMPLE PROJECT<br />
</strong></p>
<p>If you don’t have a good sample music app project to work with, you might try adding CoreMIDI support to Allen Porter’s open source <a href="http://code.google.com/p/mobilesynth/">mobilesynth</a> project. Add some code so that received MIDI notes will trigger the synth and a tap on the virtual keys will send MIDI notes out.</p>
<p><strong>NEXT TIME&#8230;<br />
</strong></p>
<p>Next in Part 3: Timing Is Everything, we’ll talk about some ways to improve on PGMidi by queueing up MIDI packets early with timestamps, adding MIDI clock functionality, and creating your own MIDI processing thread so that UI functions don’t affect your MIDI timing.</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=878</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CoreMIDI Brain Dump, Part 1: Intro</title>
		<link>http://syntheticbits.com/blog/?p=508</link>
		<comments>http://syntheticbits.com/blog/?p=508#comments</comments>
		<pubDate>Wed, 01 Jun 2011 21:52:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Dev Info]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=508</guid>
		<description><![CDATA[This is part one of what will be a series of five blog posts about CoreMIDI app development. These posts are targeted at iOS music app developers and I&#8217;ll be discussing some of the things I’ve learned while adding CoreMIDI support to our music apps. I&#8217;m writing these to help celebrate the Palm Sounds blog&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>This is part one of what will be a series of five blog posts about CoreMIDI app development. These posts are targeted at iOS music app developers and I&#8217;ll be discussing some of the things I’ve learned while adding CoreMIDI support to our music apps.</p>
<p>I&#8217;m writing these to help celebrate the <a href="http://the-palm-sound.blogspot.com/">Palm Sounds</a> blog&#8217;s fifth anniversary: five posts for five years of great coverage of all sorts of mobile music making. As a music app developer you want to keep on top of all the other latest apps being released, and get feedback on the sorts of features that users are looking for. <a href="http://the-palm-sound.blogspot.com/">Palm Sounds</a> is a great place to do that. Happy 5th and thanks!</p>
<p><strong>WELCOME TO THE COREMIDI THUNDERDOME</strong></p>
<p><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/coremidititle.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/coremidititle.jpg" alt="" title="CoreMIDI title" width="500" height="180" class="alignnone size-full wp-image-1226" /></a></p>
<p>These posts are an introduction to adding CoreMIDI to iOS music apps for developers who have never used the CoreMIDI framework before. Some devs are lucky enough to find learning this stuff is really easy, and can pick it all up themselves very quickly without needing any of this kind of help. Sadly for me, I am not one of those people. Figuring out CoreMIDI was not easy and at points it was actually extremely frustrating. And it still is sometimes, even after implementing it in a couple apps.</p>
<p>So, if you happen to be like me and find this stuff pretty hard, then maybe these posts will be helpful! And if you&#8217;re not like me and CoreMIDI already makes perfect sense to you, well, then get out of here and go make some more cool apps. And stop making me look bad!</p>
<p><strong>I LOVE IT WHEN A PLAN COMES TOGETHER</strong></p>
<p>So here&#8217;s the plan for how we&#8217;re going to try to tackle the CoreMIDI beast in five short blog posts:</p>
<ul>
<li>This first part is a basic introduction to CoreMIDI, helping you figure out what it is you want to do, creating working MIDI music setups, and grabbing some apps to test your setup with.</li>
<li><a href="http://syntheticbits.com/blog/?p=878">Part two</a> will be about implementing basic CoreMIDI functionality using Pete Goodliffe’s <a href="http://goodliffe.blogspot.com/2010/10/using-coremidi-in-ios-example.html">PGMidi sample code</a>, and will hopefully get you to the point where you can set up CoreMIDI, send and receive MIDI notes, and have a basic idea of what’s going on.
</li>
<li>Part three is when things start to get interesting. We&#8217;ll cover improving the performance and timing of MIDI by scheduling MIDI events in advance, sending and receiving MIDI clock, using a dedicated MIDI thread, as well as give you a couple other helpful techniques to avoid some specific headaches.
</li>
<li>Part four will deal with setting up network MIDI connections between iOS devices, and between an iOS device and a laptop, so you can find, connect and communicate with other apps running on other devices.
</li>
<li>Finally, part five will discuss what you need to do to allow your app to work in the background so that you can sync and communicate with other apps running simultaneously on the same iOS device.</li>
</ul>
<p><span id="more-508"></span></p>
<p>What these posts won’t give you is a sample project full of code that you can insert into your own app to make all these features automatically work. I’ll try to point you in the right direction to implement everything, try to help make sense of things with links and advice, and help you avoid some of the many pitfalls and deadends I ran into as I worked on things&#8230; but&#8230; I will not be providing code you can just #include to solve all your problems. Sorry about that! Hopefully this will still be helpful.</p>
<p><strong>INFORMATION UNDERLOAD</strong></p>
<p>Good introductory information about CoreMIDI is currently pretty tough to find. Usually when you want to add a cool feature to your iOS app, you can Google up a bunch of tutorials, sample code, and online discussions that help you figure everything out. CoreMIDI, not so much.</p>
<p>Your first stop is Apple&#8217;s official <a href="http://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/CACoreMIDIRef/_index.html">CoreMIDI Framework Documentation</a>, so go ahead and check that out now. Makes perfect sense, yes? It&#8217;s all pretty straightforward and intuitive? Not much more to say, right? If you are nodding your head non-sarcastically right now, then you don&#8217;t need my blog posts. Scram! For everyone else, this documentation has a lot of useful info and you will go back to it constantly, but it&#8217;s really more a reference than a guide and it doesn&#8217;t provide any good overview of what&#8217;s going on.</p>
<p>The next places to go are Apple’s CoreMIDI framework .h header files themselves, which like the documentation are very good for specific info about specific functions and types when you already mostly know what you’re doing. However, looking through random header files is generally not so great when you need an overall idea of what’s going on, want to decipher which files do what and how they work together, and need to just make some sort of sense of everything when you’re starting out and have no clue. So, keep moving&#8230;</p>
<p>Having some sample code to play with is good for learning things, but Apple has not yet provided any, so you’re out of luck again. You will instead want to check out the code that Pete Goodliffe mercifully provided on his blog with his <a href="http://goodliffe.blogspot.com/2010/10/using-coremidi-in-ios-example.html">PGMidi CoreMIDI sample project</a>. Also updates <a href="http://goodliffe.blogspot.com/2010/11/sending-midi-through-coremidi.html">here</a> , <a href="http://goodliffe.blogspot.com/2011/01/more-ios-midi-using-networked-midi.html">here</a> and <a href="http://goodliffe.blogspot.com/2011/02/pgmidi-updated.html">here</a>. Be sure to read through the comments on those blog posts, there’s some good stuff about implementing and testing MIDI there. We&#8217;ll talk about this code and how to use and tweak it in more depth in <a href="http://syntheticbits.com/blog/?p=878">Part 2</a>.</p>
<p>Peter Johnson of one red dog, maker of the excellent <a href="http://itunes.apple.com/us/app/molten-drum-machine/id398933969?mt=8">Molten Drum Machine</a>, has generously put up some code that handles <a href="http://www.onereddog.com.au/2011/04/08/coremidi-networking-setup/">MIDI networking connection setup</a>. This is used to configure your MIDI networking setup so your app can connect to other apps running on other devices and computers. We&#8217;ll cover this in Part 4.</p>
<p>Finally, for online discussion you can find a few small discussions on the official Apple developer forums in the Graphics and Media > CoreAudio section, and you can search through the official <a href="http://lists.apple.com/mailman/listinfo/coreaudio-api">coreaudio mailing list</a> for older, mostly MacOS based CoreMIDI discussions. Note that this official mailing list has the CoreAudio Apple engineers and other professional audio devs discussing fairly in-depth topics with each other, and they assume (nay, demand) you have a certain amount of knowledge before participating. It&#8217;s not the place to start learning things from scratch with very basic questions, but it can definitely be useful to see what sorts of bugs are being reported, and later on get some insight into alternate approaches to solving more difficult problems.</p>
<p><strong>LET&#8217;S GET THIS PARTY STARTED</strong></p>
<p>Alright, let&#8217;s get started. The first thing to keep in mind is that if you’re not already familiar with CoreAudio/CoreMIDI, and your iOS dev experience is mostly centered around Cocoa, then there will be major parts of this CoreMIDI stuff that will not be as intuitive to learn as some of the other more commonly used iOS features. The networking parts will make more sense, they are the same familiar NSObjects you have grown to know and love. At the lower levels where you&#8217;re sending and receiving raw MIDI data, however, it&#8217;s not object oriented and requires a completely different programming mindset. You probably already figured that out when you were poking around the CoreMIDI Framework Documentation and saw several sections with scary functions, pointers and typedefs.</p>
<div id="attachment_683" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/cocoaobjc.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/cocoaobjc.jpg" alt="" title="Sorry, no Cocoa for you." width="480" height="292" class="size-full wp-image-683" /></a><p class="wp-caption-text">You like Cocoa? Too bad.</p></div>
<p>I know, I know, the picture above is a bit of an exaggeration. You don&#8217;t actually want to literally throw those Cocoa books in the trash. You will probably still want to keep them around while working with CoreMIDI so you have something to hurl at the wall instead of throwing your iPad.</p>
<p>There is a bright side to all this: if you already use CoreAudio for the audio parts of your music app, and you probably do, then you should be familiar with a lot of similar concepts and approaches you’ll be using here. Glancing through the MIDI Services section of the framework documentation, you&#8217;ll see old friends like OSStatus, GetProperties, SetProperties, and all those lovely toll-free CFStringRefs. Of course on the not so bright side, we both know when I mentioned getting and setting CoreAudio properties you immediately put your head in your hands and started weeping uncontrollably, sobbing &#8220;not again&#8230; not again&#8230;&#8221; It&#8217;s okay, we&#8217;ve all been there.</p>
<p>So if this is all such a pain in the ass, why bother? Well, much like CoreAudio, yes, it can be frustrating to work with at times (it&#8217;s really not that bad, I&#8217;m mostly kidding around&#8230; mostly). But it’s also powerful, it&#8217;s been tested and refined for years, it&#8217;s part of the OS so you know it will be updated and will continue to work, and it’s better at what it does than anything else that’s available. And the end results, once you finally get it all working and assuming you have retained most of your sanity, are pretty cool.</p>
<p>Here’s what you get from CoreMIDI:</p>
<ul>
<li>Ability to communicate with just about all “real” external MIDI hardware</li>
<li>Ability to communicate with other apps multi-tasking on the same device</li>
<li>Ability to connect and communicate with apps on other iOS devices</li>
<li>Ability to connect and communicate with a computer</li>
<li>All of the above more or less work the same way, using the same API</li>
<li>You get things like latency compensation not quite for free, but for very cheap</li>
<li>MIDI may be old, and not perfect, but it works and everybody and everything uses it</li>
</ul>
<p>More specifically, you get stuff like this:</p>
<p><iframe width="480" height="300" src="http://www.youtube.com/embed/Le7NwYbeMX4" frameborder="0" allowfullscreen></iframe></p>
<p>That&#8217;s an iPad, two iPod touches, a Korg Electribe EMX-1 and Ableton Live all synced up and playing nice together. Pretty cool, and demonstrates how iOS music apps can fit right into a music studio beyond just being inspirational sketchpads and toys (which are also great, of course).</p>
<p>The video also shows the range of devices that MIDI lets you communicate with. It is a great example of the network effect: even if MIDI isn’t the most thoroughly specced protocol out there from a technical standpoint, it&#8217;s been around and used for so long and by so many things that the reality is it’s much more useful than anything else for the majority of musician users. This will likely also end up being true for CoreMIDI: the more apps that support MIDI in general and CoreMIDI specifically, the more they can interact with each other in cool ways and the more powerful and fun these music apps become for everybody. You don&#8217;t need to handle things in a special way for each and every app and setup you interact with, once you&#8217;ve figured out CoreMIDI your app can talk to everybody.</p>
<p>That’s the main reason I’m writing this series of posts. The more of us that figure this out and start using it, the better it gets for everyone. But most importantly, the better it gets for me. And really that should be your primary motivation here: making things better for me. Thanks!</p>
<p><strong>LET’S GET DOWN TO BRASS TACKS. HOW MUCH FOR THE APP?</strong></p>
<div id="attachment_559" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/05/garagebandr3.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/05/garagebandr3.jpg" alt="" title="Korg R3 hooked up to an iPad" width="480" height="373" class="size-full wp-image-559" /></a><p class="wp-caption-text">Korg R3 hooked up directly via its USB port and a Camera Connection Kit to an iPad</p></div>
<p>Okay, if you haven’t already, right now you need to grab some CoreMIDI apps and play around with them. If you’ve already done that, you need to do it a little more seriously and methodically. You need to get an idea of what these apps are capable of, what you might want your app to do, and most importantly you want to get familiar with some other apps so you have something to test with/against. Currently there are four major ways you will want to be using/testing CoreMIDI on iOS. They are, roughly in the order of complexity they will take to implement, from easy to harder:</p>
<ul>
<li>An iPad connected to CCK/USB, attached to a hardware synth</li>
<li>An iOS device talking to a computer via WiFi</li>
<li>Two iOS devices, talking to each other via WiFi</li>
<li>Two apps talking to each other on a multi-tasking capable iOS device</li>
</ul>
<p>The first iPad-CCK-USB scenario is the easiest both to set up and implement. A lot of apps that currently support CoreMIDI do this and only this. It requires an iPad (note this will change if/when hardware CoreMIDI interfaces for the iPhone/Touch appear) with a Camera Connection Kit and a USB MIDI Interface, along with a MIDI keyboard or controller of some sort. Some keyboards, like my Korg R3, have a built-in USB port with MIDI support that eliminates the need for a separate interface, so you just go iPad-&gt;CCK-&gt;keyboard.</p>
<p>iOSmidi.com has a great, comprehensive, updated <a href="http://iosmidi.com/devices/">list of MIDI interfaces</a> that work with the iPad and the Camera Connection Kit. If you don&#8217;t already have a CCK and compatible interface for your iPad, go order them now. If you don&#8217;t have a cheap MIDI controller laying around, order <a href="http://www.amazon.com/Akai-Pro-LPK25-Performance-Keyboard/dp/B002M8GBDI/ref=pd_cp_MI_1">one of those</a> too. You need to have access to these sorts of USB MIDI configurations as you develop and test your app, because this is one of the most commonly used and requested MIDI setups.</p>
<p><iframe width="468" height="384" src="http://www.youtube.com/embed/Wq1G9qPPNko" frameborder="0" allowfullscreen></iframe></p>
<p>Next, you need to stock up on CoreMIDI apps to experiment and test with. I recommend grabbing <a href="http://itunes.apple.com/us/app/garageband/id408709785?mt=8">GarageBand</a> to test keyboard MIDI input. Anything from Apple is an iOS de facto standard and this is the most popular music app out there, so you will absolutely want to make sure your app works well with it. You can also grab our free <a href="http://itunes.apple.com/us/app/little-midi-machine/id394018004?mt=8">Little MIDI Machine</a> app to test MIDI output. Yeah I’m plugging my own app, but hey it’s free. Also grab <a href="http://itunes.apple.com/us/app/midi-monitor/id395750746?mt=8">MIDI Monitor</a> from iOSmidi.com to debug everything. There will be times when nothing is working correctly and you will want to use <a href="http://itunes.apple.com/us/app/midi-monitor/id395750746?mt=8">MIDI Monitor</a> to figure out where things are going wrong. Hook everything up and get these apps working before you start trying to get your own app to work. You need an already working MIDI setup so if there’s a problem you know it is your code, and not anything else.</p>
<p>For the other three scenarios involving network and multi-tasking MIDI setups, I recommend buying two apps from Finger: <a href="http://itunes.apple.com/us/app/bassline-analog-modeling-synthesizer/id298147000?mt=8">BassLine</a> and <a href="http://itunes.apple.com/us/app/modrum-synthesis-based-drum/id408872480?mt=8">MoDrum</a>. These two apps have an excellent MIDI implementation that works great with the iOS-computer setup, and they were the first two apps to implement the iOS device-iOS device and multi-tasking scenarios. They work perfectly, have a great MIDI setup page, and are excellent for testing with your own app. Get them, you will need them.</p>
<p>You should also grab <a href="http://itunes.apple.com/us/app/molten-drum-machine/id398933969?mt=8">Molten Drum Machine</a> from one red dog to test these network setups. Peter Johnson has released his <a href="http://www.onereddog.com.au/2011/04/08/coremidi-networking-setup/">MIDI networking connection setup code</a> which we&#8217;ll look at in Part 4, and you&#8217;ll likely refer to this code when you implement these connection setup features in your own app. It&#8217;s also just good to have a few different apps that do similar things, from different developers, so you can look at how they each do things differently, what one does better than others, and how well they work together.</p>
<p>And finally you&#8217;ll want a few Mac applications to test your iOS app connected up with a MacOS computer. You&#8217;ll need a sequencer like Ableton Live or Logic to interact with your app. You&#8217;ll want to move the Audio MIDI Setup utility into your dock if you haven&#8217;t already. And for testing and debugging I recommend <a href="http://www.snoize.com/MIDIMonitor/">MIDI Monitor for MacOS</a> from snoize.com, which let&#8217;s you see incoming packets and their timestamps.</p>
<p><iframe width="480" height="300" src="http://www.youtube.com/embed/FoVGvvMSCNM" frameborder="0" allowfullscreen></iframe></p>
<p>Using <a href="http://itunes.apple.com/us/app/bassline-analog-modeling-synthesizer/id298147000?mt=8">BassLine</a> and <a href="http://itunes.apple.com/us/app/modrum-synthesis-based-drum/id408872480?mt=8">MoDrum</a>, along with <a href="http://itunes.apple.com/us/app/garageband/id408709785?mt=8">GarageBand</a>, <a href="http://itunes.apple.com/us/app/midi-monitor/id395750746?mt=8">MIDI Monitor</a>, and <a href="http://itunes.apple.com/us/app/little-midi-machine/id394018004?mt=8">Little MIDI Machine</a>, create working setups for each of the other three non-USB CoreMIDI scenarios: iOS-computer, iOS-iOS, and multi-tasking. Figure out all the settings that are needed to connect various devices together, and play around with the multi-tasking scenario enough to see how awesome it is. As I mentioned before, the MIDI implementation of <a href="http://itunes.apple.com/us/app/bassline-analog-modeling-synthesizer/id298147000?mt=8">BassLine</a> and <a href="http://itunes.apple.com/us/app/modrum-synthesis-based-drum/id408872480?mt=8">MoDrum</a> are really good, so everything should work. If it’s not working, sort out your hardware/setup problems using these apps, not with your own half-finished app.</p>
<p>Specifically, you should verify that you can get the following setups (or similar ones) working:</p>
<ul>
<li>MIDI keyboard plugged into USB MIDI Interface plugged into Camera Connection Kit plugged into iPad running Garageband. Play notes in Garageband using the keyboard.</li>
<li>Little MIDI Machine on the iPad, plugged into the Camera Connection Kit, plugged into a USB MIDI Interface, plugged into a synth or sound module. Play notes on the synth with LMM.</li>
<li>Ableton Live or another sequencer on a Mac, connected via WiFi network MIDI to an iPod/iPhone running MoDrum which is receiving MIDI clock from Ableton</li>
<li>MoDrum running on an iPod/iPhone, connected via WiFi network MIDI to a Mac running Ableton Live which is receiving MIDI clock from MoDrum</li>
<li>Little MIDI Machine running on an iPad, connected via WiFi network MIDI to a Mac running Ableton Live which is receiving MIDI notes from LMM which play a softsynth, while Ableton sends MIDI clock back to LMM and syncs it</li>
<li>MoDrum on an iPod/iPhone, connected via WiFi Network MIDI to an iPad running BassLine which is receiving MIDI clock from MoDrum.</li>
<li>Little MIDI Machine on an iPod/iPhone, connected via WiFi Network MIDI to an iPad running Garageband which is receiving MIDI notes from LMM.</li>
<li>MoDrum and BassLine running simultaneously on the same iPad, synced up via virtual MIDI ports.</li>
</ul>
<p>Multiple types of devices, multiple types of connection methods, multiple types of communication (notes, sync, etc)&#8230; and don&#8217;t forget multiple versions of iOS. CoreMIDI requires a lot of testing, and requires a lot of user documentation for your customers to be able to use it, on top of all the implementation work. Like I said before, it ain&#8217;t easy&#8230;</p>
<p><strong>AND ONE MORE THING&#8230;</strong></p>
<p>Before we wrap up Part 1, here are some random observations and quirks that might save you some time if you read about them here first. Most of the credit for these hints goes to Finger and his apps, I learned a lot about syncing and network connections just by looking at his MIDI Setup menu. You will too as you set up his apps and play with them. Sit down and spend some time studying his setup menu and figure out why he implemented each of the parts the way he did, it&#8217;s worth it. Here are a few of the little things I noticed:</p>
<div id="attachment_546" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/05/networklatency.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/05/networklatency.jpg" alt="" title="MoDrum latency" width="480" height="179" class="size-full wp-image-546" /></a><p class="wp-caption-text">Network latency setting in MoDrum</p></div>
<p>In MoDrum, note how the “Clock Delay” value increases from 0 to 50ms when you enable Network clock out. This is related to sending MIDI packets early to compensate for network latency, something we’ll talk about in Part 3. You’ll want to think in general about how your app will handle sending notes early to deal with latency on the send side for notes and clock, and on the receive side think about how you will handle sometimes being given clock messages a little late even if they have a correct timestamp.</p>
<div id="attachment_548" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/05/networkconnections.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/05/networkconnections.jpg" alt="" title="MoDrum connections setup" width="480" height="125" class="size-full wp-image-548" /></a><p class="wp-caption-text">Network connections setup in MoDrum</p></div>
<p>Next in the setup menu, look at the Network Connections list at the bottom of the setup screen. It will say “Searching&#8230;” if it can’t find anything to connect to, otherwise it will list possible connections (“iPhone 4G”, “Art’s MacBook”, etc). We’ll talk more about these in Part 4, but for now notice that devices automatically appear in this list whenever you load another app running a CoreMIDI Network Session on a device on the same network. If you quit that other app, the device will disappear from the list. You can make your Mac appear by loading Audio MIDI Setup. If you run the same MoDrum app on two separate devices, you’ll note that when you use the first device to connect to the second, the second automatically becomes connected to the first. These connections are two way, if you connect them on one end they are also automatically connected on the other.</p>
<div id="attachment_552" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/05/networksession.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/05/networksession.jpg" alt="" title="MoDrum session setup" width="480" height="106" class="size-full wp-image-552" /></a><p class="wp-caption-text">Network Session setup in MoDrum</p></div>
<p>Again in the setup menu, the Network Session switch turns the CoreMIDI Network Session on and off, as you would expect. If you multi-task both MoDrum and BassLine on the same device, you’ll notice something more: if you turn off the Network Session in one, then switch to the other app, it will also be turned off there. This setting is device wide, and shared by all apps currently using CoreMIDI. This is something to keep in mind if you are enabling or disabling it without actively consulting the user, such as reloading a MIDI configuration from a saved preference file.</p>
<div id="attachment_623" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/virtualportlist.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/virtualportlist.jpg" alt="" title="Virtual ports in MoDrum" width="480" height="201" class="size-full wp-image-623" /></a><p class="wp-caption-text">BassLine and FunkBox virtual port sources as seen by MoDrum</p></div>
<p>Our last observation about the MoDrum MIDI Setup menu involves multi-tasking and virtual ports. The screenshot above shows MoDrum running alongside BassLine and FunkBox on a single iPad. As you can see, BassLine and FunkBox offer virtual port sources so that they can send MIDI information to other apps. They will also have virtual port destinations listed in that section of the setup menu so they can receive data.</p>
<p>An important thing to note here is these ports are not app-app connections, these are direct ports to and from that specific app. Any other app can send to or receive from that same port. So if in MoDrum you turn on MIDI clock transmit to the BassLine virtual destination, you do not need to go to BassLine and turn on MIDI clock receive from MoDrum&#8217;s virtual source port. Those are two separate ports: one is always going into BassLine and anyone can send to it, one is always coming from MoDrum and anyone can listen to it.</p>
<p>This is different from the device-device and device-computer network MIDI connection list up above: with those, when you make a connection on one end, you automatically make a connection on the other end. Even if other apps don&#8217;t support setting up these connections, you can do it yourself from your own app and communicate with them. As long as one side is able to make the connection, it will work for both apps. For example, Little MIDI Machine on one iOS device can connect up with and send notes to Garageband or SynthX on another device, because Little MIDI can make those network MIDI connections even if the other apps can&#8217;t. After the connection is made, both sides can talk with each other.</p>
<p>With virtual ports, the connections are one way. Your app can send to FunkBox&#8217;s input port, and FunkBox can listen to your app&#8217;s output port, but if you configure them to do both FunkBox will receive every MIDI packet twice, once on its input and once on your output.</p>
<div id="attachment_731" class="wp-caption aligncenter" style="width: 510px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/06/bluetooth.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/06/bluetooth.jpg" alt="" title="Bluetooth MIDI" width="500" height="116" class="size-full wp-image-731" /></a><p class="wp-caption-text">Enable Bluetooth, disable WiFi, Network MIDI still works</p></div>
<p>Moving on, another neat quirky thing I found when playing with network CoreMIDI is that it doesn&#8217;t have to be done over WiFi. If you turn off WiFi entirely and enable Bluetooth in the Settings app, you&#8217;ll note that paired devices can still discover, connect and communicate normally with each other using network MIDI over a Bluetooth connection. </p>
<p>This is cool for users who want a wireless MIDI setup that is not dependent on having access to an existing WiFi network. It&#8217;s cool for developers because it demonstrates just how powerful CoreMIDI is: it abstracts away those network layers for you, and as a developer for the most part you do not need to worry about whether these connections are being made over WiFi, USB or Bluetooth (this isn&#8217;t completely true because virtual ports work a little differently in some ways that we&#8217;ll cover later). In fact, both the Finger dev and myself were surprised when CoreMIDI over Bluetooth actually worked with our apps, we had done nothing to make it work and hadn&#8217;t even thought about it when writing the code.</p>
<div id="attachment_543" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/05/killtaskbar.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/05/killtaskbar.jpg" alt="" title="Killing apps in the task bar" width="480" height="103" class="size-full wp-image-543" /></a><p class="wp-caption-text">Multi-tasking apps hang around in the background until manually stopped</p></div>
<p>Lastly, as you&#8217;re playing with the Finger apps synced up on a single device, note that since they hang around in the background when you switch out of them, there&#8217;s no easy way to automatically quit them. MoDrum and BassLine will be running in the background, even after the user leaves them to do something else, until they are explicitly cancelled by the user by holding down on the icon in the task bar and pressing the minus in the red circle. We’ll talk more about how you can minimize the effect of this on the processor and battery in Part 5.</p>
<p><strong>USEFUL LINKS!</strong></p>
<p>Here are some other sources to check out for info on CoreMIDI:</p>
<p><a href="http://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/CACoreMIDIRef/_index.html">Apple&#8217;s CoreMIDI Reference</a></p>
<p><a href="http://goodliffe.blogspot.com/2010/10/using-coremidi-in-ios-example.html">Pete Goodliffe&#8217;s PGMIDI Sample Code</a></p>
<p><a href="http://www.onereddog.com.au/2011/04/08/coremidi-networking-setup/">Peter Johnson of one red dog&#8217;s CoreMIDI Network Setup Code</a></p>
<p><a href="http://michaelaldridge.info/post/7393386507/coremidi-within-openframeworks">Michael Aldridge&#8217;s Sample Code to use CoreMIDI with Open Frameworks</a></p>
<p><strong>UNTIL NEXT TIME&#8230;</strong></p>
<p>Okay, that&#8217;s about it for Part 1. You have a working MIDI setup now with different apps and devices, so find some CoreMIDI quirks of your own, and start thinking about how your own app will be integrated into all these various setups. That will of course depend on the type of MIDI app you’re creating: are you a sound source to be played? A sequencer that sends notes? A self contained app that needs to sync up in time with other things? Think about how you can test your app so it works in these various scenarios, and if possible find another app from someone else that does similar things and fills a similar role, so that when you run into problems you can doublecheck if it’s just your app that isn’t working, or if it doesn’t work with anybody&#8217;s apps.</p>
<p>Now that you’ve played with CoreMIDI as a user and you’re sufficiently comfortable using it, you’re ready to add some basic MIDI functions to your own app, which we’ll cover next in <a href="http://syntheticbits.com/blog/?p=878">Part Two</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=508</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Little MIDI Machine v2 coming soon!</title>
		<link>http://syntheticbits.com/blog/?p=498</link>
		<comments>http://syntheticbits.com/blog/?p=498#comments</comments>
		<pubDate>Wed, 18 May 2011 20:18:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Preview]]></category>

		<guid isPermaLink="false">http://syntheticbits.com/blog/?p=498</guid>
		<description><![CDATA[We just submitted the long awaited version 2 of Little MIDI Machine to Apple for review. Here are a couple screenshots to whet your appetite while we wait for approval: Version 2.0 features include: Now a universal app, supports iPad, iPhone, iPod Touch CoreMIDI support, including network MIDI MIDI clock sync for both Line 6 [...]]]></description>
			<content:encoded><![CDATA[<p>We just submitted the long awaited version 2 of Little MIDI Machine to Apple for review. Here are a couple screenshots to whet your appetite while we wait for approval:</p>
<div id="attachment_499" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/05/LMMiPad.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/05/LMMiPad.jpg" alt="" title="LMM v2 for iPad" width="480" height="360" class="size-full wp-image-499" /></a><p class="wp-caption-text">Little MIDI v2 for iPad</p></div>
<div id="attachment_500" class="wp-caption aligncenter" style="width: 490px"><a href="http://syntheticbits.com/blog/wp-content/uploads/2011/05/LMMiPhone.jpg"><img src="http://syntheticbits.com/blog/wp-content/uploads/2011/05/LMMiPhone.jpg" alt="" title="LMM v2 iPhone" width="480" height="320" class="size-full wp-image-500" /></a><p class="wp-caption-text">Little MIDI Machine got littler! Now for iPhone and iPod Touch too</p></div>
<p>Version 2.0 features include:<br />
Now a universal app, supports iPad, iPhone, iPod Touch<br />
CoreMIDI support, including network MIDI<br />
MIDI clock sync for both Line 6 and CoreMIDI, send and receive<br />
New random sequence mode<br />
Updated graphics/UI<br />
Still free</p>
<p>And more! Coming soon!</p>
<p>While we wait, if you&#8217;ve been enjoying the latest FunkBox updates and get a chance to leave an app store review (or update an old one), we&#8217;d really appreciate it! Every time we release an update it hides all the old reviews, which actually hurts us and has a noticeable negative effect on sales. So it really helps us out and encourages us to release more updates if you leave new reviews or update the old ones so they re-appear again. Thanks so much!</p>
<p><a href="http://itunes.apple.com/us/app/funkbox-drum-machine/id350437349?mt=8">Help us out and leave us a FunkBox review at the iTunes App Store</a></p>
]]></content:encoded>
			<wfw:commentRss>http://syntheticbits.com/blog/?feed=rss2&#038;p=498</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

