Scott Hanselman

Learning WPF with BabySmash - Speech Synthesis

June 11, '08 Comments [16] Posted in BabySmash | Windows Client | WPF
Sponsored By

image NOTE: If you haven't read the first post in this series, I would encourage you do to that first, or check out the BabySmash category. Also check out http://windowsclient.net/ for more developer info on WPF.

BACKGROUND: This is one of a series of posts on learning WPF. I wrote an application for my 2 year old using WPF, but as I'm a Win32-minded programmer, my working app is full of Win32-isms. It's not a good example of a WPF application even though it uses the technology. I'm calling on community (that's you, Dear Reader) to blog about your solutions to different (horrible) selections of my code. You can get the code http://www.codeplex.com/babysmash. Post your solutions on your blog, in the comments, or in the Issue Tracker and we'll all learn WPF together. Pick a single line, a section, or subsystem or the whole app!

There's been a flood of interesting content coming in around BabySmash, including WPF Expert Karl Shifflett who found the original code so nasty that he rewrote it from scratch! I'll do a whole post analyzing his code and how I can refactor my own.

Before that, I wanted to share one little tidbit that isn't explicit to WPF but rather to the .NET Framework 3.0. Most folks think of .NET 3.0 (myself included) as being WPF (Windows Presentation Foundation), WCF (Windows Communication Foundation) and WF (Windows Workflow). However, there's a bunch of miscellaneous goodness in in .NET 3.0 that I always forget about.

In BabySmash I wanted to have the letters and shapes spoken when they appear on the screen, and lazily, rather than recording the sounds, I thought to myself, "self, why not text to speech?"

I know there's TTS (Text to Speech) stuff in Windows as COM Objects, so I went into Add Reference in Visual Studio, found the component and added it. A .NET wrapper got created that makes the COM object look like .NET and off I went.

Turns out that .NET 3.0 includes System.Speech, an official component that does all this for me. I yanked out the COM stuff and put System.Speech in, and got the added benefit of a Cancel method to stop any current speech. This is particularly helpful for BabySmash because when kids hit the keyboard fast the speech system slowed down as words to say queued up. It couldn't say the words as fast as they were said.

objSpeech = new SpeechSynthesizer();
objSpeech.SpeakAsyncCancelAll();
objSpeech.Rate = -1;
objSpeech.Volume = 100;
objSpeech.SpeakAsync(s);

//REMOVED COM STUFF
//objSpeech.WaitUntilDone(Timeout.Infinite);
//objSpeech.Speak(s, SpeechVoiceSpeakFlags.SVSFlagsAsync);

Additionally, by using the COM Component, I got into trouble where Vista has version 5.3 and XP had version 5.0. This made it difficult for developers using XP to build the program. This goes away when using the .NET assembly.

Hopefully I'll get to do more "refactoring via subtraction" as I dig deeper into .NET 3.x.

Also, thanks to Gina at LifeHacker for her post on BabySmash! The comments are pretty good, but the best interaction was these two comments:

"Wow, 15 years of progress with Windows and this is all we have to show for it? No wonder Windows is teh suckage."

Very supportive! ;) And a response from another random commenter:

"Wow, I've seen people take cheap shots at Windows, but this is the winner! A dad who writes a program for his son suddenly contributing to windows being 'teh suckage' ..."

Bam. Baby! Smash!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Wednesday, June 11, 2008 9:10:03 PM UTC
Thanks for the info Scott. It's always good to hear about things that were COM only in the past finally becoming part of the BCL.
Wednesday, June 11, 2008 9:15:31 PM UTC
Scott,

"It couldn't say the words as fast as they were said."

Huh?

BOb
Bob Archer
Wednesday, June 11, 2008 11:35:18 PM UTC
... who found the original code so nasty that he rewrote it from scratch!

some guy's have all the luck, I'm still searching someone who hates my GUI enough ;-)

PowerShell WMI Explorer WPF Edition first beta


Greetings /\/\o\/\/

Wednesday, June 11, 2008 11:36:49 PM UTC
Bob - Heh, ya, that doesn't parse does it? You know what I meant, though. ;) You could smash the keys and have to wait a full minute for the speech system to finish saying all the letters.
Wednesday, June 11, 2008 11:37:24 PM UTC
Oops! I just used my Yahoo OpenID instead of the main one.
Thursday, June 12, 2008 12:29:37 AM UTC
I have a warning for you...

