<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0"><channel><description>learn more about me at my personal web site [kindohm.com]</description><title>mike hodnick's blog</title><generator>Tumblr (3.0; @kindohm)</generator><link>http://hodnick.com/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Kindohm" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="kindohm" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><geo:lat>44.809954</geo:lat><geo:long>-93.610506</geo:long><item><title>Introducing the Error Alpaca</title><description>&lt;p&gt;Before I get to the Error Alpaca, I have to explain that I’m reviving my good old &lt;a href="http://kindohm.com" target="_blank"&gt;kindohm.com&lt;/a&gt; web site to be my personal internet end point for information about me. &lt;a href="http://hodnick.com" target="_blank"&gt;Hodnick.com&lt;/a&gt; will continue to live on for blog/article posts. Rss feed URLs haven’t changed. It’s a personal internet identity crisis that has now been put to rest.&lt;/p&gt;

&lt;p&gt;The new kindohm.com is a new informational source for me: bio, music, code, etc. It’s a new, simple design and I encourage you to check it out and let me know what you think.&lt;/p&gt;

&lt;p&gt;With this new design and domain switch, I decided to implement new standard error pages for kindohm.com that handle basic 400, 404, and 500 error codes.&lt;/p&gt;

&lt;p&gt;This is where the Error Alpaca comes in. The Error Alpaca politely lets you know that some type of problem occurred on the site:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l84ivpOwtc1qzrj0v.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;You can reproduce this error by following this link: &lt;a href="http://kindohm.com/bad.htm" target="_blank"&gt;&lt;a href="http://kindohm.com/bad.htm" target="_blank"&gt;http://kindohm.com/bad.htm&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I can’t easily reproduce the other error types, but the Error Alpaca can specifically handle the 401, 404, and 500 error codes. If another type of error occurs, it can handle that one generically:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l84j1v3kYk1qzrj0v.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l84j23Lihy1qzrj0v.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l84j29scfM1qzrj0v.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l84j2g3XaG1qzrj0v.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;I must say that I’ve never enjoyed handling error conditions more.&lt;/p&gt;</description><link>http://hodnick.com/post/1053489668</link><guid>http://hodnick.com/post/1053489668</guid><pubDate>Thu, 02 Sep 2010 09:35:32 -0500</pubDate><category>error</category><category>web</category><category>alpaca</category></item><item><title>That's my girl</title><description>&lt;p&gt;Eva (5 yrs) and I had the following discussion at breakfast today:&lt;/p&gt;

&lt;p&gt;Me: Do you know what today is? &lt;br/&gt;
Eva: No &lt;br/&gt;
Me: It’s the first day of September &lt;br/&gt;
Eva: Does that mean that the new Halo is coming out?&lt;br/&gt;&lt;/p&gt;

&lt;p&gt;// tears of joy //&lt;/p&gt;

&lt;p&gt;That’s my girl.&lt;/p&gt;</description><link>http://hodnick.com/post/1048601379</link><guid>http://hodnick.com/post/1048601379</guid><pubDate>Wed, 01 Sep 2010 12:03:50 -0500</pubDate><category>eva</category><category>breakfast</category><category>halo</category></item><item><title>Photo</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_l7xkzxHWHO1qzrz0oo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;</description><link>http://hodnick.com/post/1032770537</link><guid>http://hodnick.com/post/1032770537</guid><pubDate>Sun, 29 Aug 2010 15:31:16 -0500</pubDate></item><item><title>Greetings from Android</title><description>&lt;p&gt;Greetings from Android&lt;/p&gt;</description><link>http://hodnick.com/post/1014126633</link><guid>http://hodnick.com/post/1014126633</guid><pubDate>Thu, 26 Aug 2010 07:43:10 -0500</pubDate></item><item><title>Code from today's Twin Cities Silverlight User Group session</title><description>&lt;p&gt;Here is all of the source code from today’s session I held on network awareness, out-of-browser, webcam, and microphone integration with Silverlight 4 at the Twin Cities Silverlight User Group:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://kindohm.com/files/TCSLUG.2010.08.17.zip" target="_blank"&gt;TCSLUG.2010.08.17.zip&lt;/a&gt; [474 KB]&lt;/p&gt;

