Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

Exclusive offer: get 50% off this eBook here
3D Game Development with Microsoft Silverlight 3: Beginner's Guide

3D Game Development with Microsoft Silverlight 3: Beginner's Guide — Save 50%

A practical guide to creating real-time responsive online 3D games in Silverlight 3 using C#, XBAP WPF, XAML, Balder, and Farseer Physics Engine

$29.99    $15.00
by Gastón C. Hillar | October 2009 | Beginner's Guides Web Development Web Graphics & Video

Read Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 1

Time for action – animating projections

Your project manager wants you to animate the perspective transform applied to the video while it is being reproduced.

We are going to add a StoryBoard in XAML code to animate the PlaneProjection instance:

  1. Stay in the project, 3DInvadersSilverlight.
  2. Open MainPage.xaml and replace the PlaneProjection definition with the following line (we have to add a name to refer to it):
    <PlaneProjection x:Name ="proIntroduction" RotationX="-40"
    RotationY="15" RotationZ="-6" LocalOffsetX="-70"
    LocalOffsetY="-105" />
  3. Add the following lines of code before the end of the definition of the cnvVideo Canvas:
    <Canvas.Resources>
        <Storyboard x:Name="introductionSB">
            <DoubleAnimation Storyboard.TargetName="proIntroduction"
                    Storyboard.TargetProperty="RotationX"
                    From="-40" To="0" Duration="0:0:5"
                    AutoReverse="False" RepeatBehavior="1x" />
        </Storyboard>
    </Canvas.Resources>
  4. Now, add the following line of code before the end of the PlayIntroductoryVideo method (to start the animation):
    introductionSB.Begin();
  5. Build and run the solution. Click on the butt on and the video will start its reproduction after the transition effect. While the video is being played, the projection will be animated, as shown in the following diagram:

    Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

What just happened?

Now, the projection that shows the video is animated while the video is being reproduced.

Working with a StoryBoard in XAML to animate a projection

First, we added a name to the existing PlaneProjection (proIntroduction). Then, we were able to create a new StoryBoard with a DoubleAnimation instance as a child, with the StoryBoard's TargetName set to proIntroduction and its TargetProperty set to RotationX. Thus, the DoubleAnimation controls proIntroduction's RotationX value. The RotationX value will go from -40 to 0 in five seconds—the same time as the video's duration:

From="-40" To="0" Duration="0:0:5"

The animation will run once (1x) and it won't reverse its behavior:

AutoReverse="False" RepeatBehavior="1x"

We added the StoryBoard inside . Thus, we were able to start it by calling its Begin method, in the PlayIntroductionVideo procedure:

introductionSB.Begin();

We can define StoryBoard instances and different Animation (System. Windows.Media.Animation) subclasses instances as DoubleAnimation, using XAML code. This way, we can create amazing animations for many properties of many other UIElements defined in XAML code.

 

Time for action – solving navigation problems

When the game starts, there is an undesired side effect. The projected video appears in the right background, as shown in the following screenshot:

Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

This usually happens when working with projections. Now, we are going to solve this small problem:

  1. Stay in the 3DInvadersSilverlight project.
  2. Open MainPage.xaml.cs and add the following line before the first one in the medIntroduction_MediaEnded method:
    cnvVideo.Visibility = Visibility.Collapsed;
  3. Build and run the solution. Click on the button and after the video reproduction and animation, the game will start without the undesired background, as shown in the following screenshot:

    Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

What just happened?

Now, once the video finishes its reproduction and associated animation, we have hidden the Canvas that contains it. Hence, there are no parts of the previous animation visible when the game starts.

Time for action – reproducing music

Great games have appealing background music. Now, we are going to search and add background music to our game:

