Home > Guides > Programming > .NET and Windows Programming

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Playing Simple Sounds

Last updated Nov 4, 2004.

Playing Simple Sounds

Over the years, sound has become an important part of many applications. Surprisingly, the .NET Framework does not include a class that implements playing sounds, although you can call the Beep function (Microsoft.VisualBasic.Beep()) if you just want to make a simple noise. If you want to play other types of sounds, you have to dive into the Windows API. There are several different ways to play sounds, and the way you choose will depend on how rich you want your sound support to be. This entry will discuss the simplest way: using the PlaySound function.

About PlaySound

PlaySound is one function in a fairly large API set called the Waveform Audio Interface, which in turn is part of the Windows Multimedia interface. With the exception of the sndPlaySound function, which implements a subset of PlaySound functionality, the other functions in the Waveform Audio Interface present a very low-level method of playing sounds. Those functions (which all have the wave prefix) are very handy if you want to mix sounds and have very tight control over what gets played and when, but they're overkill if all you want is to play a simple sound. If you're interested in learning more about using the wave functions, you should read the article Recording and Playing Sound with the Waveform Audio Interface.

PlaySound is defined in the Windows API like this:

BOOL PlaySound(LPCSTR pszSound, HMODULE hmod, DWORD fdwSound);

The corresponding .NET managed prototypes for this function are:

[C#]

[DllImport("winmm.dll")]
public extern static bool PlaySound(
  string pszName, IntPtr hModule, int dwFlags);

[Visual Basic]

<DllImport("winmm.dll")> Public Shared Function PlaySound( _
  ByVal pszName As String, ByVal hModule As IntPtr, _
  ByVal dwFlags As Integer) As Boolean
End Function

The first parameter to PlaySound is normally the name of the sound file that you want to play. PlaySound only plays waveform audio files (.WAV). This parameter can also be interpreted as an alias for a system event, a resource identifier, or even a pointer to a .WAV file that has been loaded into memory. In this section, we'll concentrate on the parameter being used as a file name.

If the first parameter is a resource identifier, then the second parameter, hModule is used to pass the handle of the executable file that contains the resource. Since we won't be loading sounds from resources here, we'll pass IntPtr.Zero as the second parameter.

The third parameter is the ubiquitous "flags" parameter that all too many Windows API functions use. This is a bitmapped value that specifies how the first parameter is to be interpreted, and also how the system should play the sound. As you will see below, you can select a number of different options with this parameter.

The Windows API header files define the different flags values as constants that have the SND_ prefix. In .NET programs, that sort of thing is more commonly expressed as an enumeration, like this:

[C#]

[Flags]
public enum SoundFlags
{
  SndApplication = 0x80,   // look for application specific association
  SndAlias = 0x10000,     // name is a WIN.INI [sounds] entry
  SndAliasId = 0x110000,   // name is a WIN.INI [sounds] entry
  SndAsync = 0x1,       // play asynchronously
  SndFilename = 0x20000,   // lpszSoundName is a file name
  SndLoop = 0x8,       // loop the sound until stopped
  SndMemory = 0x4,      // lpszSoundName points to a memory file
  SndNoDefault = 0x2,     // Do not play default sound if sound file not found
  SndNoStop = 0x10,      // Do not stop currently playing sound
  SndNoWait = 0x2000,     // Do not wait if sound is currently playing
  SndPurge = 0x40,      // purge non-static events for task
  SndResource = 0x40004,   // lpszSoundName is a resource name or atom
  SndSync = 0x0        // play synchronously (default)
}

[Visual Basic]

<Flags()> Public Enum SoundFlags
  SndApplication = &H80    ' look for application specific association
  SndAlias = &H10000     ' name is a WIN.INI [sounds] entry
  SndAliasId = &H110000    ' name is a WIN.INI [sounds] entry
  SndAsync = &H1       ' play asynchronously
  SndFilename = &H20000    ' lpszSoundName is a file name
  SndLoop = &H8        ' loop the sound until stopped
  SndMemory = &H4       ' lpszSoundName points to a memory file
  SndNoDefault = &H2     ' Do not play default sound if sound file not found
  SndNoStop = &H10      ' Do not stop currently playing sound
  SndNoWait = &H2000     ' Do not wait if sound is currently playing
  SndPurge = &H40       ' purge non-static events for task
  SndResource = &H40004    ' lpszSoundName is a resource name or atom
  SndSync = &H0        ' play synchronously (default)
End Enum

Note that the enumeration has the Flags attribute applied so that the values can be combined using an arithmetic "or" operation.

Discussions

Copies of the array?
Posted Dec 23, 2008 03:40 PM by luige21
1 Replies
Hi
Posted Dec 5, 2008 05:10 AM by ajay2000bhushan
2 Replies
You have no clue.
Posted Jun 10, 2008 03:28 PM by theinternetmaster
1 Replies

Make a New Comment

You must log in in order to post a comment.

Related Resources

Jim Mischel"Highly unlikely" does not mean "impossible"
By Jim MischelJuly 18, 2009 No Comments

One of my programs crashed the other day in a very unexpected place.  A call to System.Threading.ConcurrentQueue.TryDequeue (from the Parallel Extensions to .NET) resulted in an OverflowException being thrown.  Investigation revealed a pretty serious bug in the System.Random constructor.

It's Here; Put Away Your Pre-Conceptions on What an OS Must Be: Part II
By John TraenkenschuhMay 24, 2009 No Comments

In the last blog in this series, Traenk relates his first experiences with computers and with coding.  But now, some years have passed. . .

It's Here; Put Away Your Pre-Conceptions on What an OS Must Be: Part I
By John TraenkenschuhMay 24, 2009 No Comments

Traenk relates his past experience with Operating Systems that goes back 25 years, ok, more than that but he ain't tellin'

See More Blogs

Informit Network