UbGames

Sound Generation in C#

sound and music

Adding Sound and Music to your game in C#

In this tutorial, you will learn how to handle sound and music files in C#.

When we think of creating a video game, often the first things that come to mind are the visuals, the story lines, and the memories created when someone plays the game. Having sound in your game is just as important to the players gaming experience.

Sound can set the mood of the player while playing a game. A smooth upbeat melody can bring out happy feelings while sharp chords can make tense or frightened emotion.

Sounds can directly correlate to good or bad actions for the player. Destroying an enemy might have a happy sound, but being destroyed by that enemy might have a sad sound.

Because sound is a necessary part of any game program, it is apparent to know how to program these sounds so they can be heard.

The System.Media Namespace contains classes for playing sound files and accessing sounds provided by the system.

The following classes are included in this namespace:

  • SoundPlayer class – used for loading and playing sounds from a .wav file.
  • SystemSound class – used for representing and playing a system sound.
  • SystemSounds class – used to retrieve sounds associated with a set of Windows operating system sound-event types.

In this tutorial we will discuss the SoundPlayer class, which provides a simple interface for loading and playing a sound (.wav) file. The SoundPlayer class supports loading a .wav file from a file path, a URL, a Stream that contains a .wav file, or an embedded resource that contains a .wav file.

You can load or play a .wav file synchronously or asynchronously.

Synchronously or Asynchronously

  • Synchronously – existing or occurring at the same time.
  • Asynchronously – (of two or more objects or events) not existing or happening at the same time.

If you call a synchronous load or play, the file must be loaded before it can be played.

If you call an asynchronous load or play, you do not need to wait for the sound to be played.

Before you can use the SoundPlayer class, you need to initialize a new instance of the SoundPlayer class using one of the SoundPlayer class constructors.

Following are the constructors included in this SoundPlayer class:

SoundPlayer() – Initializes a new instance of the SoundPlayer class.

public SoundPlayer ();

This constructor initializes a SoundPlayer with no audio source. Until it is configured with an audio source path, the SoundPlayer will play a beep sound when one of its playback methods is called.

SoundPlayer(Stream) – Initializes a new instance of the SoundPlayer class, and attaches the .wav file within the specified Stream.

public SoundPlayer (System.IO.Stream stream);

The Stream passed to the stream parameter should be a Stream containing a .wav file. The data returned by the Read method of the Stream should be the data within a .wav file.

SoundPlayer(String) – Initializes a new instance of the SoundPlayer class, and attaches the specified .wav file.

public SoundPlayer (string soundLocation);

The string passed to the soundLocation parameter can be either a file path or a URL to a .wav file. If the path or URL is not valid, the SoundPlayer will still be constructed, but subsequent calls to a load or play method will fail.

There are several properties, methods, and events for the SoundPlayer class, but the most common are listed below.

Properties

  • SoundLocation property – Gets or sets the file path or URL of the .wav file to load. If no file path is present the value is Empty.
  • LoadTimeout property – Gets or sets the time, in milliseconds, in which the .wav file must load. After this time (10 seconds) has expired, the loading is canceled and a TimeoutException exception is thrown.
  • IsLoadCompleted property – Gets a value indicating whether loading of a .wav file has successfully completed. Boolean value true if a .wav file is loaded; false if a .wav file has not yet been loaded.

Methods

  • Load method – Loads a sound synchronously.
  • LoadAsync method – Loads a .wav file from a stream or a Web resource using a new thread. Begins to load a sound asynchronously.
  • Play method – Plays the .wav file using a new thread, and loads the .wav file first if it has not been loaded. Plays the sound specified in the SoundLocation or Stream property in a new thread.
  • PlayLooping method – Plays and loops the .wav file using a new thread, and loads the .wav file first if it has not been loaded. Plays the sound specified in the SoundLocation or Stream property in a new thread.
  • PlaySync method – Plays the .wav file and loads the .wav file first if it has not been loaded. Plays the sound specified in the SoundLocation or Stream property in the current thread.
  • Stop method – Stops playback of the sound if playback is occurring.

Events

  • LoadCompleted event – Raised after the load of a sound is attempted.

The other class of the System.Media Namespace worth mentioning is the SystemSounds class to play common system sounds, including a beep.

The following is the syntax for the sound function:

//Gets the sound associated with the Beep program event in the current Windows sound scheme.

System.Media.SystemSounds.Beep.Play();

This does exactly what you might expect, it beeps the computer’s speaker. The beep function is rather limited, because it lacks the ability to change the tone and duration of the beep. The sound varies from computer to computer, but it’s good for simple audio feedback.

You can get better sound with the SoundPlayer Class.

Play and PlayLooping methods

The Play method plays the .wav file. The Play method is useful in a space game if you want to hear a sound when you fire the weapon.

This example plays a sound at a given path. The SoundPlayer class is first initialized and the sound file is loaded and played when the playButton is clicked.

Using System.Media;

namespace SoundPlayerPlay

{

       public partial class Form1 : Form

       {

              //initialize the SoundPlayer class

              private SoundPlayer Player = new SoundPlayer();

              private void playButton_Click(object sender, EventArgs e)

              {

              // the .wav file is loaded and ready to play.

              this.Player.SoundLocation = @”C:\Windows\Media\shoot.wav”;

              //plays the .wav file using a new thread

              this.Player.Play();

             }

       }

}

The PlayLooping method plays and loops the .wav file until stopped. The PlayLooping method is useful in a space game if you want to hear a sound when you repeatedly fire the weapon.

The following code example plays a sound repeatedly.

Using System.Media;

namespace SoundPlayerPlay

{

       public partial class Form1 : Form

       {

              //initialize the SoundPlayer class

              private SoundPlayer Player = new SoundPlayer();

              private void playLoopingButton_Click(object sender, EventArgs e)

              {

              // the sound is loaded and ready to play.

             this.Player.SoundLocation = @”C:\Windows\Media\shoot.wav”;

             //plays and loops the .wav file using a new thread

             this.Player.PlayLooping();

              }          

              private void stopPlayingButton_Click(object sender, EventArgs e)

              {

                     //stop playing the .wav file

                     this.Player.Stop();

             }

       }

}

When the code in the stopPlayingButton_Click procedure is executed, any sound currently playing stops. If no sound is playing, nothing happens.

Sound Examples:

There are two examples:

  1. SoundPlayer1 – Play, PlayLooping, PlaySync methods.
  2. SpaceInvasion6 – Sound added to the game.

Example 1: SoundPlayer1

sound player

The sound example (SoundPlayer1.sln) will illustrate the use the Play, PlayLooping, and PlaySync methods of the SoundPlayer class.

The System.Media Namespace contains the SoundPlayer class for loading and playing sound files. The following code is used to add the reference to the System.Media namespace.

Using System.Media;

The following code will initialize the SoundPlayer, set the path to the .wav file, load the .wav file, and play the .wav file.

private void PlaySimpleSound_Click(object sender, EventArgs e)

{

    string tSoundFileName = “kaboom.wav”;

    txtBoxSimple.Text = tSoundFileName.ToString();

    //assign the path to the sound file

    string filePath = Application.StartupPath + “\\” + “Sounds” + “\\” + tSoundFileName;

    //Initialize a new instance of the SoundPlayer class.

    //Then the location is set for the sound.

    SoundPlayer splayer2 = new SoundPlayer

    {

        // Set location of the .wav file

        SoundLocation = filePath.ToString()

    };

       //check if the path set for the sound file, default is false

    if (splayer2.SoundLocation != string.Empty)

    {

        //Loads the sound synchronously

        splayer2.Load();

    }

    else

    {

        MessageBox.Show(“Please load sound file!”, “Error”, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

    }

    if (splayer2.IsLoadCompleted == true)

    {

        //Plays the .wav file, and loads the .wav file first if it has not been loaded.

        splayer2.Play();

    }

    else

    {

        MessageBox.Show(“Please load sound file!”, “Error”, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

    }

}

Run the program, and click on the “Play Sound File” button. The PlaySimpleSound_Click procedure is executed. The .wav (kaboom.wav) file is assigned the variable tSoundFileName, which is displayed in the textbox named “txtBoxSimple”.

Next, the path to the .wav file is assigned to a variable “filePath”. Then a new instance of the SoundPlayer class is assigned to splayer2 and the location of the .wav file is set using the string of the “filepath” variable.

Next, the splayer2.SoundLocation is checked for an empty string, this should be the path for the .wav file. If the file was found, we can load the .wav file using the Load method, splayer2.Load(). Otherwise, we need to flag an error.

Next, the splayer2.IsLoadCompleted is checked, if the value is true, the .wav file is played using the Paly method, splayer2,Play().

The sound will play every time the user clicks the “Play Sound File” button.

This SoundPlayer1 example includes a function to play a sound and loop the sound. You can also browse your computer, select a .wav file and play the sound file using the Play, PlayLooping, and PlaySync methods.

Example 2: SpaceInvasion6

spaceinvasion6

The sound example (SpaceInvasion6.sln) will illustrate the Play method to provide a sound when the weapon is fired.

In this example you can use the “A, D or Arrow” keys to move left or right. Use the “Spacebar” key to fire the weapon.

The System.Media Namespace contains the SoundPlayer class for loading and playing sound files. The following code is used to add the reference to the System.Media namespace.

Using System.Media;

Next, variables were added for the sound file, the path to the sound file, and to initialize a new instance of the SoundPlayer class.

//the path to the sound file

public static object SoundFilePath;

//used for Player sound: simple_bullet_shot.wav, 3.wav, spaceship_firing.wav

public string SOUNDFILENAME1 = “fire1.wav”;

//Initialize a new instance of the SoundPlayer class.

private SoundPlayer Player = new SoundPlayer();

In the Form1_Load procedure, the path to the sound file is set, the location of the sound file is added to the Player.SoundLocation property, the location is checked for a valid path, then the sound file is loaded using the Load method.

private void Form1_Load(object sender, EventArgs e)

{

       //assign the path to the sound file

      SoundFilePath = Application.StartupPath + “\\” + “Sounds” + “\\” + SOUNDFILENAME1;

      // Set location of the .wav file

      Player.SoundLocation = SoundFilePath.ToString();

      //check if the path set for the sound file, default is false

      if (Player.SoundLocation != string.Empty)

      {

            //Loads the sound synchronously

            Player.Load();

      }

}

The PlaySoundFire procedure is added to play the .wav file when the weapon is fired, using the Play method.

private void PlaySoundFire()

 {

    //check if the sound file is loaded and was the weapon fired?

    if (Player.IsLoadCompleted == true && shooting == true)

    {

        //Plays the .wav file, and loads the .wav file first if it has not been loaded.

        Player.Play();

    }

}

Now, all we need to do is call the PlaySoundFire procedure where we want to play the sound file.

After the bullet is created, is where we want to play the sound file. The CreateBullet procedure is used to create the bullet and call the PlaySoundFire procedure.

private void CreateBullet(string bulletTag)

{

    PictureBox bullet = new PictureBox

    {

        Image = Properties.Resources.bullet,

        BackColor = Color.Black,

        Size = new Size(5, 20),

        Tag = bulletTag,

        Left = player.Left + player.Width / 2

    };

    if ((string)bullet.Tag == “bullet”)

    {

        bullet.Top = player.Top – 20;

    }

    this.Controls.Add(bullet);

    bullet.BringToFront();

    //call to Play the .wav file

    PlaySoundFire();

}

Another thing to do is stop the sound player. This is done when the game is over. The Stop method is added to the GameOver procedure.

private void GameOver(string message)

{

    isGameOver = true;

    gameTimer.Stop();

    txtScore.ForeColor = Color.White;

    txtScore.Text = message.ToString();

    //stop sound Player

    Player.Stop();

}

Just adding sound to the game can improve the gaming experience.

When you execute or run the game, you will hear a sound when the “Spacebar” key is pressed to fire the weapon, but you should also notice a sound playing in the background.

Playing a Background Sound

The SoundPlayer class cannot play other file types, such as .wma or .mp3. If you want to play other file types, you can use the Windows Media Player control.

The background sound was added using NAudio, an open-source audio API for .NET written in C# by Mark Heath, with contributions from many other developers.

The API is intended to provide a comprehensive set of useful utility classes from which you can construct your own audio application.

NAudio is licensed under the MIT license which means that you can use it in whatever project you like including commercial projects.

The simplest way to get started with NAudio is to install the NAudio NuGet package. You can do this with the “Manage NuGet Packages…” context menu option for your project with Visual Studio:

PM> Install-Package NAudio

Before the NAudio can be installed, the application must be targeting .NET 3.5 or above.

In this tutorial we target .Net 4.7.1 and installed the version 1.8.4 of the NAudio API.

PM> Install-Package NAudio -Version 1.8.4

After the NAudio package was installed, a file called “Audio.cs” was added to the project. The Audio.cs contains a class for the load, play and stop procedures for playing the background sound.

Then the following code was added to the project.

The MyPath variable was added to hold the path to the sound file.

public static object MyPath;

Then a call to the Audio class was added in the Form1_Load procedure.

MyPath = Application.StartupPath + “\\” + “Sounds”;

//play music when form is loaded, will play .wav and .mp3 files

//Audio song = new Audio(“path to sound file”, looping=true/false);

Audio song = new Audio(MyPath + “\\” + “Level1.wav”, true);

song.Play();

Notice the two parameters sent to the Audio class, one was the “path to the sound file” and the other was “looping”. With looping set to “true” the background sound will continue to play until the game is closed.

Why use the NAudio API? You can play .mp3 files!

Just change the following code in the Form1_Load procedure:

  1. Comment out the following line.

Audio song = new Audio(MyPath + “\\” + “Level1.wav”, true);

  1. Uncomment out the following line.

//Audio song = new Audio(MyPath + “\\” + “piano.mp3”, true);

Then rebuild the solution and run the game.

Conclusion:

Now, you can add some neat sound effects to your games.

Game development

ubgames

Adding Sound To Your Game in C#