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 boxa 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 responseI 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:
method plays its sound asynchronously-the following code executes immediately. You can also investigate 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
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
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 herethe 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:
The System.Media.SystemSounds enumeration is small (it includes only Asterisk
, 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
, 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.)