.
GDI+ FAQ
Skip Navigation LinksWelcome : Windows Forms Tips and Tricks : How to play a sound

How to play a sound.

Windows Forms classes are bereft of a simple way to play sounds. This glaring oversight is however easily rectified with a little bit of platform-invoke interop.

There are a couple of ways to do this. The first method requires the multimedia API sndPlaySnd and a few constants defined but once this is done you can add sounds to your Windows Forms applications easily. This API is a subset of the PlaySound API which can also be accessed through interop.

First you need to import the sndPlaySound or PlaySound API from the multimedia DLL. Interop enables us to import these signatures in a number of ways. For example, in some configurations the sndPlaySound method can be passed the address of a .WAV sound stored in memory but C# and VB are a bit finicky about casting strings to pointers so we can overload the p/invoke import statement to provide a version of the method signature that accepts an IntPtr instead of a string.

[DllImport("Winmm.dll")]

static extern int sndPlaySound(string lpszSound,  int fuSound);

[DllImport("Winmm.dll")]

static extern int sndPlaySound(IntPtr ptr,  int fuSound);

The constants required for the multimedia functions can be converted from the old C++ header files.

 enum soundConstants

 {

  SND_SYNC =           0x0000,  /* play synchronously (default) */

  SND_ASYNC =          0x0001,  /* play asynchronously */

  SND_NODEFAULT =      0x0002,  /* silence (!default) if sound not found */

  SND_MEMORY =         0x0004,  /* pszSound points to a memory file */

  SND_LOOP =           0x0008,  /* loop the sound until next sndPlaySound */

  SND_NOSTOP =         0x0010,  /* don't stop any currently playing sound */

 

  SND_NOWAIT =     0x00002000, /* don't wait if the driver is busy */

  SND_ALIAS =      0x00010000, /* name is a registry alias */

  SND_ALIAS_ID =   0x00110000, /* alias is a predefined ID */

  SND_FILENAME =   0x00020000, /* name is file name */

  SND_RESOURCE =   0x00040004, /* name is resource name or atom */

  SND_PURGE =          0x0040,  /* purge non-static events for task */

  SND_APPLICATION =    0x0080,  /* look for application specific association */

 }

 

Then, to play a sound simply call the method and provide the sound file.

sndPlaySound(@"C:\Sounds\Explosion1.wav", (int)soundConstants.SND_ASYNC);

You can embed a .wav file into your application by adding it to the application and then setting the build action to "embedded resource" in the solution item properties. This enables you to ship an application with the sounds built into the resources and so there are no extra files to distribute.

Getting at the file is a little more complex than simply nominating the filename an must be done using a Garbage Collector handle (GCHandle) and a pinned array. The following listing assumes a file has been embedded in the resources and is accessible as a stream.

   Stream s=this.GetType().Assembly.GetManifestResourceStream("PlaySound.win_1.wav");

   byte[] buffer=new byte[s.Length];

   s.Read(buffer,0,(int)s.Length);

   GCHandle h=GCHandle.Alloc(buffer);

   IntPtr ptr=Marshal.UnsafeAddrOfPinnedArrayElement(buffer,0);

   sndPlaySound(ptr,(int)soundConstants.SND_MEMORY | (int)soundConstants.SND_ASYNC);

   h.Free();

Return to Windows Forms Tips and Tricks

Visit the GDI+ FAQ.

Copyright Bob Powell 2004. All rights reserved.

Sponsored By
DaraizeTechnologies.com

&
Proteus Groupe

Bob Powell

Create your badge

Copyright © Bob Powell 2000-2012.  All rights reserved.