Chapter 8. Playing Sound Effects and Music

In years past, programming sound and music for games was an enormous task. Custom sound code was usually too difficult to write due to the conflicting standards among the various sound cards in the industry. Today, that is no longer a problem. Now a single, dominant hardware maker sets the PC audio standard and a single, dominant sound library sets the software standard. While some may argue the point, I believe that Creative Labs had the sound card market wrapped up with their Sound Blaster products, but today many mother-boards include very capable audio hardware. This chapter is a quick jaunt through the basic audio features of Visual Basic, with demos to show how to play sound effects and music files in Visual Basic, including the versatile MP3 format.

Here’s what we’ll cover in this chapter:

Programming Audio

Audio is always a fun subject to explore because sound effects and music can influence our emotions so dramatically. Could you imagine playing a game like Halo: Reach without audio? It would be a different experience entirely! What is a game without sound? Little more than a graphics demo, all but unplayable in my opinion (unless you’re playing late at night and don’t want anyone to know!). Sound is absolutely essential for the success of any game, in both the professional and indie market.

Even the simplest game needs some form of background music, or it is difficult for the player to remain interested. Remember this important rule of gaming: Any game without sound and music is just a technology demo. It is absolutely essential that you spend some of your development time on a game working on the music and sound effects. In fact, it is probably a good idea to do so during development. As the game takes shape, so should the sounds and music. Background music should reflect what is going on in the game and can even be used to invoke the emotions of the player. Consider a scene in which a beloved game character dies. Upbeat music would spoil the mood, whereas dark and menacing background music would engender feelings of remorse and sorrow (and perhaps even anger).

Keep this in mind when working on sections of a game and try to have a different background sequence for different circumstances. Victory should be rewarded with upbeat music, while menacing or dangerous situations should be accompanied by low-beat, low-tempo songs that reinforce the natural emotions that arise in such a circumstance. Later in this chapter, under the heading, “Using The Media Player Control,” I’ll show you how to use Windows Media Player to play an MP3 file in your game projects.

Ambient sound is a term that I borrowed from ambient light, which you might already understand. Just look at a light bulb in a light fixture on the ceiling. The light emitted by the bulb pretty much fills the room (unless you are in a very large room). When light permeates a room, it is said to be ambient; that is, the light does not seem to have a source. Contrast this idea with directional light and you get the idea behind ambient sound. Ambient sound refers to sound that appears to have no direction or source. Ambient sound is emitted by speakers uniformly, without any positional effects. This is the most common type of sound generated by most games (at least most older games—the tendency with modern games is to use positional sound).

Playing Wave Files

We can load and play a wave file using the class called System.Media.SoundPlayer. This class has limited features but gets the job done for simple sound effects needs. First, we create an object:

Dim audio As System.Media.SoundPlayer

By adding System.Media to the list of imports, we can refer to just SoundPlayer.

audio = new SoundPlayer()

There are two overloads of the SoundPlayer() constructor, one to specify the audio file and another to specify a System.10.Stream for loading the file. So, one way to load an audio clip is to pass the filename to the constructor:

audio = new SoundPlayer("sound.wav")

An option is to just use the default constructor and instead load the audio file manually. The SoundPlayer.SoundLocation property is used to specify the filename. Once set, we can use SoundPlayer.Load() to load the file.

audio.SoundLocation = "sound.wav"
audio.Load()

In either case, trapping errors is a good idea since a bad filename will generate an exception. We can write a LoadWave() function to trap errors and return a SoundPlayer object if loading succeeds.

Hint

If you have a very large wave file that may take a few seconds to load, use the SoundPlayer. LoadAsync() function and SoundPlayer.IsLoadCompleted() function to find out when loading has finished.

Public Function LoadWave(ByVal filename As String) As System.Media.SoundPlayer
    Dim sound As SoundPlayer = Nothing
    Try
        sound = New SoundPlayer()
        sound.SoundLocation = filename
        sound.Load()
    Catch ex As Exception
    End Try
    Return sound
End Function

Playing Wave Resources

We can play a wave file that has been added to the project as a resource using a class called Microsoft.VisualBasic.Devices.Audio. This class can play a wave from a file, from a byte buffer, from a stream, or from a resource. Since we can use System.Media.SoundPlayer to play waves from a file, we will just look at using the Devices.Audio class to play a wave that has been added to the project as a resource. One great advantage to using a resource file is that your game’s asset files are compiled into the executable and are no longer exposed so that the user can access them. Let me show you how to add a resource file to the project.

First, open the Project menu and choose Add New Item. Choose the list of General items, and then Resources File, as shown in Figure 8.1.

Adding a resource file to the project.

Figure 8.1. Adding a resource file to the project.

Next, double click the Resource1.resx file to open the project’s resources. Open the drop-down list of resource types and choose Audio, as shown in Figure 8.2.

Selecting the Audio resources list.

Figure 8.2. Selecting the Audio resources list.

Next, you can use the Add Resource drop-down list and choose a wave file to load, or you can just drag a wave file from Windows Explorer into the resource file asset pane, as shown in Figure 8.3.

The foom.wav file has been added to the project as a resource.

Figure 8.3. The foom.wav file has been added to the project as a resource.

To play an audio file from a resource, we can use the Microsoft.VisualBasic. Devices.Audio class.

Dim audioDevice As New Microsoft.VisualBasic.Devices.Audio

Or, by importing Microsoft.VisualBasic, we can refer to the class using just Devices.Audio. The Play() function has three overloads (plus the default), one of which accepts a resource. The second parameter is the AudioPlayMode enumeration with these options:

  • Background

  • BackgroundLoop

  • WaitToComplete

So, based on our “foom” wave file added to the Resource1.resx file in our project, this is what the code to play the audio looks like:

audioDevice.Play(My.Resources.Resource1.foom, AudioPlayMode.Background)

The Audio Demo Program

The Audio Demo program demonstrates how to load wave files into memory and play them using System.Media.SoundPlayer. To demonstrate how sounds are automatically mixed, the program actually loads up another sound file as well. There are two buttons on the form; each plays one of the sound buffers. There is not much to this program other than the simple form. You will need to add two buttons to the form, simply called Button1 and Button2, as shown in Figure 8.4.

The Audio Demo program demonstrates how to play audio files.

Figure 8.4. The Audio Demo program demonstrates how to play audio files.

Imports Microsoft.VisualBasic
Imports System.Media
Public Class Form1
    Dim audioDevice As Microsoft.VisualBasic.Devices.Audio
    Dim audio(4) As System.Media.SoundPlayer
    Public WithEvents button1 As Button
    Public WithEvents button2 As Button
    Public WithEvents button3 As Button
    Public WithEvents button4 As Button
    Public WithEvents button5 As Button
    Public WithEvents button6 As Button
    Public WithEvents button7 As Button
    Public WithEvents button8 As Button
    Public WithEvents button9 As Button
    Public WithEvents button10 As Button

    Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load
        Dim x = 10, y = 10
        REM create buttons used to play system sounds
        button1 = New Button()
        button1.Text = "Asterisk"
        button1.Location = New Point(x, y)
        button1.Parent = Me
        y += 30

         button2 = New Button()
         button2.Text = "Beep"
         button2.Location = New Point(x, y)
         button2.Parent = Me
         y += 30
         button3 = New Button()
         button3.Text = "Exclamation"
         button3.Location = New Point(x, y)
         button3.Parent = Me
         y += 30
         button4 = New Button()
         button4.Text = "Hand"
         button4.Location = New Point(x, y)
         button4.Parent = Me
         y += 30
         button5 = New Button()
         button5.Text = "Question"
         button5.Location = New Point(x, y)
         button5.Parent = Me
         y = 10
         x += 100
         REM create buttons used to play wave files
         button6 = New Button()
         button6.Text = "Launch1"
         button6.Location = New Point(x, y)
         button6.Parent = Me
         y += 30
         button7 = New Button()
         button7.Text = "Launch2"
         button7.Location = New Point(x, y)
         button7.Parent = Me
         y += 30
         button8 = New Button()
         button8.Text = "Missed1"
         button8.Location = New Point(x, y)
         button8.Parent = Me
         y += 30
         button9 = New Button()
         button9.Text = "Laser"
         button9.Location = New Point(x, y)

        button9.Parent = Me
        y += 30
        button10 = New Button()
        button10.Text = "Foom"
        button10.Location = New Point(x, y)
        button10.Parent = Me
        y += 30

        REM load audio file using constructor
        audio(0) = New SoundPlayer("launch1.wav")

        REM load audio file using Load function
        audio(1) = New SoundPlayer()
        audio(1).SoundLocation = "launch2.wav"
        audio(1).Load()

        REM load audio using our LoadWave function
        audio(2) = LoadWave("missed1.wav")
        audio(3) = LoadWave("laser.wav")

        REM create audio device
        audioDevice = New Devices.Audio()
    End Sub

    Public Function LoadWave(ByVal filename As String) _
            As System.Media.SoundPlayer
        Dim sound As SoundPlayer = Nothing
        Try
            sound = New SoundPlayer()
            sound.SoundLocation = filename
            sound.Load()
        Catch ex As Exception
        End Try
        Return sound
    End Function

    Private Sub button_clicked(ByVal sender As Object, _
            ByVal e As EventArgs) _
            Handles button1.Click, button2.Click, _
            button3.Click, button4.Click, button5.Click, _

            button6.Click, button7.Click, button8.Click, _
            button9.Click, button10.Click

        Dim button As Button = sender
        If button.Text = "Asterisk" Then
            REM play Asterisk sound
            SystemSounds.Asterisk.Play()
        ElseIf button.Text = "Beep" Then
            REM play Beep sound
            SystemSounds.Beep.Play()
        ElseIf button.Text = "Exclamation" Then
            REM play Exclamation sound
            SystemSounds.Exclamation.Play()
        ElseIf button.Text = "Hand" Then
            REM play Hand sound
            SystemSounds.Hand.Play()
        ElseIf button.Text = "Question" Then
            REM play Question sound
            SystemSounds.Question.Play()
        ElseIf button.Text = "Launch1" Then
            REM play loaded launch1.wav
            audio(0).Play()
        ElseIf button.Text = "Launch2" Then
            REM play loaded launch2.wav
            audio(1).Play()
        ElseIf button.Text = "Missed1" Then
            REM play loaded missed1.wav
            audio(2).Play()
        ElseIf button.Text = "Laser" Then
            REM play loaded laser.wav
            audio(3).Play()
        ElseIf button.Text = "Foom" Then
            REM player "foom" resource
            audioDevice.Play(My.Resources.Resource1.foom, AudioPlayMode.
Background)
        End If
    End Sub
End Class

Using the Media Player Control

What if you want to use a more advanced audio file, such as an MP3, for your game’s music? Although we don’t have a library available for this, there is an alternative that works quite well that I’ll introduce to you: the Windows Media Player control. You may be wondering: why would I want to use a Media Player control when we can already play audio files? Here’s the reason: for simple music playback, System.Media.SoundPlayer and Microsoft.VisualBasic.Devices.Audio are preferred. But there is a drawback—they don’t have very many options. Sure, you can play back an audio file, but that’s about all you can do. Beyond that, the features are pretty slim. The Media Player control, on the other hand, is full of features, as the Media Player Demo program demonstrates.

So how does this work? Visual Basic has the ability to embed an object on a form, and this capability is called OLE (Object Linking and Embedding). You can, for instance, embed an Excel spreadsheet on a VB Form, and it will be fully functional! There are some obvious licensing issues when you embed a whole application onto a form, and usually applications that do this sort of thing just assume that the software (such as Excel) has already been preinstalled on the end user’s PC. (The Excel control simply won’t work unless Excel is already installed). But there are some Windows applications that are so common that we can pretty much count on them being available. One example is Windows Media Player, which is automatically installed on Windows systems today. Even if someone is still using an older version of Windows, odds are they have Windows Media Player installed because it is free.

Referencing the Media Player

I’ve included a project with this chapter called Media Player Demo, which demonstrates how to use an embedded Media Player object. The Media Player is not available as a .NET Component, so we have to add it from the list of COM/ ActiveX components (see the COM tab in the Add Reference dialog box). See Figure 8.5—the ActiveX control is called Windows Media Player.

Adding a reference to the Windows Media Player control.

Figure 8.5. Adding a reference to the Windows Media Player control.

When the MediaPlayer control is available to the project, you can drag it from the Toolbox to the form. The complete design of the form is shown in Figure 8.6. Note that the Media Player control is on the bottom of the form, and in the Properties window on the right, its Visible property has been set to false. This will allow us to use the Media Player control in the program without it being visible, so our program will look as if it’s a real media player, while in fact it is just using the features built into the control (namely, the ability to load and play any type of media file).

Adding the Windows Media Player control to the form.

Figure 8.6. Adding the Windows Media Player control to the form.

The Media Player Demo program lets you type in details for each media file, including a filename (which can be a local or remote media file streamed over the Internet, as shown in Figure 8.7).

Media files can be played locally or streamed over the Internet.

Figure 8.7. Media files can be played locally or streamed over the Internet.

Playing MP3 and MIDI Files

You can play any media file with the Windows Media Player control by setting its URL property equal to a filename (or a URL to a file on a website, for instance). This is deceptively simple, because there is really no “play” function at all. Once you set the URL property to a filename, playback will automatically start. Likewise, if you want to stop playback, set the URL to an empty string (“”). The control can support the same media file formats supported by the full-blown Media Player, including MP3!

AxWindowsMediaPlayer1.URL = "symphony.rmi"

The program has a media player-like interface and it keeps track of audio files in an XML database. If you have any MP3 music files (and who doesn’t these days?) go ahead and copy a few to the project folder and add them to the program by clicking the “+” button and entering the filename and information. Then click the play button (“>”).

Since there is a form full of controls for this program, I will forego listing the source code here to save space, and instead encourage you to load the project and play around with it to learn how the Windows Media Player control works. It is extremely easy to use. Most of this program’s source code is wrapped up in just the user interface. To use the control in your own programs, just set its Visible property to false so it doesn’t show up on the form!

Level Up!

This chapter was a quick overview of Visual Basic audio support, giving you just enough information to add sound effects and music to your own games. By loading multiple sound files into memory and playing them at certain points in your game, you greatly enhance the gameplay experience. In a sense, you are the conductor of this orchestra by directing what happens in source code. You also learned how to use the Windows Media Player control for advanced audio file support such as MP3 files and streaming from a web URL. Just keep in mind that you cannot distribute copyrighted music.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.19.14.243