&lt;p&gt;And here is the composite image made from myself and one brave volunteer when I was demonstrating simultaneous webcams (from the WebCamFun solution in the source code):&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l7brti5xxV1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Sorry guy (don’t know your name)…  I hope you don’t mind me posting the image!&lt;/p&gt;</description><link>http://hodnick.com/post/969658966</link><guid>http://hodnick.com/post/969658966</guid><pubDate>Tue, 17 Aug 2010 20:53:08 -0500</pubDate><category>silverlight</category><category>webcam</category><category>microphone</category><category>code</category><category>programming</category><category>tcslug</category></item><item><title>For once, Facebook correctly recommends a page/group that suits...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_l73o7d3xhe1qzrz0oo1_400.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;For once, Facebook correctly recommends a page/group that suits me.&lt;/p&gt;</description><link>http://hodnick.com/post/947981880</link><guid>http://hodnick.com/post/947981880</guid><pubDate>Fri, 13 Aug 2010 11:52:25 -0500</pubDate></item><item><title>HTTPS with Azure, Web APIs, Local Environments, and Build Automation</title><description>&lt;p&gt;My, that’s a long title….&lt;/p&gt;

&lt;p&gt;On my current project we have developed a web-based API (e.g. sorta kinda RESTful) that allows remote applications to interface with our system. These remote applications currently include a Silverlight app and an iPhone app prototype.&lt;/p&gt;

&lt;p&gt;Our web API is hosted at a secure HTTPS endpoint. This is crucial so that user credentials, which are required by our API, are not sent unencrypted across the internet. We could have chosen to require client applications to encrypt credentials before sending them to the API, but why not let SSL do that dirty work for you?&lt;/p&gt;

&lt;p&gt;Our API is hosted in an Azure web role. When hosted at an HTTPS endpoint, the Azure web role must be configured for HTTPS and with the SSL certificate thumbprint before it is deployed to Windows Azure up in the cloud. This causes a problem for doing local development against the API when hosted in the Azure dev fabric: API calls will fail because the SSL certificate used does not match the localhost URL. When you browse a normal web site where the SSL certificate does not match the actual web site url, you get these certificate/identification warnings shown in browsers like Chrome and IE:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6vzc1IDan1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6vzccecL01qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;As a human, you can choose to bypass these warnings and let the web browser continue to render the site.  However, with a web-based API your code won’t let you make that choice. Your code will fail, and rightfully so. We wouldn’t want our automated API to use a web site that was potentially spoofing us.&lt;/p&gt;

&lt;p&gt;If you compile and deploy your Azure cloud package through a TFS build (or another build system), this presents a problem. You need a local Cloud Service project with no SSL certificate (or a different SSL certificate) configured for your developers to develop on, but then you need to deploy a Cloud Service that &lt;em&gt;does&lt;/em&gt; have the SSL certificate configuration.&lt;/p&gt;

&lt;p&gt;There are a couple ways to handle this. The first approach is the one I recommend. The second one I don’t recommend, but it could be useful in certain contexts.&lt;/p&gt;

&lt;h3&gt;1) Create Two Cloud Service Projects&lt;/h3&gt;

&lt;p&gt;This is the approach I recommend. It requires less trickery with TFS build tasks/scripts and relies more on permanently storing the HTTPS/Certificate data in the cloud service projects themselves. It’s just easier.&lt;/p&gt;

&lt;p&gt;Basically, just create two Cloud Service projects in your solution that host the same project for the web role:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6w0jxYyiu1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;In one cloud service project, leave it with HTTP on port 80. With the second cloud project, add the HTTPS and Certificate configuration. You can do this by going to the Properties page for each web role in each cloud service project:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6w07seBJT1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6w0txhnuk1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Now in your build/deploy automation you can just select which Cloud Service project and supporting files to use when calling cspack.exe. There. Done. Easy. Cake.&lt;/p&gt;