As with other digital content, sound and music have a copyright owner and a license. Hence, we must be very careful when downloading sound and music for our games. We must read licenses before deploying our games with these digital contents embedded.

  1. One of the 3D digital artists found a very cool electro music sample for reproduction as background music. You have to pay to use it. However, you can download a free demo (Distorted velocity. 1) from http://www.musicmediatracks.com/music/Style/Electro/. Save the downloaded MP3 file (distorted_velocity._1.mp3) in the previously created media folder (C:Silverlight3DInvaders3DMedia).

    You can use any other MP3 sound for this exercise. The aforementioned MP3 demo is not included in the accompanying source code.

  2. Stay in the 3DInvadersSilverlight project.
  3. Right-click on the Media sub-folder in the 3DInvadersSilverlight.Web project and select Add | Existing item… from the context menu that appears.
  4. Go to the folder in which you copied the downloaded MP3 file (C:Silverlight3DInvaders3DMedia). Select the MP3 file and click on Add. This way, the audio file will be part of the web project, in the Media folder, as shown in the following screenshot:

    Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

  5. Now, add the following lines of code at the beginning of the btnStartGame button's Click event. This code will enable the new background music to start playing:
    // Background music
    MediaElement backgroundMusic = new MediaElement();
    LayoutRoot.Children.Add(backgroundMusic);
    backgroundMusic.Volume = 0.8;
    backgroundMusic.Source =
    new Uri("Media/distorted_velocity._1.mp3", UriKind.Relative);
    backgroundMusic.Play();
  6. Build and run the solution. Click on the button and turn on your speakers. You will hear the background music while the transition effect starts.
3D Game Development with Microsoft Silverlight 3: Beginner's Guide A practical guide to creating real-time responsive online 3D games in Silverlight 3 using C#, XBAP WPF, XAML, Balder, and Farseer Physics Engine
Published: September 2009
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

What just happened?

You discovered that the speakers worked! Now, the game has attractive background music. Leave the speakers on, because your project manager wants more sound eff ects in the game.

We created a new MediaElement instance (backgroundMusic). However, this time, we used C# to create it, instead of working on XAML code. We had to add the new MediaElement to a parent container:

LayoutRoot.Children.Add(backgroundMusic);

Then, we defined the desired Volume level and the Source as a new relative Uri (Uniform Resource Identifier):

backgroundMusic.Volume = 0.8;
backgroundMusic.Source = new Uri("Media/distorted_velocity._1.mp3",UriKind.Relative);

The Volume ranges from 0 to 1. It uses a linear scale. We used 0.8 because we want the future sound effects to be louder than the background music.

The first parameter for the new Uri is the relative path (ClientBin is our base path in the web project). The second one is the UriKind. In this case, we are working with a Relative Uri.

Once we set up all the necessary parameters, we called the Play method and Silverlight started playing the MP3 file:

backgroundMusic.Play();

The code goes on running while the music file is being played. Hence, the game starts and we can still hear the music.

Time for action – preparing audio files to use them in Silverlight

