Scott Hanselman

Learning WPF with BabySmash - Speech Synthesis

June 11, 2008 Comment on this post [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. He is a failed stand-up comic, a cornrower, and a book author.

facebook bluesky subscribe
About   Newsletter
Hosting By
Hosted on Linux using .NET in an Azure App Service
June 12, 2008 1:10
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.
June 12, 2008 1:15
Scott,

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

Huh?

BOb
June 12, 2008 3:35
... 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\/\/

June 12, 2008 3:36
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.
June 12, 2008 3:37
Oops! I just used my Yahoo OpenID instead of the main one.
June 12, 2008 4:29
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.
June 12, 2008 6:09
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!
June 12, 2008 8:36
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.
June 12, 2008 9:11
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
June 12, 2008 9:13
By the way, you cracked me up with: I thought to myself, "self, why not text to speech?"
June 12, 2008 9:41
Good point on the power thing. Know how to prevent a shutdown from code?
June 12, 2008 10:31
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!
June 12, 2008 18:05
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.
Tom
June 12, 2008 22:11
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.
June 12, 2008 23:04
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...
June 26, 2008 19:53
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.