&lt;h3&gt;2) Modify the Azure Service Definition and Config at Build Time&lt;/h3&gt;

&lt;p&gt;At this time &lt;em&gt;&lt;strong&gt;I do not recommend this approach&lt;/strong&gt;&lt;/em&gt; as it just creates a lot of complexity in your build. I’m not even sure that this approach is worth writing about, but in some circumstances it may be appropriate. It’s also the first approach I tried in real life, and maybe after you read about it you can avoid the pain I went through.&lt;/p&gt;

&lt;p&gt;The gist of this approach is to inject the HTTPS and SSL certificate configuration information into your Service Definition and Service Configuration files at build/deploy time. This will allow you to work with the Cloud Service package locally without HTTPS/SSL configuration, but deploy the package to Azure with the HTTPS/SSL configuration &lt;em&gt;without additional Azure Cloud Service projects&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You’ll need to create custom tasks or scripts that will run during your build to make copies of the ServiceDefinition.csdef and ServiceConfiguration.cscfg files. You can even use new names for them. You’ll modify these new copies to include the HTTPS/SSL configuration. Point to your new copies when you run cspack.exe to create your cloud package.&lt;/p&gt;

&lt;p&gt;In short, you’ll need to modify your ServiceDefinition.csdef file from this:&lt;/p&gt;

&lt;script src="http://gist.github.com/515404.js?file=gistfile1.xml"&gt;&lt;/script&gt;&lt;p&gt;To this:&lt;/p&gt;

&lt;script src="http://gist.github.com/515405.js?file=gistfile1.xml"&gt;&lt;/script&gt;&lt;p&gt;And modify your ServiceConfiguration.cscfg file from this:&lt;/p&gt;

&lt;script src="http://gist.github.com/515410.js?file=gistfile1.xml"&gt;&lt;/script&gt;&lt;p&gt;To this (adding the Certificates element):&lt;/p&gt;

&lt;script src="http://gist.github.com/515413.js?file=gistfile1.xml"&gt;&lt;/script&gt;&lt;p&gt;Obviously - use your own role and certificate names as well as your own real SSL thumbprint.&lt;/p&gt;

&lt;p&gt;I recommend getting comfortable with these config settings and being able to read the XML before you start manipulating the files in a build task. You can warm up to the idea by manipulating these settings in the Properties of your Azure web role in Visual Studio. Visual Studio will modify your ServiceDefinition.csdef and ServiceConfiguration.cscfg files when you change these properties in Visual Studio:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6w07seBJT1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Again, just use Visual Studio in a test project to warm up to the idea - you don’t want to embed the real SSL/HTTPS configuration into your local environment with this approach.&lt;/p&gt;

&lt;p&gt;After you add custom scripts or tasks in your build to create the new Service Definition and Service Configuration, you can call cspack.exe, point to the right files, and generate an Azure package with the SSL/HTTPS configuration that you need.&lt;/p&gt;</description><link>http://hodnick.com/post/927338768</link><guid>http://hodnick.com/post/927338768</guid><pubDate>Mon, 09 Aug 2010 10:11:29 -0500</pubDate><category>azure</category><category>security</category><category>https</category></item><item><title>Digital Audio Synthesis on Windows Phone 7</title><description>&lt;p&gt;Back in March 2010, I &lt;a href="http://hodnick.com/post/453609901/wp7devtoolsimpressions" target="_blank"&gt;posted about my initial excitement and disappointment&lt;/a&gt; with the Windows Phone 7 developer tools. Back then, then WP7 emulator didn’t support the MediaElement’s SetSource method. SetSource provides the basis for being able to do digital audio synthesis with custom MediaStreamSource objects.&lt;/p&gt;

&lt;p&gt;With the new WP7 beta tools, I’m happy to say that the SetSource method is now supported by the WP7 emulator - so you can now hear and play your synthesized audio!&lt;/p&gt;