As with video files, Silverlight 3 does not support all audio formats. Now, we are going to use Expression Encoder to convert audio files video from WAV (WAVeform audio format) format to a WMA (Windows Media Audio) format with an adaptive streaming audio encoding profile, compatible with Silverlight 3:

  1. Your project manager found two excellent WAV files to use as sound effects for the game on The Freesound Project website (http://www.freesound.org/):
    1. The first one is the Ufo atmosphere. This can be downloaded from http://www.freesound.org/samplesViewSingle.php?id=235—filename 235__Erratic__ufo_atmosphere.wav
    2. The second one is that of a thunder clap. This can be downloaded from http://www.freesound.org/samplesViewSingle.php?id=2525—filename 2525__RHumphries__rbh_thunder_03.wav

      The Freesound Project website offers high quality sounds with a Creative Commons License. The website offers thousands of samples. However, it does not offer songs.

  2. Save or copy the original audio files (235__Erratic__ufo_atmosphere.wav and 2525__RHumphries__rbh_thunder_03.wav) in a new folder (C:Silverlight3DInvaders3DMedia).
  3. Start Expression Encoder.
  4. Select File | New Job.
  5. Now, select File | Import…. Browse to the folder that holds the audio files (C:Silverlight3DInvaders3DMedia) and select the files to import, 235__Erratic__ufo_atmosphere.wav and 2525__RHumphries__rbh_thunder_03.wav. Then, click on Open. Expression Encoder will analyze the files for a few seconds, and then it will display a Ready Status for both items.
  6. Expand Profile and select WMA High Quality Audio from the Audio combo box. This step defines the desired audio profile for the encoding process. The expanded Audio options will display the output audio's codec, mode, bitrate, sample rate, bits per sample, and channels, among other parameter values, as shown in the following screenshot:

    Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

  7. Click on the Output tab, expand Job output and click on the Browse for output folder button (…) on the right side of the Directory text box. Browse to the folder that holds the original audio files (C:Silverlight3DInvaders3DMedia) and click on OK.
  8. Select File | Encode or click on the Encode button. Expression Blend will begin the encoding job and will display the overall progress as shown in the following screenshot:

    Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

  9. After a few seconds (depending on the audio files length and format), Expression Blend will show Ready in the Status columns.
  10. Right-click on one of the items (235__Erratic__ufo_atmosphere.wma) under Media Content and select Open File Location in the context menu that appears. A new Explorer window will appear showing the folder with a new sub-folder with the default user name as a prefix, the date and the time. Enter in this sub-folder and move the audio files (235__Erratic__ufo_atmosphere.wma and 2525__RHumphries__rbh_thunder_03.wma) to the previously mentioned parent folder.
  11. Double-click on the new audio files and listen to them using your default media player (Windows Media Player or VLC Media Player, among others). Check whether audio quality, channels and sampling are as good as expected, as shown in the following screenshot:

    Adding Sound, Music, and Video in 3D Game Development with Microsoft Silverlight 3: Part 2

What just happened?

You used Expression Blend to encode the original WAV audio files into WMA with adaptive streaming audio encoding profiles. Now, the audio files are compatible with Silverlight 3.

In this case, we created audio files that were very high quality because we want to test the game locally. However, we will have to choose a different encoding profile according to the Internet bandwidth offered by the hosting service and the average download speed available for the game's potential players.

Audio formats supported in Silverlight 3

Silverlight 3 supports the audio encodings shown in the following table:

Encoding name

Description and restrictions

LPCM

Linear 8 or 16-bits Pulse Code Modulation.

WMA Standard

Windows Media Audio 7, 8, and 9 Standard

WMA Professional

Windows Media Audio 9 and 10 Professional; Multichannel (5.1 and 7.1 surround) is automatically mixed down to stereo; it supports neither 24 bit audio nor sampling rates beyond 48 kHz

MP3

ISO MPEG-1 Layer III

AAC

ISO Advanced Audio Coding; AAC-LC (Low Complexity) is supported at full fidelity (up to 48 kHz); HE-AAC (High Efficiency) will decode only at half fidelity (up to 24 kHz); Multichannel (5.1) audio content is not supported

If we want to use an audio file with an encoding that does not appear in the previously shown table, we will have to convert it to one of the supported formats.

Using free applications to convert audio formats

Expression Encoder is not the only application capable of converting audio files to the encoding profiles supported by Silverlight 3. We can also use many free or open source applications and several online services to convert audio files to any of the previously shown formats.

The same applications mentioned for converting video formats are capable of converting audio files to the encoding profiles supported by Silverlight 3.

Time for action – creating a class to handle audio concurrency

Now, your project manager wants you to add different sound effects associated with different game events. Sometimes, these sounds have to be played concurrently. For example, a thunder can happen at the same time as the player applies an impulse to an UFO.

It is time to create a simple yet useful sound manager class. It must be able to handle many concurrent sound banks:

  1. Stay in the 3DInvadersSilverlight project.
  2. Create a new class—SoundManager.
  3. Add the following lines of code at the beginning of the class definition (as we are going to use the System.Collections.Generic.List class):
    using System.Collections.Generic;
  4. Add the following private and static variables:
    // The target for the new MediaElement instances (it must be a
    Panel subclass)
    private static Panel _target;
    // The last sound bank used
    private int _lastSoundBank = -1;
    // The number of sound banks available
    private static int SoundBanks = 5;
    // The default media folder
    public static String MediaFolder = "Media/";
  5. Add the following private list of media elements that will hold many MediaElement instances:
    // The list of media elements
    private List<MediaElement> _soundBanks;
  6. Add the following property to control the Volume (it must be improved later with additional code):
    public double Volume { get; set; }
  7. Add the following constructor with a parameter:
    public SoundManager(Panel target)
    {
    _target = target;
    _soundBanks = new List<MediaElement>(SoundBanks);
    for (int i = 0; i < SoundBanks; i++)
    {
    _soundBanks.Add(new MediaElement());
    _target.Children.Add(_soundBanks[i]);
    }
    }
  8. Add the following public method to play a sound taking advantage of the banks using a round robin algorithm:
    public void Play(Uri uri)
    {
    _lastSoundBank++;
    if (_lastSoundBank >= SoundBanks)
    {
    // A simple round robin algorithm
    _lastSoundBank = 0;
    }
    _soundBanks[_lastSoundBank].Stop();
    _soundBanks[_lastSoundBank].Source = uri;
    _soundBanks[_lastSoundBank].Volume = Volume;
    _soundBanks[_lastSoundBank].Play();
    }
  9. Add the previously encoded audio files (235__Erratic__ufo_atmosphere.wma and 2525__RHumphries__rbh_thunder_03.wma) to the Media folder in the web project.
  10. Add the following two public methods to reproduce the previously added audio files without the need to call the generic Play method specifying a Uri:
    public void PlayAtmosphere()
    {
    Play(new Uri(MediaFolder + "235__Erratic__ufo_atmosphere.wma",
    UriKind.Relative));
    }
    public void PlayThunder()
    {
    Play(new Uri(MediaFolder +"2525__RHumphries__rbh_thunder_03.wma",
    UriKind.Relative));
    }

