January 18, 2009

iPhone Home Theater Remote Control Project

Posted at 23:50 in home theater , iPhone , web services . | 0 Trackbacks | 1 Comments

"Who needs universal remotes or expensive home automation products when you have a computer in your pocket?" This is the question I asked myself a few weeks ago while growing tired of managing the four remotes and mouse and keyboard that control my home theater components. There was a break in my otherwise hectic schedule and I hadn't taken on any cool personal projects in a while, so I thought, why not build something.

In the months prior, I have built a handful of components to control my home theater components, but I have never tied them together. After all, where would I control them from? The iPhone, always being in my pocket or within an arm's reach, is the answer to that question. So, I decided to build a home theater remote control for my iPhone.

I considered writing a native iPhone application, but I don't have an Intel Mac and the investment wasn't worth it. Besides, the HTML support of the iPhone is superb and there are many templates out there for creating very impressive-looking HTML applications for iPhone.

In a few hours, I was able to piece together a nifty-looking web site that displayed my musical library. It took a few more hours to hack together the backend components and expose them through HTTP so the iPhone's browser could make AJAX calls.

Here are all the details:

Components

  • Pioneer PDP-5080 television
  • Emotiva MMC-1 preamp
  • Emotiva XPA-5 amplifier
  • PC running Vista 64
  • Foobar 2000 audio player

Interconnections and Control

  • RS-232 to TV
  • RS-232 to preamp
  • trigger cable between amp and preamp (for amp's power)
  • Foobar plugins running HTTP and socket servers for control
  • TOSLINK audio cable between PC and preamp
  • Apache HTTP server w/ mod_perl

Other Requirements

  • Music library with full MusicBrainz tags (I used Picard)

Features and Capabilities

  • Full control of preamp functionality, including power toggling, input switching, and volume control
  • Basic control of television, including power toggling and input switching (I only using my television as a monitor, so this is all I need)
  • RESTful HTTP APIs to Foobar 2000 to play or enqueue tracks, albums, artists, stop and start playback, pause, change tracks, etc
  • iPhone-optimized website to control everything and view system status
  • Bluetooth signal polling to toggle system power state (powers on when I walk in range and powers off when I leave)

Screenshots

I still have a bit of work to do in the UI department, but here are some screenshots.

Main Screen
Main Source Control
Music Index
Album List
Album Info
Emotiva Control

Future Enhancements

I currently don't have my DVR/cable tuner or DVD player bussed into my PC. Neither offers a remote control method besides IR. I will likely purchase or build an IR transmitter to control these components in the near future. (I may take the easy road and buy a TiVo, which I believe has a sufficient network-level API.)

I have built a few applications to control my home theater using voice and Vista's built-in speech recognizer. However, I don't have a good way of shipping audio from my couch to my PC. My living room layout won't allow a cable to be routed. A Bluetooth microphone is possible, but seems a little awkward. Ideally, the iPhone would record utterances and ship them, but I would need to write a native application for that. Microphone arrays (for optimal noise cancellation and audio pick-up from across the room) would be a possible solution, but I'm not satisfied with any current product.

Regarding Perl

Long-time readers may have noticed I am using Perl instead of PHP for the backend. It took a while after first exposure, but I have warmed up to Perl. Actually, it has usurped PHP as my language of choice for all areas where PHP once held the crown. There are still some parts of PHP I like better, but the language just didn't scale to meet my needs. Specifically, it didn't give me the low-level control and flexibility that Perl offers. And, CPAN puts PEAR to shame.


September 10, 2008

iTunes Genius FAIL

Posted at 1:55 in Apple , iTunes . | 0 Trackbacks | 1 Comments

I downloaded iTunes 8 today in hopes that it would fix the 1+ hour sync times with my iPhone (it did). I saw the news blurbs about the new "Genius" feature, so I thought I'd give a try. First, I had to transcode a few albums from FLAC to MP3 (because iTunes can't read FLAC files, sigh).

So, I quickly converted the complete Led Zeppelin studio discography (all 10 discs from the Complete Studio Recordings collection) and imported them in iTunes. I clicked on a random album, and things got funky. A screenshot can best illustrate.

genius_fail.jpg

Um, yeah. Not only was I playing Stairway when it said I was missing it, but I also had every single track in the list of "missing" tracks. Helloooo?

It got even better when I imported Abbey Road from The Beatles (published on the Apple label, of course).