&lt;p&gt;I created a very simple audio synthesis app to demonstrate these features:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://kindohm.com/files/WP7AudioSynthesisDemo.zip" target="_blank"&gt;Download the source code&lt;/a&gt; [26 kb]&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6kye8iQPf1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;The app lets you pick from two audio sources: one source generates random noise and the other source generates a constant, smooth set of tones.&lt;/p&gt;

&lt;p&gt;Happy WP7 coding!&lt;/p&gt;</description><link>http://hodnick.com/post/898160917</link><guid>http://hodnick.com/post/898160917</guid><pubDate>Tue, 03 Aug 2010 09:21:00 -0500</pubDate><category>audio</category><category>synthesis</category><category>wp7</category><category>windowsphone7</category></item><item><title>Broken Silverlight apps fixed</title><description>&lt;p&gt;Apparently the web hosting company (webhost4life.com) which hosts my ASP.NET / Silverlight applications decided to remove the XAP MIME type from my web site, thus breaking all of my personal Silverlight apps. If you follow my site and have been trying to use an app that appeared to be broken, please try again as I have resolved the issue.&lt;/p&gt;

&lt;p&gt;In the meantime, don’t sign up for webhost4life.com.&lt;/p&gt;</description><link>http://hodnick.com/post/895788961</link><guid>http://hodnick.com/post/895788961</guid><pubDate>Mon, 02 Aug 2010 20:46:48 -0500</pubDate></item><item><title>Old School Advertising</title><description>&lt;p&gt;Phone book? Srsly?&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/kindohm/4840943303/" title="Old school advertising by kindohm, on Flickr" target="_blank"&gt;&lt;img src="http://farm5.static.flickr.com/4108/4840943303_0abbbb60b3.jpg" width="500" height="375" alt="Old school advertising"/&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://hodnick.com/post/876038516</link><guid>http://hodnick.com/post/876038516</guid><pubDate>Thu, 29 Jul 2010 13:21:09 -0500</pubDate><category>advertising</category><category>picture</category></item><item><title>New Music: Feel the Sealant (Tub Repair mix)</title><description>&lt;p&gt;I’ve completed a remix of &lt;a href="http://hodnick.com/post/847700040/new-music-feel-the-sealant" target="_blank"&gt;the last tune I posted&lt;/a&gt;. I introduce to you the Tub Repair mix of Feel the Sealant:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://hodsaudio.net/mp3/Electronica/Parser.FeelTheSealant.TubRepairMix.mp3" target="_blank"&gt;Parser.FeelTheSealant.TubRepairMix.mp3&lt;/a&gt; [10.3 MB]&lt;/p&gt;

&lt;p&gt;The tune is also available at hodsaudio.net: &lt;a href="http://hodsaudio.net/Song/Details/307" target="_blank"&gt;&lt;a href="http://hodsaudio.net/Song/Details/307" target="_blank"&gt;http://hodsaudio.net/Song/Details/307&lt;/a&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a quick video introducing the tune:&lt;/p&gt;

