Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

.Finalize(): What Does That Beep Mean?

The sounds that an application makes are important. Learn to use the new System.Media.Soundplayer in .NET 2.0 and use the My.Computer.Audio functionality in VB.NET.


advertisement
pparently, only a fraction of the people who live in Florida actually live in Florida. At least, that's what the tax collector thinks, because if you actually do suffer through the entire year here, they give you a prize. It's more like the prize you find in the Crackerjacks box—a small tax break on property taxes. If you can prove you're a full-time resident, they knock off a few bucks. After settling in back in February, we decided to face the local county tax collector and work this out.

As with most bureaucratic departments, it's all about the forms. And documentation. One damp February day, we got on our bikes (looking for any excuse to run errands self-powered) and headed to the county tax collector's office, armed with all of the documents we had found listed on their Web site. We took a number, and waited. And waited. After a seemingly interminable time-out, our number came up. To the desk we went only to be rebuffed: unless we had FL drivers' licenses, we weren't getting our prize. Bzzzzt. Round one over.

Fast forward three weeks. We won't even go into the process of getting a driver's license, which also took two trips to the DMV (a 30-minute drive) because of missing documentation. Armed with the appropriate documentation, we headed back to visit our friend, the county tax collector. This time, we got past the "take a number," the wait, and the documentation, and were on our way to a tax break that would cover, if lucky, a nice weekend vacation.

So we're standing there as the nice lady types in the appropriate information, and we start hearing Windows sounds that normally indicate failure, or error. (To hear the sound I'm referring to, go to the C:\Windows\Media folder, and double-click Windows XP Critical Stop.wav file. It's not a good sound.) The sound plays, several times.

By this point, we're getting more and more nervous, figuring that at any moment, the tax collector net will descend and we'll be carted off to debtor's prison without even a trial. Not that I really have anything to be worried about-I'm very honest with Mr. Tax Man, really. Finally, I asked the representative of the tax collector (in a joking sort of tone, hoping to alleviate some of the assumed tension in the air) "So what's up with all the errors?" Her response: "There aren't any errors. That's the noise the program makes when we enter a correct value."

I'd love to find the developer who wrote this software. Why play a sound that's clearly linked to system failure on correct data entry? That sound, to be honest, makes me cringe every time I hear it. It's a Pavlovian response—I hear the sound, my blood pressure goes up. Talk about your bad UI design!

Of course, in .NET applications prior to the upcoming 2005 release, it was difficult to play sounds at all. The .NET Framework 1.x didn't include any native support for multimedia-your choices were either to use the managed extensions for DirectX, call the Windows API, or use a third-party component of some sort that did one of those for you.

In the latest release, however, you can take advantage of the System.Media namespace to play Windows .WAV files. (If you want to play other file formats, you'll need to investigate elsewhere.) The System.Media.SoundPlayer class provides the tools you need in order to be just as annoying as the tax collector's developer-in its simplest form, you can play a sound using code like this:

The Play method plays its sound asynchronously-the following code executes immediately. You can also investigate the PlaySync and PlayLooping methods-the PlaySync method delays any further code in the thread until the sound has finished playing. The PlayLooping method does what it says-plays the sound in a loop until you call the SoundPlayer.Stop method. This one is guaranteed to drive end users nuts. Try it-declare the SoundPlayer variable at the class level. In the Click event of one button, put the code shown above, calling the sp.PlayLooping method. In another button's Click event handler, add a call to the SoundPlayer.Stop method. Think of the fun you can have!

If you have stored your sound files as resources in your project, you'll most likely retrieve each as a System.IO.Stream. In that case, you can set the SoundPlayer.Stream property to load the player, rather than specifying a file location.

Because some sound files can be quite large and can take time to load, the SoundPlayer class also provides Load and LoadAsync methods. The Load method loads the sound synchronously, but silently. The LoadAsync method loads the sound asynchronously. Both methods raise the SoundPlayer's LoadCompleted event. In that event handler, you could call the Play method to play the sound.

The SoundPlayer class also raises its StreamChanged and SoundLocationChanged events, so your code can handle changes to the stream or file location, perhaps updating the user interface as the file or stream changes.

That's really all there is to this simple class. Visual Basic 2005 developers get some extra love here—the System.Media.SoundPlayer class is wrapped up in the Microsoft.VisualBasic.Devices.Audio class, which is exposed via the My.Computer.Audio reference, with some extra treats. For example, Visual Basic developers who want to play system sounds don't have to locate the actual file to play. Instead, you can write code like this:

My.Computer. _ Audio.PlaySystemSound( _ SystemSounds.Asterisk)


The System.Media.SystemSounds enumeration is small (it includes only Asterisk, Beep, Exclamation, Hand, and Question), but it does make it simple to play basic system sounds. The My.Computer.Audio class also provides several overloaded versions of its Play method (you can specify a file name, and a play mode [Background, BackgroundLoop, or WaitToComplete]), an array of bytes and a play mode, or a stream and a play mode). You can call My.Computer.Audio.Stop to cancel a looping sound, and that's the entirety of this simple, but elegant, wrapper.

No, you won't write the next great MP3/WMA player using the SoundPlayer class (or its wrapper, My.Computer.Audio), but this simple class provides an easy way to add audio to your applications. Just promise me you won't use audio for the forces of evil, as did the clearly misguided developer at the Palm Beach County Tax Collector's office. (If that developer is reading this, by the way, please understand that there's nothing personal meant by this. Really. And I didn't write this article. My evil twin did it. Don't come looking for me.)



   
Ken Getz is a senior consultant with MCW Technologies and splits his time between programming, writing, and training. He specializes in tools and applications written in Visual Studio .NET and Visual Basic. Ken is the author of the highly rated .Finalize() column in CoDe Magazine. He is also the co-author of several best-selling books, including Access 2002 Developer's Handbooks with Paul Litwin and Mike Gunderloy, Visual Basic Language Developer's Handbook with Mike Gilbert, and VBA Developer's Handbook with Mike Gilbert (Sybex). He co-wrote several training courses for Application Developer's Training Company, including VB.NET, ASP.NET, Access 2000 and 97, Visual Basic 6, and Visual Basic 5 seminars. He has also recorded video training for AppDev covering VB.NET, ASP.NET, VB6, Access 2000, and Access 97. Ken is a frequent speaker at technical conferences and has spoken often at Microsoft's Tech-Ed conference. Ken's also a technical editor for Access-VB-SQL Advisor magazine and a columnist for Informant Publications' asp.netPRO magazine..
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap