Click here to Skip to main content
6,292,426 members and growing! (10,596 online)
Email Password   helpLost your password?
Multimedia » Audio and Video » Audio     Intermediate

Playing .wav files using C#

By Marc Merritt

An article demonstrating how to play chosen and user-defined sounds in the .NET framework
C#.NET 1.0, .NET 1.1, Win2K, WinXP, Win2003VS.NET2003, Dev
Posted:5 Aug 2003
Updated:10 Aug 2003
Views:144,374
Bookmarked:58 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
28 votes for this article.
Popularity: 6.16 Rating: 4.26 out of 5
2 votes, 7.1%
1

2
1 vote, 3.6%
3
6 votes, 21.4%
4
19 votes, 67.9%
5

Sample Image - player.jpg

Introduction

To achieve some things in the .NET Framework, one must make platform invocation calls to the underlying OS, or use one of the thinly-wrapped COM objects exposed as a class library. This example shows how to play .WAV sounds from a file picker, or play a user-defined sound by enumerating the Windows registry. Since Microsoft did not include a method for playing sounds in the Framework, we must make a PInvoke call to the PlaySound() function located in the Winmm.dll library. The PlaySound function is extremely simple to use as you'll see below.

The PlaySound function

bool PlaySound(
    LPCSTR pszSound,    // filename

    HMODULE hmod,    // handle to resource file

    DWORD fdwSound)    // sound flags

For this example, we play a sound directly from a filename, therefore we need only specify values for pszSound and fdwSound; The hmod parameter must be set to NULL unless playing a sound from a resource.

Partial Source

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;    // for PInvoke

using Microsoft.Win32;    // RegistryKey


namespace PlaySound
{
    public class Form1 : System.Windows.Forms.Form
    {
        ...
        private RegistryKey key1;
        private RegistryKey key2;




        // collection of user-defined sound events

        private PropertyCollection events;    

        // PlaySound()

        [DllImport("winmm.dll", SetLastError=true, 
                                CallingConvention=CallingConvention.Winapi)]
            static extern bool PlaySound(
                string pszSound,
                IntPtr hMod,
                SoundFlags sf );

        // Flags for playing sounds.  For this example, we are reading 

        // the sound from a filename, so we need only specify 

        // SND_FILENAME | SND_ASYNC

        [Flags]
        public enum SoundFlags : int 
        {
            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 

        }
        
        ...

        private void buttonPlay_Click(object sender, System.EventArgs e)
        {
            int err = 0;    // last error


            try
            {
                // play the sound from the selected filename

                if (!PlaySound( tbFileName.Text, IntPtr.Zero,
                    SoundFlags.SND_FILENAME | SoundFlags.SND_ASYNC ))
                    MessageBox.Show(this,
                           "Unable to find specified sound file or " +
                           "default Windows sound");
            }
            catch
            {
                // grab the underlying Win32 error code

                err = Marshal.GetLastWin32Error();
                if (err != 0)
                    MessageBox.Show( this,
                        "Error " + err.ToString(),
                        "PlaySound() failed",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error );
            }
        }

        // browse button handler

        private void buttonBrowse_Click(object sender, System.EventArgs e)
        {
            string sysRoot = System.Environment.SystemDirectory;
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.AddExtension = true;
            dlg.Filter = "Wave files (*.wav)|*.wav|All files (*.*)|*.*" ;
            // start in media folder

            dlg.InitialDirectory = sysRoot + @"\..\Media";    
            // open dialog

            if(dlg.ShowDialog(this) == DialogResult.OK)
            {
                tbFileName.Text = dlg.FileName;
            }
        }

        ...
        
        // fill combobox with user-defined sounds

        private void PopulateDropDown()
        {
            // fill our PropertyCollection object

            events = GetUserDefinedSounds();

            // disable if no sound events

            if (events.Keys.Count == 0)
                cbUserSound.Enabled = false;
            else
            {
                foreach (string key in events.Keys)
                {
                    cbUserSound.Items.Add(key);
                }
            }
        }

        // Retrieves the user-defined sounds from the registry

