Larry Osterman's WebLog

Confessions of an Old Fogey
Blog - Title

So how do I play sounds anyway?

So how do I play sounds anyway?

  • Comments 11

Well, the answer to that is WAY more complicated than I can answer, there are LOTs of different ways, and I’m not qualified to talk about most of them.

But I can talk about some of the easier ways to make noises.

The first, and simplest one is PlaySound (and its little brother sndPlaySound).

The PlaySound API takes a WAV file (or resource) and plays its contents.  A WAV file is essentially raw PCM data with additional information describing the sample size and the sample rate (there’s more to it, but that works).

So to play a “ding”, you can just call:

        PlaySound(“ding.wav”, NULL, SND_FILENAME);

That’s it, the “ding” sound will play on your speakers.

But that’s not all you can do with PlaySound.  You can embed a resource in your executable and play that resource by specifying SND_RESOURCE – in that case, the sound name (ding.wav in the example above) is a resource ID and that resource will be extracted and treated as a WAV file and played.

In addition, you can use PlaySound to play sounds that are controlled by the sound themes control panel applet.  All versions of Windows support a set of default events (SystemAsterisk, SystemExit, SystemStart, etc) that can be played by simply calling:

        PlaySound(“SystemAsterisk”, NULL, SND_ALIAS);

This will play whatever sound is set for the “Asterisk”.

PlaySound can also be used to play sounds looped (with SND_LOOP), you can have it play asynchronously (SND_ASYNC), etc.

One important caveat with SND_ASYNC – SND_ASYNC means that the playback of the sound file is asynchronous.  But before the sound can be played, the sound needs to be loaded into memory, which involves loading resources, opening files, etc, and all of these can take some time to complete.

If all you need to do for your app is to make dings and whatnot, PlaySound is actually pretty cool, and remarkably lightweight.

 

  • What about from pure managed code (ie no PInvoke)?
  • I'll be honest and say that the 1.0 framework doesn't have a good story for multimedia events.

    I believe that there are plans for a better story in future versions of the framework, but...
  • I looked this one up on pinkvoke.net just a few days ago, and it works fine.
  • Chris, I'm sure that Stuart knows you can P/Invoke it, it's a dead simple API, so..

    But he's spot-on in saying that the framework doesn't handle multimedia at all.

    This will undoubtedly be fixed, but I'm not sure when (I'm not a CLR person).
  • > SND_ASYNC means that the playback of the
    > sound file is asynchronous.

    Hmm. By any chance is the Windows XP PCMCIA driver using that where previous versions of Windows didn't? In Windows XP, sometimes I get the pair of tones indicating that Windows recognized removal of a PCMCIA card, and then I remember that 15 minutes ago I indeed removed one.

    By the way it doesn't seem to matter if I got Windows XP's permission to remove the card first. If I'm going to remove an external hard drive (USB, or USB via a CardBus card, or SCSI) then of course I'd better get permission first. But if it's a DVD or CD or floppy drive with no media in it, or a CardBus USB card with no device on the other end, sometimes I just pull it out without asking first. In previous versions of Windows the recognition sounds were immediate, but in Windows XP the sounds might be 5, 15, or 30 minutes later.
  • cat foo.wav > /dev/audio
  • ga,
    How does /dev/audio know the sample rate of foo.wav? Or does it just assume that the sample rate is some constant?

    Norman,
    SND_ASYNC means that the sound is actually played on a separate thread (inside winmm.dll), playing the sound is inherently synchronous to winmm, but we let the application's thread go before the sound finishes playing.
    What you're seeing is the time between when you plug in the card and the PnP notification that the card's been plugged in is received by the shell. There's a lot of things that have to happen before the shell notification plays (like swapping in the shell notification code, and the PnP notification sound, etc). That may be the cause of a large part of the delay.
  • Instead of SND_ALIAS, you can use MessageBeep. Strangely, though, MSDN says that it's not sent to the client under Terminal Services.
  • IIRC, in order for /dev/dsp or /dev/audio to play a file correctly you have to configure it with a call to the ioctl function in <sys/ioctl.h>.
  • I've noticed a similar issue with my Compaq Tablet PC when I remove it from the keyboard. I think the keyboard is a mini usb hub with three HID devices, the keyboard, touchpoint and the swivel switch that changes the screen orientation. I get a couple of ding-dongs straight away after seperating the keyboard, and another one about 10 minutes later. Wierd.
Page 1 of 1 (11 items)