&lt;p&gt;&lt;object width="480" height="390"&gt;&lt;param name="movie" value="http://www.xtranormal.com/site_media/players/jwplayer.swf"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;param name="allowscriptaccess" value="always"&gt;
&lt;param name="flashvars" value="height=390&amp;width=480&amp;file=http://newvideos.xtranormal.com/web_final_lo/bcc88f8e-9b0d-11df-a87a-003048d69c21_21_web_final_lo_web_finallo-flv.flv&amp;image=http://newvideos.xtranormal.com/web_final_lo/bcc88f8e-9b0d-11df-a87a-003048d69c21_21_web_final_lo_poster.jpg&amp;link=http://www.xtranormal.com/watch/6847959&amp;searchbar=false&amp;autostart=false"&gt;
&lt;embed src="http://www.xtranormal.com/site_media/players/jwplayer.swf" width="480" height="390" allowscriptaccess="always" allowfullscreen="true" flashvars="height=390&amp;width=480&amp;file=http://newvideos.xtranormal.com/web_final_lo/bcc88f8e-9b0d-11df-a87a-003048d69c21_21_web_final_lo_web_finallo-flv.flv&amp;image=http://newvideos.xtranormal.com/web_final_lo/bcc88f8e-9b0d-11df-a87a-003048d69c21_21_web_final_lo_poster.jpg&amp;link=http://www.xtranormal.com/watch/6847959&amp;searchbar=false&amp;autostart=false"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;object width="480" height="390"&gt;&lt;param name="movie" value="http://www.xtranormal.com/site_media/players/embedded-xnl-stats.swf"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;param name="allowscriptaccess" value="always"&gt;
&lt;embed src="http://www.xtranormal.com/site_media/players/embedded-xnl-stats.swf" width="1" height="1" allowscriptaccess="always"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;</description><link>http://hodnick.com/post/875208994</link><guid>http://hodnick.com/post/875208994</guid><pubDate>Thu, 29 Jul 2010 08:38:43 -0500</pubDate><category>music</category></item><item><title>New Music: Feel the Sealant</title><description>&lt;p&gt;I’ve finished work on a new audio track entitled “Feel the Sealant”. Click below to play or download:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://hodsaudio.net/mp3/Electronica/Parser.FeelTheSealant.mp3" target="_blank"&gt;Parser.FeelTheSealant.mp3&lt;/a&gt; [7.21 MB]&lt;/p&gt;

&lt;p&gt;The file is also available from hodsaudio.net: &lt;a href="http://hodsaudio.net/Song/Details/306" target="_blank"&gt;&lt;a href="http://hodsaudio.net/Song/Details/306" target="_blank"&gt;http://hodsaudio.net/Song/Details/306&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a picture of some sealant:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l5zoq03Zhg1qzrj0v.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;</description><link>http://hodnick.com/post/847700040</link><guid>http://hodnick.com/post/847700040</guid><pubDate>Thu, 22 Jul 2010 21:40:19 -0500</pubDate><category>music</category><category>electronica</category><category>studio</category></item><item><title>Capture and Play Back Audio with a Microphone in Silverlight</title><description>&lt;p&gt;&lt;a href="http://kindohm.com/micsampler/" target="_blank"&gt;Try the demo app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://kindohm.com/micsampler/SampleEditor.zip" target="_blank"&gt;Download the source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l5v4ihH4EU1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;In a previous post I talked about capturing video from a web cam in Silverlight. In this article I’m going to talk about capturing &lt;em&gt;audio&lt;/em&gt;. In addition, I’m going to cover how to keep the captured audio in memory and play it back using a custom MediaStreamSource object.&lt;/p&gt;

&lt;p&gt;Just like with video, capturing audio begins with a CaptureSource and an AudioCaptureDevice:&lt;/p&gt;

&lt;script src="http://gist.github.com/483048.js?file=gistfile1.cs"&gt;&lt;/script&gt;&lt;p&gt;The above code assumes you’ve gained permission from the user to use the device.&lt;/p&gt;

&lt;p&gt;As you can expect, the CaptureDeviceConfiguration class has a GetAvailableAudioCaptureDevices method that you can use to get all audio devices on the user’s computer.&lt;/p&gt;

&lt;p&gt;Calling Start() on the CaptureSource begins the capture process, but it doesn’t actually store the audio data anywhere. That is where a handy little class in Silverlight called AudioSink comes in. AudioSink is a class you use to handle incoming audio samples. It is an abstract class so you will need to create your own custom implementation and override four abstract methods: OnCaptureStarted, OnCaptureStopped, OnFormatChanged, and OnSamples:&lt;/p&gt;

&lt;script src="http://gist.github.com/483055.js?file=gistfile1.cs"&gt;&lt;/script&gt;&lt;p&gt;To use a custom AudioSink, you wire it up to a CaptureSource by setting the AudioSink’s CaptureSource property equal to a CaptureSource instance:&lt;/p&gt;

&lt;script src="http://gist.github.com/483079.js?file=gistfile1.cs"&gt;&lt;/script&gt;&lt;p&gt;In the most simple form you can just create a custom AudioSink that captures the samples in a MemoryStream. You can optionally read this stream into a byte array if you so choose:&lt;/p&gt;