Several years ago, I decided to make the most of some down time after heavy surgery and learn DirectX programming. I soon realized that drawing random 3D objects on the screen in response to any key press fascinated my 2 year old daughter to no end. Like any geek father, the idea of my daughter on a laptop - for whatever reason - was too great and I began improving my version of "baby smash" and letting her bang away, sometimes for an hour straight. Then it happened...

A laptop hard drive sits below the keyboard; in fact on most laptops you access the hard drive by removing the keyboard. Though the laptop hard drive can with stand the occasional bump or drop, the power of a 2 year old banging away with glee is beyond all fault tolerance capabilities.

I was lucky; the laptop was at the end, but still within, my 3 year warranty when it went sent in with a dead hard drive.
Thursday, June 12, 2008 2:09:53 AM UTC
I know nothing about programming but I do know that my 10 month old son is going to be in his glory when he gets a chance to "play" Babysmash. I had located an old DOS game with a similar concept of smashing on the keyboard for pictures to appear but there is no sound and it's doesn't lock the Windows key so it really wasn't feasible to let my son bash away. This holds great promise and I have several spare keyboards so if he breaks this one it's no big deal! Thanks again for this awesome little program!
Thursday, June 12, 2008 4:36:41 AM UTC
I've considered writing a similar program myself, but my 15 month old goes beyond smashing. In a lightning move she reaches over and pops the keys right off the keyboard. I wish she'd just smash.
Harold
Thursday, June 12, 2008 5:11:11 AM UTC
Another warning... and maybe a bug...

I let my 20-month-old play BabySmash for the first time tonight, and I got some video of him playing. But at the end of the video, he presses the power button on the laptop keyboard, and down the system goes! Baby-proof computing should prevent a shut-down! :-)

The funniest part is that I had done fast user switching, leaving my wife logged in with her dozen or so browser windows open. When the power button was pressed, it prompted to make sure my son wanted to shut the computer down, as there were others logged in. He managed to hit the correct key to confirm the shut-down.

My 4-year-old was battling to get his turn playing too though. They had a lot of fun with it tonight.

Thanks,
Jeff Handley
Thursday, June 12, 2008 5:13:56 AM UTC
By the way, you cracked me up with: I thought to myself, "self, why not text to speech?"
Thursday, June 12, 2008 5:41:34 AM UTC
Good point on the power thing. Know how to prevent a shutdown from code?
Scott Hanselman
Thursday, June 12, 2008 6:31:21 AM UTC
I am new to development. I am all for constructive criticism, but I am continually amazed at how humble anyone is required to be by some members of the development community when work is shared. It really seems that not all the disclaimers in the world will provide any guarantee of anyone coming away with their intestines halfway intact after these primadonnas are done with you.

What a pity.

Nice effort Scott!
Derick
Thursday, June 12, 2008 2:05:49 PM UTC
In unmanaged code, you can trap the WM_QueryEndSession message (Delphi implementation), but I'm not sure how it would be possible in managed code.
Thursday, June 12, 2008 6:11:34 PM UTC
The Application class has a SessionEnding event. This event is raised when the Windows session is ending. Its EventArgs is a CancelEventArgs, so if you set its Cancel property to true supposedly it will stop the shutdown process. In my experience, this can be really spotty. I think it's because you can't control the order in which things are shut down, and it might be asynchronous, so more often than not my application halts the shutdown but some critical service or application has already died so I have to restart anyway.

There's also the Microsoft.Win32.SystemEvents class, which has similar events that are raised when the session is ending or switching and when the power mode of the computer changes. It doesn't look like an interface to stop the power mode from changing is available, so I'm not sure exactly how useful it is.
Thursday, June 12, 2008 7:04:31 PM UTC
I was fascinated by the news about speech in .NET 3.0. So I checked it out and got some really bad speech out of the system (you know, with full sentences). I'd be very, very afraid to let the toddler get their pronunciation habits from the .NET Framework! Let us know if you hear some peculiar letter sounds...
Walter Lounsbery
Thursday, June 26, 2008 3:53:32 PM UTC
Is Karl Shifflett's rewrite available anywhere? I don't see it on his blog or the codeplex issue list.

BTW, love the BabySmash app and series. Makes the WPF learning curve a little less steep.
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.