Genius sidebar could not find matches for your specific selection, but here are the Top Songs and Albums in the iTunes Store.

In all fairness, Genius did seem to work pretty well for a few more recent artists (like Coldplay and U2). Since recommendations appear to be limited to what is in the iTunes Store (I don't want this to sound like criticism because it is likely a calculated business decision), I think I'll stick to Last.fm's recommendation engine for now. It may not be as pretty, but it has a wider scope of coverage and more than one player can Scrobble to it.



July 6, 2008

Bluetooth Proximity Detection

Posted at 0:49 in Personal . | 0 Trackbacks | 3 Comments

Call me a dork, but I just wrote a quick application that looks for the Bluetooth signal from my cell phone and performs actions depending on whether it is detected. Currently, I just have it turning my stereo on and off via the serial port control, but there are many more possibilities. I wonder, what else can I remote control with my computer...



June 24, 2008

Phishing Attempt for Case Webmail

Posted at 18:39 in security . | 0 Trackbacks | 1 Comments

I hope nobody falls for this:

from Case Support Team
reply-to Support-Team@jmail.co.za
to undisclosed-recipients
date Tue, Jun 24, 2008 at 10:12 AM
subject [photos-admin] Cofirm Your Account!!!
mailing list Filter messages from this
mailing list
mailed-by case.edu
Dear Case Webmail Subscriber

This message is to inform all our {CASE} webmail users that we will be
maintaining and upgrading our website in a couple of days from now.
As a Subscriber you are required to send us your Email account details to
enable us know if you are still making use of your mail box.
Be informed that we will be deleting all mail account that is not
functioning to enable us create more space for new users, You are to send
your mailaccount details which are as follows:

*User Name:
*Password:
*Date of birth:

You can also confirm your email address by logging into your Edu account
at http://webmail.case.edu/ before sending us the required
information.

WARNING: Any of our webmail user that refuses to send his/her
verification details within the next seven(7) days of receiveing this
message and failed to respond will be deleted immedately from our
database.

verification code: Cu:65248671/852#

Thank you for using Case!
From The Case Support Team.
©Case Western Reserve University



June 18, 2008

How to Identify a Well-Mastered CD: The Definitive Test

Posted at 1:53 in music . | 0 Trackbacks | 0 Comments

It seems nearly every CD has fallen victim to the Loudness War. I could go on a rant about how much talent is being thrown away at the mastering studio, but instead, I'll share a quick bit of advice for identifying a CD that is the victim of the Loudness War.

If the CD sounds good in your car -- you can hear detail and the album "rocks" -- the CD has a highly compressed dynamic range and is a victim of the Loudness War.

Since my new speakers arrived a few months ago, I've been listening to old CDs and purchasing new ones en mass. What I've quickly learned is that any album that sounds amazing in my living room sounds like crap in my car. Conversely, albums that sound like crap in my living room are amazing in the car. I have yet to find one album that sounds great in both locations. Of course, "great" is now highly skewed because of the quality of my living room setup, but I digress.



May 5, 2008

Yuck!

Posted at 17:38 in Case IT . | 0 Trackbacks | 3 Comments
New www.case.edu designs

This post's title says it all.

Please do the university a favor a leave a comment on the survey on how utterly sucktastic the proposed (flash) designs are.



April 8, 2008

I'm the Proud Father of Twins

Posted at 21:48 in Personal , home theater . | 0 Trackbacks | 0 Comments

My twins were delivered today. Pictures at http://picasaweb.google.com/gregory.szorc/SalkSongTowers. Aren't they beautiful?



April 6, 2008

Using DTD's and Catalogs for XHTML Validation

Posted at 1:48 in PHP , XML . | 0 Trackbacks | 5 Comments

If you are like me, whenever you develop web sites or pages, you constantly find yourself validating the generated XHTML using the W3C Markup Validator (TIP: the Web Developer Firefox extension has an option under the "Tools" menu to validate local source, which automatically uploads the source to the validation service).

This approach is a good start, but it is far from ideal because it is based on an honor system of sorts. You often forget to validate each change you make and there is always some corner case that you forget. So, what can be done about it?

Well, if you find yourself developing in PHP, you can employ the following solution.

First, you need the output of your script available to the PHP script itself. If you are using one of the many frameworks out there, chances are you have a $response->getBody() function or equivalent. If you aren't saving output to a string, use the Output Control functions to capture script output to a string. For example,


ob_start();
header('Content-Type: application/xhtml+xml');
print '<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head />
<body>
<!-- stuff here -->
</body>
</html>';

$xhtml = ob_get_clean();

Now, you have the XHTML (supposedly XHTML 1.1) in a string variable. Now, we need to plug in the validation part. All you need is PHP's DOM extension with libXML support. This extension has functions built-in to validate XML. But, instructions for optimally configuring it are hard to find (if they even exist).

The basic recipe for validating the XHTML/XML response is the following,


libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->loadXML($body, LIBXML_DTDLOAD | LIBXML_DTDATTR);

if (!$doc->validate()) {
  foreach (libxml_get_errors() as $err) {
    print $err->line . ' : ' . $err->message . PHP_EOL;
  }
}

You can actually use any kind of error handling you want. My personal favorite is to split the XHTML string by newlines and then correlate the $err->line to the actual line in the output so you can print error context and figure out what the offending code is.

When you run the above code, you will find that script execution becomes extremely slow or you will get some cryptic error about remote URI's not being accessible. The reason is that the validate() call will fetch the referenced DTD's in your XML. In the above example, it will fetch http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd and any files referenced by that document.

But, the W3C doesn't like people who fetch DTD's all day, so we need a way to avoid the remote file fetching.

This is where XML Catalogs come to the rescue (see #1 and #2 for more about XML Catalogs). Basically, XML catalogs allow you to map remote entities into a local space, mainly your file system. In this case, we will be using XML catalogs to map the XHTML DTD files to your local filesystem so validation doesn't have to go across the internet to access necessary files.

The first step is to define mappings of remote URI's to the local filesystem. On my Gentoo Linux install, this file is /etc/xml/catalog. In this file, I add the following mappings:


<rewriteSystem systemIdStartString="http://www.w3.org/MarkUp/DTD" rewritePrefix="file:///etc/xml/www.w3.org/MarkUp/DTD"/>
<rewriteSystem systemIdStartString="http://www.w3.org/TR" rewritePrefix="file:///etc/xml/www.w3.org/TR" />

There is probably a way to do this with the 'xmlcatalog' program distributed as part of libXML, but I am lazy.

The above example maps http://www.w3.org/MarkUp/DTD to /etc/xml/www.w3.org/MarkUp/DTD and http://www.w3.org/TR to /etc/xml/www.w3.org/TR. Any remote entity existing under one of the above URL's will be mapped to the corresponding local filesystem location.

Once you make these additions, try to run the XML validation in your script again. It will probably fail fast, but this time with a different error message. It will most likely say that it couldn't find /etc/xml/www.w3.org/TR/xhtml11/DTD/xhtml11.dtd. So, you need to add it to your filesystem.

Create the necessary directory structure in your local filesystem (e.g. /etc/xml/www.w3.org/TD/xhtml11/DTD). Then, start downloading the missing files needed for validation. The XHTML 1.1 DTD's can be found in http://www.w3.org/TR/xhtml11/xhtml11.tgz.

Once you have that, you will need to find all the modular XHTML files. You can find these inside http://www.w3.org/TR/xhtml-modularization/xhtml-modularization.tgz. Be sure to place the files in directories that match the mapping you created in your XML catalog file.

Now, try running validation again. If it complains about missing files, just fetch them one at a time from w3.org until you get no more errors about missing files.

After you have put all of these files on your local file system, calls to validate() should be quick and will immediately tell you if your output conforms to XHTML 1.1. No need to use the W3C service!

So, there you have it. An easy and quick method for automatically validating script output for XML compliance!

Finally, you will probably want to turn off XML validation on production web sites because it adds unnecessary overhead. But for developing, it is an invaluable asset! Even though the above example was for XHTML 1.1, the same methods can be used to validate any XML that has a DTD, schema, or RelaxNG description available.

Update 1, April 6
Added content-type header to help remind people it is needed. Some rewording all around.



April 5, 2008

Why I May Never Ship DHL Again

Posted at 16:00 in DHL , misc . | 0 Trackbacks | 0 Comments

Last Friday, I had three packages shipped from Michigan to my home in San Mateo, CA via DHL ground. I finally received tracking numbers on Wednesday evening and went to DHL's web site to see the status. They were both scheduled for delivery the next day, Thursday.

Thursday morning, I once again checked the tracking status and saw that the packages were in Santa Monica, which is by LA, 400 miles south of me. I thought this was weird, since they were scheduled for delivery that day. I called up customer service to see what the problem was. It turns out the destination zip code on the packages was incorrectly listed as 90024 (Santa Monica, CA) instead of 94403 (San Mateo, CA). As a result, the packages made it all the way to Santa Monica before they realized the address was really 400 miles north. I'm puzzled as to how this can happen because you'd think on package scan they would do a geocode of the address and compare to the zip code and alert if something seemed wrong (e.g. the distance between the two points was greater than 50 miles or something). Anyway, the conversation with customer service went well and they stated the packages would arrive the next day, on Friday.

Later in the day, I again checked the tracking status to see if the information was updated. The destination zip was still listed as 90024 and it said to contact customer service. Again, I called and talked with an agent. I explained that I had called earlier to update the zip code and they said everything was in order on their end. It is just the web site can sometimes run a little behind. Great. This second agent also confirmed that the packages would arrive on Friday.

So, Friday comes. I'm fully expecting delivery of the packages. I leave a signed note on my door to let DHL know they can leave them there. Around 3 PM, I leave work early and head home in anticipation of playing with the contents of my packages. I get home and nothing. The note is still on the door and no packages are there. I check DHL's web site. It states the packages are scheduled for delivery on April 3 (the day before) and has no status updates. Great.

I call up customer service for the third time. They say the packages are traveling from the regional distribution center near LA to the one in South San Francisco and should arrive any moment. Wanting the packages before the weekend, I ask if I can pick them up at the sorting facility. They confirm I can and I give them my telephone number, which they promise someone should call in the next hour or so to say the packages are ready for pickup in South San Francisco.

An hour comes, and passes. No word from DHL. I call them back. This customer representative says the packages are still in the southern regional hub and the one I talked to an hour ago had bogus information. Are you kidding me?! At this point, it was after normal business hours, so I'm pretty sure I can't pick up the packages in South San Francisco. So, I confirm they will be put on a truck for delivery instead of waiting for me to pick them up. To my surprise, the agent said that because of the zip code screwup, they will be delivered on Saturday, despite the fact they are only ground service. Oh well, what's another day?

Before I go to bed, I check the tracking information. Both packages have left the southern regional hub and are presumably on their way to South San Francisco. Good, it sounds like I really will get them on Saturday. I leave a note on my door saying to drop them off in case the delivery happens before I wake, then I head to bed.

I wake up, open the door, and nothing. So, I wait. I periodically check DHL's web site. It still says the packages are scheduled for delivery on April 3, now two days prior. There hasn't been an update since 2:00 AM, when one of the packages left the southern facility (the other one left around 12:00 AM).

Usually I go on a bike ride on Saturdays, but I wanted to stay at home and wait for the packages. So, I'm sitting around, waiting. Around 1 PM, I grow restless because the tracking information hasn't been updated. I call customer service. The lady says the package is on its way to Santa Monica! Aggghh! I tell her that zip code is wrong and the real zip code has been updated. She quickly realizes the error on her end and sees they are going to San Mateo. Whew. I ask about the state of the packages and she informs me they haven't been scanned at the South San Francisco facility yet. You are kidding me, right? If they haven't been scanned, they aren't out on a truck for delivery -- and customer service yesterday twice stated they would be delivered on Saturday!

At this point, I am pretty pissed off. I try to vent as calmly as possible to the agent. I know she didn't cause the problem, but I explain that I called up Thursday and they said they would be delivered on Friday. I called up Friday and they said they would be delivered on Saturday. I call up on Saturday and hear they won't be delivered until Monday. Every time I call, the delivery date seems to be "tomorrow." It sounds like I am being told what I want to be told rather than reality. Furthermore, I'm not getting consistent information from the agents. I ask that she kindly relay my plight to management. Who knows what that'll do.

At this point, I'd like to think that I will receive notification of the packages' arrival in South San Francisco so I can drive up and retrieve them today (Saturday) instead of waiting until Monday. But, after all that has happened, I'm very pessimistic.

This being my first interaction with DHL, I am very disappointed. Although I was impressed with the speed with which I could talk to a customer representative, that service is all but useless if you receive inaccurate information. I cannot begin to comprehend how you can talk to five different agents and hear five different stories.

Oh well, it sounds like I have another 48 hours of waiting. That will be 4 days after it was initially scheduled and 3 days after when a customer service agent promised it would be delivered after correcting the zip code mistake.



February 24, 2008

Ahh, Comcast

Posted at 15:35 in Comcast . | 0 Trackbacks | 4 Comments

Comcast has caused troubles and tribulations before. Their new act, although presented with less drama than previous, is still hideous.

I recently moved from Santa Clara to San Mateo. My new abode, like the old one, is only serviced by Comcast. So, I needed to get service transitioned. Simple, right?

When I called Comcast and scheduled the switchover, everything went without a hitch. The technician even showed up on time and service was hooked up without incident (unless you count that I couldn't retain my existing DVR and cable modem because they were incompatible with the systems in San Mateo -- 25 miles from where I was living).

After the rather smooth transition, my stock in Comcast started ascending. Then, things got funky.

Within the span of two days, I received two separate Comcast bills. One for my new address. The other, for the old. Of course, the service billing dates for the old address were after I had moved out. Not only were they still billing me for the old address, but they had included an installation fee for my new address, something which would be free according to both the telephone service representative and the technician who performed the installation.

Like I always do, I called Comcast to address the issues. The installation charge was removed and they assured me that I don't have to pay the Santa Clara bill. According to them, it takes a month or two for the old address to be removed from the system and I will continue to receive bills until that happens. Huh? Back that up. In a day and age where you have electronic central billing systems that allow up to the second accurate access to information as it changes, you will be unable to stop billing me for a few months and I should just ignore the bill. Are you kidding me?

Comcast, your procedures confound me. It is no wonder that Comcast is the only recurring bill I have not set up for automatic payment: I simply don't trust them to deduct the proper amount.



February 6, 2008

Why Can't They Get This Voting Thing Right

Posted at 23:20 in politics . | 0 Trackbacks | 0 Comments

When I moved to California in Jan 2007, I didn't feel like declaring a party affiliation. But, come election time, I decided to change it from non-partisan to a specific party. I made the change well before the voter registration deadline and received confirmation in the mail. But, when I showed up to the polling place yesterday for the California primary, they had me registered as non-partisan. If you believe the online community, apparently I wasn't alone.

The worst part about it was that when I said something about a phone number you can call (California has a toll-free number to call regarding voting issues), the people at the polling place knew nothing of it and told me to call another number, which I did, and got somebody's personal voice mail.

You'd think that the poll workers would at least be competent and know how to deal with this stuff. I did cast a ballot, but not for the party and candidate that I had intended. Ah, politics.



January 28, 2008

The Facebook Tax

Posted at 1:39 in Facebook , Palo Alto , Silicon Valley . | 0 Trackbacks | 0 Comments

As much as I love Facebook, I feel compelled to share one of their sinister creations: The Facebook Tax.

Facebook has this amazing benefit that if you live within a certain range of their offices, which are conveniently located in the very trendy and yuppie haven of University Ave. in Palo Alto, you get a $600/mo living expenses credit. It is an awesome benefit, and one I would definitely use if my company offered it (even though downtown Mountain View doesn't have the wannabe San Francisco atmosphere of University Ave).

Now, what this benefit has done has caused Facebook employees to not only snatch up numerous apartments in Palo Alto (to the extent that when I go to one, the first question out of the landlord's mouth is, "do you work for Facebook?") but it has also created an artificial rate increase for eligible apartments. Units near Facebook that would go for $1200-$1500/mo elsewhere in the bay area are going for $1600-$2000/mo because landlords know that Facebook employees are willing to pay for it.

I have dubbed this apartment rent increase the "Facebook Tax." Anyone living near University Ave. that is not working for Facebook must pay it. There is no getting around it.

While I was content in paying the University Ave. Yuppie Tax, the additional Facebook Tax is just too much. Although I could afford to pay both taxes, why should I? Paying more for less is not rational. Besides, I'd rather take the saved money and put it towards a yuppiemobile.

So, while the Facebook crowd enjoys taking over University Ave., I'll be enjoying the proximity to San Francisco and cycling mecca that is San Mateo. Oh, and I'll be harnessing the most powerful force in the universe! Take that, financially irresponsible yuppies!



January 8, 2008

Enable HTTP Pipelining in Firefox for a Speed Enhancement

Posted at 22:49 in . | 0 Trackbacks | 0 Comments

A coworker and I today were talking a bit about network optimization today, when the subject of HTTP pipelining came up. Something led to me looking up the subject on Wikipedia, where I discovered that pipelining is not enabled by default in Firefox.

Anyway, the folks at Mozilla have a wonderful pipelining FAQ as well as instructions for enabling pipelining in Firefox.

After enabling pipelining in Firefox, I was greeted by a very modest speedup of page rendering. It is pretty noticeable on sites that are heavy on the accessory files (graphics, javascript, css, etc).

So, if you want a quick speed boost, type "about:config" in Firefox's location bar and enable the "network.http.pipelining" preference.



November 30, 2007

What a Difference a DAC Makes

Posted at 3:02 in Personal , home theater . | 0 Trackbacks | 0 Comments

The home theater bug is getting the best of me again, which means I am heavily researching my next purchase.

As part of the process for selecting speakers, I am putting together an audition CD, which consists of clips of various types of music (classical, jazz, rock, vocal, etc). I listen to the CD religiously on as my "reference" setups, which are my Klipsch computer speakers and my surprisingly decent sounding car stereo (Alpine receiver + CDT speakers).

After listening to a few recordings in both environments, I noticed that my computer setup was severely lagging behind the car. I was hearing detail in the car that I couldn't on the computer -- even when traveling! Something had to be wrong, especially since I remember my computer sounding better than my car.

Could it be my computer speakers were failing? Was some sound setting configured improperly?

It turns out, everything was configured properly. I just fell victims to the marketers. When I bought my new computer, the Gigabyte DS3R motherboard came with an advertised "high performance DAC with a 106dB S/N playback quality." I just kind of assumed that it would be comparable to my aging Sound Blaster Audigy Platinum (I think they have Audigy 4's now). In addition, I wasn't willing to "pollute" my new black case with the Audigy's beige drive bay expansion unit (I guess I never made the connection I could install the PCI card without the expansion unit).

What a mistake that was.

Tonight, I decided to put in the Audigy to see if that would affect the sound quality. From the first few notes emanating from the new setup, I could tell what a different it made. Everything is so much cleaner and crisper. The clarity and definition across the spectrum is now where it should be. It is as if a blanket that had been draped over the speakers has been lifted away. Oh, it sounds so beautiful now.

This is definitely the last time I trust the built-in audio on a motherboard to be high quality.

Now, I just need to figure out what speakers, pre/pro, and amp to buy. I am currently enamored with the Emotiva Holiday Deals (especially the IPS-1). It is more than I need right now, but those offers are just too good. I keep telling myself that I need to select speakers first. Aye aye aye. The only way this is ending is with my wallet a lot lighter...



November 10, 2007

Talking to My Television

Posted at 18:51 in .NET , C# , Personal , home theater , speech , speech recognition . | 0 Trackbacks | 2 Comments

I can now control my Pioneer PDP-5080 plasma television by using my voice. How cool is that!

Using Visual Studio 2008 Express, I was able to create a C# application that utilizes the .NET System.IO.Ports.SerialPort class and System.Speech.Recognition namespace to manipulate settings on my television. Currently, I am able to perform simple commands, like turning the television on and off, muting, adjusting volume, etc. But, the Pioneer RS-232 Protocol supports nearly every function you could want, so the sky is really the limit.

I was really surprised at how efficiently I was able to write a working program. I was expecting it would take upwards of 20 hours to figure out C# and the necessary API's, but, Visual Studio made it a snap! This was my first C# application, so there was a learning curve there. However, the language is similar enough to C++ and Java that it made picking up a breeze. The excessive amount of online tutorials and examples were also a plus. The only difficulty I had was figuring out how exactly to build grammars in .NET. The GrammarBuilder interface wasn't intuitive at first, with SemanticResultKey, SemanticResultValue, SemanticValue, and other classes confusing me at first. But, once I realized that I could just instantiate a GrammarBuilder with Choices, create a new Grammar from that, and then name the grammar, and finally load that named grammar into the SpeechRecognizer, it was all down hill. For the future, unless I need to use the API's grammar building functions, I think I will just create SRGS files manually.

So, now that I have a grasp on how to program voice recognition into programs, the sky is the limit for what's next. When I finally get around to buying a receiver, I'll be sure to get one that has a published RS-232 protocol. Then, I'll be able to say things like "Play DVD," and my receiver will be told to switch to the correct input, the television will follow, etc. Until then, I can always look into adding voice control for typical home theater PC functions. Both Winamp and foobar2000 (my two preferred audio players) have SDK's available. I would love to control my playlist via voice. It can be annoying navigating a library of a few thousand songs. Using your voice is so much more efficient.

Anyway, back to hacking.