&lt;script src="http://gist.github.com/483063.js?file=gistfile1.cs"&gt;&lt;/script&gt;&lt;p&gt;At this point, you’re &lt;em&gt;almost&lt;/em&gt; ready to start playing back the audio you’ve captured. However, we cannot ignore the OnFormatChanged method and the audio format of the incoming data.&lt;/p&gt;

&lt;p&gt;The AudioCaptureDevice class has a SupportedFormats property which is a collection of AudioFormat objects. AudioFormat describes the samples per second, bits per sample, and number of channels for the captured audio. These properties are &lt;em&gt;crucial&lt;/em&gt; in being able to correctly play back your audio. AudioCaptureDevice also has a DesiredFormat property. When set, DesiredFormat will use that format to capture audio.&lt;/p&gt;

&lt;p&gt;To take a step back here - you have an available set of AudioCaptureDevices, and each device has a set of SupportedFormats. You will either need to use a set of defaults or maintain two lists (one dependent on the other) for the user to pick from.&lt;/p&gt;

&lt;p&gt;OnFormatChange in the AudioSink class gets called for the first time just before the samples start rolling in. However, it is possible that it may get called again. In advanced scenarios you may want to support a changed audio format. I just prefer to throw an exception in my AudioSink and not deal with it. My app must then be constrained to prevent the user from changing the audio format at capture time.&lt;/p&gt;

&lt;p&gt;Once the audio format is set, you can keep this format stored in the AudioSink for future use:&lt;/p&gt;

&lt;script src="http://gist.github.com/483074.js?file=gistfile1.cs"&gt;&lt;/script&gt;&lt;p&gt;When you call Stop() on CaptureSource, recording will stop and the AudioSink’s OnCaptureStopped method will get called.&lt;/p&gt;

&lt;p&gt;Next we need to deal with playing back the audio. You will need to create a custom MediaStreamSource object that can describe the media stream in terms of the audio format captured in the AudioSink. Then, you will use that MediaStreamSource to send out the audio samples captured in the AudioSink. Basically you’ll want to pass in the AudioFormat and byte[] data you captured in your AudioSink into your custom MediaStreamSource.&lt;/p&gt;

&lt;p&gt;I don’t want to get too deep into the MediaStreamSource implementation because &lt;em&gt;so much&lt;/em&gt; of it is verbose boilerplate code. However, your constructor, OpenMediaAsync(), and GetSampleAsync() methods for the MediaStreamSource will look something like this:&lt;/p&gt;

&lt;script src="http://gist.github.com/483090.js?file=gistfile1.cs"&gt;&lt;/script&gt;&lt;p&gt;The above code is incomplete but it should give you a taste of what you need to do with a MediaStreamSource. There are plenty of resources out there on how to set up and use MediaStreamSource objects. The above code basically starts at the beginning of the audio data and plays through to the end, then starts at the beginning again. The source code example with this post has a complete implementation.&lt;/p&gt;

&lt;p&gt;One quirk I’ve found while having a few friends test out this demo app is that audio recording and playback seem to fail if no default audio capture device exists within the Silverlight configuration. This is an operating-system level configuration setting and not an application setting. If this scenario occurs, it can be remedied by having the user right-click on the Silverlight application, select “Silverlight”, then select the Webcam/Mic tab. From there, the user can select an audio capture device as their “default” on their operating system. This seems to clear up the problem (so far).&lt;/p&gt;