        private PropertyCollection GetUserDefinedSounds()
        {
            string rootKey = "AppEvents\\Schemes\\Apps\\.Default";
            PropertyCollection coll = new PropertyCollection();

            try
            {                
                // open root key

                key1 = Registry.CurrentUser.OpenSubKey(rootKey, false);

                // go through each subkey

                foreach (string subKey in key1.GetSubKeyNames())
                {
                    // open subkey

                    key2 = key1.OpenSubKey(subKey + "\\.Current", false);
                    
                    // get filename, if any

                    if (key2 != null)
                        if (key2.GetValue(null).ToString().Length > 0)
                            coll.Add(subKey, key2.GetValue(null).ToString());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "Yikes!", 
                                  MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                // close keys

                key1.Close();
                key2.Close();
            }
            
            return coll;
        }
        
        ...        
    }
}

You probably noticed the SetLastError=true parameter in the DllImport call. This simply states that the runtime marshaler calls GetLastError for us in the event something went wrong with our PInvoke call.

Points of Interest

This code has only been tested on Windows 2000 and XP SP1 using Framework version 1.1, however it should also work as far back as Windows 98. Oh yes, the project file is VS.NET 2003 - sorry.

History

Version 1.0 - 07.25.03 - First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Marc Merritt


Member
Doing my own consulting gig these days. It's so fun to work in your pajamas and act professional.

I live in southeastern Pennsylvania, USA with my lovely wife and two beautiful daughters. Life is good.
Occupation: Web Developer
Location: United States United States

Other popular Audio and Video articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 24 of 24 (Total in Forum: 24) (Refresh)FirstPrevNext
Generalwhy dont just add windows media player? Pinmembervishal108220:56 2 May '09  
GeneralStop Playing PinmemberMartinLarsson2:38 18 Feb '09  
GeneralRe: Stop Playing PinmemberMarc Merritt3:03 18 Feb '09  
GeneralCode to play audio/video file Pinmemberreogeo20083:01 28 Aug '08  
Questionhow todefine visibility of a control in a datalist by clicking on a button which is also in datalist Pinmemberrahul25260:14 14 Jun '08  
Questionusing this dll in vista Pinmembergurumosch22:21 19 Nov '07  
AnswerRe: using this dll in vista PinmemberMarc Merritt4:23 20 Nov '07  
QuestionWhat about mp3??? PinmemberIbrahim Dwaikat10:01 7 Nov '07  
GeneralRe: What about mp3??? PinmemberDavid ITA18:42 31 Mar '08  
GeneralAlternative - using sound recorder to play wave file programmatically Pinmemberdaluu15:44 19 Jul '07  
Generalwinmm.dll's PlaySound fails to work after compiling my application Pinmemberdaluu15:31 19 Jul '07  
GeneralThanks!!! PinmemberHelbrax6:01 23 Mar '07  
GeneralBookmark a given point in the wav files. Pinmemberywchen14:38 7 Apr '06  
GeneralPlaying a resource PinmemberDave Midgley5:02 24 Jan '06  
GeneralThanks! PinmemberJoe Pardue12:12 21 Nov '05  
GeneralRecording .wav files PinmemberRicardo Mendes5:57 2 Feb '05  
GeneralRe: Recording .wav files PinmemberDave Midgley4:57 24 Jan '06  
GeneralVery simple PinsusseVeryOne0:51 28 Apr '04  
General[Message Deleted] PinmemberMarc Merritt15:42 28 Apr '04  
GeneralRe: Very simple Pinmemberwenger2k8:24 25 Oct '04  
GeneralRe: Very simple PinmemberHui Shen0:43 6 Jan '05  
GeneralRe: Very simple PinmemberMuammar©22:32 8 Jan '07  
GeneralSound File From Memory PinmemberTboner19:44 20 Aug '03  
GeneralRe: Sound File From Memory Pinmembermusketeer_aramis11:51 9 Jun '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 10 Aug 2003
Editor: Nick Parker
Copyright 2003 by Marc Merritt
Everything else Copyright © CodeProject, 1999-2009
Web19 | Advertise on the Code Project