What just happened?

The code to manage multiple concurrent audio playback is now held in the new SoundManager class. It uses some static private variables because there will be just one sound manager for the game. Thus, we will need just one instance of this class.

The class is quite easy to understand. The constructor receives a Panel as a parameter. It will use it as a container for the multiple MediaElement instances that it is going to create.

The _soundBanks list holds the number of MediaElement instances defined in the static variable SoundBanks (5).

3D Game Development with Microsoft Silverlight 3: Beginner's Guide A practical guide to creating real-time responsive online 3D games in Silverlight 3 using C#, XBAP WPF, XAML, Balder, and Farseer Physics Engine
Published: September 2009
eBook Price: $29.99
Book Price: $49.99
See more
Select your format and quantity:

Using a round robin algorithm to work with concurrent sounds

The Play method is responsible of playing the audio file, which Uri receives as a parameter. It uses a simple round robin algorithm to assign the available MediaElement instances (sound banks) for each new audio file that has to be played.

Initially, there are 5 sound banks available.

If we call the Play method 7 times, the following sequence will take place:

  1. Play audio file #1 with MediaElement instance #0 (_soundBanks[0]).
  2. Play audio file #2 with MediaElement instance #1 (_soundBanks[1]).
  3. Play audio file #3 with MediaElement instance #2 (_soundBanks[2]).
  4. Play audio file #4 with MediaElement instance #3 (_soundBanks[3]).
  5. Play audio file #5 with MediaElement instance #4 (_soundBanks[4]).
  6. Play audio file #6 with MediaElement instance #0 (_soundBanks[0]). The round starts again here.
  7. Play audio file #7 with MediaElement instance #1 (_soundBanks[1]).

Each time the Play method is called, the value in the _lastSoundBank increases by 1:

_lastSoundBank++;

If the value is equal or greater than the maximum number of sound banks, it is time to start using the first sound bank available again (a new round):

if (_lastSoundBank >= SoundBanks)
{
_lastSoundBank = 0;
}

Then, it is time to play the new audio file using the assigned MediaElement instance (sound bank).

This way, we can play many audio files concurrently. We do not have to worry about MediaElement instances in the game because we can use the SoundManager instance features.

Time for action – generating sounds associated to game events

Now, it is time to add concurrent sound effects associated to game events.

  1. Stay in the 3DInvadersSilverlight project.
  2. Open InvadersGame.cs.
  3. Add the following private variable to hold the SoundManager instance:
    private SoundManager _soundManager;
  4. Add the following private method to create and initialize the sound manger related to the game:
    private void InitializeSoundManager()
    {
    _soundManager = new SoundManager(_mainPage.LayoutRoot);
    _soundManager.Volume = 1;
    }
  5. Add the following lines of code after the line base.Initialize(); in the Initialize method:
    InitializeSoundManager();
  6. Now, add the following lines of code before the end of the UpdateWithTime method (a random thunder):
    if (_random.Next(20) == 2)
    _soundManager.PlayThunder();
  7. Replace the code that checks the Key.I key in the CheckKeyboard method with these lines:
    if (KeyboardManager.IsKeyDown(Key.I))
    {
    _ufo1.Body.ApplyImpulse(_levelImpulse);
    // Play a sound when the user applies an impulse to the UFO
    _soundManager.PlayAtmosphere();
    }
  8. Build and run the solution. Click on the button and turn on your speakers again. You will hear the background music. Then, the game will start. If you wait for a few seconds, you will hear the sound of many thunder claps. Sometimes, before a thunder clap finishes, you will hear many others. The music will go on playing in the background.
  9. Now, press the I key and you will hear a strange sound like the atmosphere of a UFO. Another thunder clap will scare you. Press the I key again and you will enjoy concurrent sound effects.

 

What just happened?

You are promoted from the position of a game developer to that of a senior game developer!

The game has background music and amazing concurrent sound effects thanks to the simple use of a SoundManager class.

We created and initialized a SoundManager instance (_soundManager). Then, we used its methods to play a random thunder sound and a UFO atmosphere effect when the player presses the I key.

Using a sound manager it is very easy to fire sounds when certain game events occur.

Have a go hero – animating the game over scene

Now that you have shown your project manager videos with animated projections, he wants you to change the Game Over screen.

You have to use a VideoBrush to paint the GAME OVER text with an animated video. You do not know how to do it. However, you know about brushes, videos, animations, and timeline management. You can do it with some additional research!

Have a go hero – configuring sounds and music

Most games allow the players to configure the desired volume levels for the different sound effects and the background music.

Your project manager wants you to add a new gauge with a button to the game. When the player clicks on this button, the game has to pause and a Canvas with a control panel using diff erent sliders must allow the user to control the volumes for sounds and music.

You will have to make some changes to the SoundManager class to allow the user to change some properties that define the volume for sounds organized by categories. Also, you have to change the way you play the background music in the game.

Summary

We learnt a lot in this article about adding and controlling sound, music, and videos. Specifically, we were able to use Expression Encoder to convert many different audio and video formats to the encoding profiles supported by Silverlight. We added animated plane projections to videos. We created a simple sound manager class capable of reproducing concurrent sound effects. Also, we learnt how to take advantage of hardware acceleration when scaling or stretching videos.

If you have read this article you may be interested to view :

 

About the Author :


Gastón C. Hillar

Gastón C. Hillar has been working with computers since he was eight. He began programming with the legendary Texas TI-99/4A and Commodore 64 home computers in the early 80s.
He has a Bachelor degree in Computer Science from which he graduated with honors, and an MBA from which he graduated with an outstanding thesis. Now, he is an independent IT consultant and a freelance author always looking for new adventures around the world.

To date he’s written more than 40 books in Spanish, and for Packt Publishing has written “C# 2008 and 2005 Threaded Programming: Beginner's Guide”. He usually writes articles for Spanish magazines Mundo Linux, Solo Programadores and Resistor.
He contributes to Dr. Dobb's Go Parallel programming portal http://www.ddj.com/go-parallel/ and he is a guest blogger at Intel Software Network http://software.intel.com

Gastón C. Hillar is the author of "Microsoft Silverlight 4 and SharePoint 2010 Integration".

Books From Packt

Blender 3D 2.49 Incredible Machines
Blender 3D 2.49 Incredible Machines

jQuery 1.3 with PHP
jQuery 1.3 with PHP

Symfony 1.3 Web Application Development
Symfony 1.3 Web Application Development

Zend Framework 1.8 Web Application Development
Zend Framework 1.8 Web Application Development

JBoss Tools 3 Developers Guide
JBoss Tools 3 Developers Guide

Seam 2.x Web Development
Seam 2.x Web Development

WordPress Plugin Development: Beginner's Guide
WordPress Plugin Development: Beginner's Guide

Scratch 1.4: Beginner’s Guide
Scratch 1.4: Beginner’s Guide

No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
s
H
n
r
n
c
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software