&lt;p&gt;After you get these mechanics working, you can slap on a fun UI and start hacking with samples!&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;</description><link>http://hodnick.com/post/838893081</link><guid>http://hodnick.com/post/838893081</guid><pubDate>Tue, 20 Jul 2010 21:35:59 -0500</pubDate><category>silverlight</category><category>programming</category><category>code</category><category>audio</category><category>microphone</category></item><item><title>Comments Fixed</title><description>&lt;p&gt;I just noticed that my commenting system was completely missing from my web site and posts!  The problem is fixed now. It was caused by some theme changes I made a while back. Sorry bout that.&lt;/p&gt;</description><link>http://hodnick.com/post/837499164</link><guid>http://hodnick.com/post/837499164</guid><pubDate>Tue, 20 Jul 2010 14:46:17 -0500</pubDate><category>blog</category></item><item><title>Multi Video Capture in Silverlight</title><description>&lt;p&gt;&lt;a href="http://kindohm.com/doublecam/" target="_blank"&gt;Try the demo application&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://kindohm.com/doublecam/DoubleCam.zip" target="_blank"&gt;Download source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l5ta77hynA1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;One fine detail before you read any further: you need to have two video capture devices (e.g. web cams) in order to really have any fun with this.&lt;/p&gt;

&lt;p&gt;One of the best features about Silverlight 4 is that you can interact with video and audio capture devices. This enables you to take pictures from a web cam, record video, or record audio in your Silverlight application and handle the media data directly.&lt;/p&gt;

&lt;p&gt;One fun little side effect of the video capture API in Silverlight 4 is that you can enable two video capture devices simultaneously. This may or may not have any value to you and your everyday Silverlight programming, but if it did then it probably wouldn’t be any fun anyway!&lt;/p&gt;

&lt;p&gt;If you haven’t tried out the Audio/Video capture API in Silverlight 4 yet, here is the basic idea:&lt;/p&gt;

&lt;script src="http://gist.github.com/480674.js?file=capture.cs"&gt;&lt;/script&gt;&lt;p&gt;That’s all the code you need to do to start viewing/recording video. Basically, CaptureSource is the key class that makes it all work for you. You use CaptureSource’s VideoCaptureDevice property to tell it which video device on your computer to use. You may have more than one, but Silverlight lets you select a default one with the CaptureDeviceConfiguration class’s GetDefaultVideoCaptureDevice method.  It’s cake.&lt;/p&gt;

&lt;p&gt;If you actually want to select a specific video device and not use the default, you can use the CaptureDeviceConfiguration’s GetAvailableVideoCaptureDevices method:&lt;/p&gt;

&lt;script src="http://gist.github.com/480681.js?file=getdevices.cs"&gt;&lt;/script&gt;&lt;p&gt;With that list of devices you can bind to it or do whatever it is you like to do with lists of VideoCaptureDevices. Typically, I bind that list to a ComboBox so that the user can select their device.&lt;/p&gt;

&lt;p&gt;To display the video from your device on screen, call the Start() method on the CaptureSource object and use a video brush to paint it onto a surface, like a rectangle:&lt;/p&gt;

&lt;script src="http://gist.github.com/480687.js?file=allowaccess.cs"&gt;&lt;/script&gt;&lt;p&gt;In the source code for this article you can see this all in action.&lt;/p&gt;

&lt;p&gt;Now, the cool part is that you can encapsulate all of the above logic in a Silverlight UserControl and display two cameras at the same time. Essentially, two CaptureSource objects can be set up and started.&lt;/p&gt;

&lt;p&gt;As an example, I have a main page with two Camera user controls I created on it:&lt;/p&gt;

&lt;script src="http://gist.github.com/480690.js?file=MainPage.xaml"&gt;&lt;/script&gt;&lt;p&gt;And the camera controls look like this:&lt;/p&gt;

&lt;script src="http://gist.github.com/480692.js?file=camera.xaml"&gt;&lt;/script&gt;&lt;p&gt;You can see that I’ve added a Rectangle for the video display area, a Combo box to let the user select their device, a “Turn On” button, and a warning message to display (if necessary) about the device already being in use.&lt;/p&gt;

&lt;p&gt;CaptureSource.Start() will throw an InvalidOperationException if the same device is selected twice (once in each Camera control). I’m catching that exception and then displaying the “already in use” warning message when that scenario occurs.&lt;/p&gt;

&lt;p&gt;When I run the application, I can select two different cameras and display them at the same time:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l5s8n9gFul1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;You’ll receive the following error if you select a device that is already in use:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l5tati1deo1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Again, what is the point?  Well, I’ll leave that up to you. Theoretically the ability to run two video devices in Silverlight would allow you to, say, take pictures of yourself with one device while scanning barcodes with the other. I do that all the time. Kidding!  Geez!&lt;/p&gt;

&lt;p&gt;Another interesting example is that you can achieve a composite image by layering one visual element with less than full opacity over another element - and have both elements use VisualBrushes that pull from different video sources:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l5t957HXJo1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;I’ve just spawned a whole new genre of visual art…&lt;/p&gt;

&lt;p&gt;One “gotcha!” of using two web cams at the same time is that your browser and operating system might not be too happy with you. If you are constantly starting capture sources, debugging without stopping devices, plugging in and removing devices, and testing multiple browsers, you may experience a “hang” (or “crash”) in your Silverlight app when you call CaptureSource.Start().&lt;/p&gt;

&lt;p&gt;You can reproduce this problem in the Silverlight configuration tool. Right-click on your application, choose Silverlight, then choose the Webcam/Mic tab. In a crash-free scenario, your config tool will show this:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l5t9hpZRka1qzrj0v.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;In a scenario when your operating system and Silverlight can’t communicate with your video capture devices, the above tab will “hang” indefinitely and not display anything.&lt;/p&gt;

&lt;p&gt;To help minimize this problem with hangs and crashing, I encourage you to stop all CaptureSources when the application exits. This seems to make all those web cams and Silverlight play more happily together:&lt;/p&gt;

&lt;script src="http://gist.github.com/481539.js?file=stopall.cs"&gt;&lt;/script&gt;&lt;p&gt;That’s it. If anything, playing with multiple capture devices simultaneously is just good clean fun. Since &lt;em&gt;audio&lt;/em&gt; capture is very similar to video capture in Silverlight, you could probably do some crazy stereo imaging or something with audio capture using these techniques (I smell another blog post coming…).&lt;/p&gt;

&lt;p&gt;Have fun and enjoy!&lt;/p&gt;</description><link>http://hodnick.com/post/832399937</link><guid>http://hodnick.com/post/832399937</guid><pubDate>Mon, 19 Jul 2010 10:56:00 -0500</pubDate><category>silverlight</category><category>programming</category><category>code</category><category>video</category></item><item><title>Jackie, Nikki, and Eva</title><description>&lt;img src="http://28.media.tumblr.com/tumblr_l5rrzwA0UP1qzrz0oo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Jackie, Nikki, and Eva&lt;/p&gt;</description><link>http://hodnick.com/post/828892456</link><guid>http://hodnick.com/post/828892456</guid><pubDate>Sun, 18 Jul 2010 15:09:31 -0500</pubDate></item><item><title>First visit to Target Field</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_l5rrybaYzi1qzrz0oo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;First visit to Target Field&lt;/p&gt;</description><link>http://hodnick.com/post/828889382</link><guid>http://hodnick.com/post/828889382</guid><pubDate>Sun, 18 Jul 2010 15:08:35 -0500</pubDate></item><item><title> </title><description>&lt;img src="http://25.media.tumblr.com/tumblr_l55uisV6QK1qzrz0oo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;</description><link>http://hodnick.com/post/778744067</link><guid>http://hodnick.com/post/778744067</guid><pubDate>Tue, 06 Jul 2010 18:56:44 -0500</pubDate></item><item><title> </title><description>&lt;img src="http://26.media.tumblr.com/tumblr_l55uixPo211qzrz0oo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;</description><link>http://hodnick.com/post/778744365</link><guid>http://hodnick.com/post/778744365</guid><pubDate>Tue, 06 Jul 2010 18:56:44 -0500</pubDate></item><item><title> </title><description>&lt;img src="http://29.media.tumblr.com/tumblr_l55uinBRLT1qzrz0oo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;</description><link>http://hodnick.com/post/778743815</link><guid>http://hodnick.com/post/778743815</guid><pubDate>Tue, 06 Jul 2010 18:56:44 -0500</pubDate></item></channel></rss>
