Windows Phone Embedding Audio in your Game

Controlling an audio file

Music has the ability to impact the emotions of human beings. Different styles of music produce different feelings. Fast tempo music makes people feel nervous or excited; when the tempo becomes slow, people feel relaxed and safe. In modern video games, music often plays an important role in creating the atmosphere. Game designers and composers work together to tailor the music to the plot. When a player goes into a beautiful scene, a euphonious and harmonious song will accompany it; when immersed in a dangerous situation, the music will sound oppressive. In this recipe, you will learn how to use the media technology to control music in your Windows Phone 7 game.

Getting ready

In Windows Phone 7 XNA, a song or music is encapsulated as a Song class. This class provides the metadata of a song and includes the song’s name, artist, album, and duration. The Name and Duration are the most direct properties for your song. We will use them in our example. As a class design consideration, the Song class does not have a Play() method to play a song. You should use the MediaPlayer class, which provides methods and properties for playing songs. To control song playback, we can use the following methods:

  • Play(): The Play() method kicks off the song.
  • Stop(): The Stop() method stops the song playing and sets the playing position to the song’s beginning.
  • Pause(): The Pause() method also stops the song playing, the difference between the Pause() and the Stop() method is that the Pause() method will not reset the playing position to the start. Instead, it keeps the playing position at the place where the song is paused.
  • Resume(): The Resume() method replays the song from the paused position.

Besides these essential methods, if you have more than one song in your playing queue, the MoveNext() and MovePrevious() methods will help you to do circular playing. The two methods move to the next or previous song in the queue. They operate as if playing the queue was circular. That is, when the last song is playing the MoveNext() method moves to the first song and when the first song is playing the MovePrevious() method moves to the last song. If the IsShuffled property is set, the MoveNext() and MovePrevious() methods will randomly choose a song in the playing queue to play. To use these methods, there is no need to instantiate the MediaPlayer class, which is actually a static class. You can directly call the method using the following pattern:

MediaPlayer.MethodName()

In this example, we will play, pause, resume, and stop a song using the MediaPlayer and Song classes. Besides this, the song’s name, playing state, and position will be displayed on the Windows Phone 7 screen.

How to do it…

The following steps show you how to load, play, pause, and resume a song in the Windows Phone7 XNA application:

  1. Create a Windows Phone Game named PlayMusic, and change Game1.cs to PlayMusicGame.cs. Add the audio file music.wma and the sprite font file gameFont.spritefont to the content project.
  2. Declare the indispensable variable. Add the following lines to the field of the PlayMusicGame class:
    // SpriteFont object for showing song information
    SpriteFont font;
    // Text presents the song playing position
    string textPlayingPosition = "";
    // Song's name
    string textSongName;
    // Playing state
    MediaState PlayingState;
    // Song object stores a song
    Song song;
    
  3. Load the game font and the audio file. Then get the song’s name and play it. Add the following code to the LoadContent() method:
    // Load the game font
    font = Content.Load<SpriteFont>("gameFont");
    // Load the song
    song = Content.Load<Song>("music");
    // Get the song's name
    textSongName = song.Name;
    // Play the song
    MediaPlayer.Play(song);
    
  4. Use the MediaPlayer class to play, pause, resume, and stop the song. Meanwhile, update the playing state and position. Insert the following code to the Update() method:
    // Get the tapped position
    TouchCollection touches = TouchPanel.GetState();
    if (touches.Count > 0 && touches[0].State ==
    TouchLocationState.Pressed)
    {
    Point point = new Point((int)touches[0].Position.X,
    (int)touches[0].Position.Y);
    // If the tap gesture is valid
    if (GraphicsDevice.Viewport.Bounds.Contains(point))
    {
    // If the the media player is playing, pause the
    // playing song
    if (MediaPlayer.State == MediaState.Playing)
    {
    MediaPlayer.Pause();
    PlayingState = MediaState.Paused;
    }
    else if (MediaPlayer.State == MediaState.Paused)
    {
    // If the song is paused and not stopped, resume
    //it
    MediaPlayer.Resume();
    PlayingState = MediaState.Playing;
    }
    else if (MediaPlayer.State == MediaState.Stopped)
    {
    // If the song is stopped, replay it
    MediaPlayer.Play(song);
    PlayingState = MediaState.Playing;
    }
    }
    }
    if (MediaPlayer.State == MediaState.Playing)
    {
    // If the song's playing position meets the end, stop
    // playing
    if (MediaPlayer.PlayPosition == song.Duration)
    {
    MediaPlayer.Stop();
    PlayingState = MediaState.Stopped;
    }
    // Show the song's playing position and the total duration
    textPlayingPosition = MediaPlayer.PlayPosition.ToString()
    + " / " + song.Duration.ToString();
    }
    
  5. Draw the song’s name, playing state, and playing position on the Windows Phone 7 screen. Add the following code to the Draw() method:
    spriteBatch.Begin();
    // Draw the instruction text
    spriteBatch.DrawString(font, "Tap Screen to Play, Pause and "
    +"Resume the Song", new Vector2(0, 0), Color.White);
    // Draw the song's name
    spriteBatch.DrawString(font, "Song's Name: " + textSongName,
    new Vector2(0,200 ), Color.White);
    // Draw the song's playing state
    spriteBatch.DrawString(font, "State: " +
    PlayingState.ToString(),
    new Vector2(0, 240), Color.White);
    spriteBatch.DrawString(font, textPlayingPosition,
    new Vector2(0, 280), Color.White);
    spriteBatch.End();
    
  6. Now, build and run the application; it should run as shown in the following screenshot:

Controlling an audio file

How it works…

In step 2, font will be used to show the instructions, song’s name, playing state, and position; the texPlayingPosition stores the song’s current playing position; textSongName saves the song’s name; PlayingState shows the song’s playing state: Playing, Paused, or Stopped; the song is the object of the Song class and will be used to process and load an audio file.

In step 4, the first part of the Update() method is to check whether the player taps on the Windows Phone 7 screen; if he/she does, it has three MediaState options for controlling the song. When the song is Playing, the tap gesture will pause it; if the song is Paused, the gesture will replay it from the paused position using the MediaPlayer.Resume() method; once the song’s current MediaState is Stopped, we will replay the song from the beginning when a valid tap gesture takes place. The second part is about updating the song’s current playing position with its total duration using the two properties of the Song class: PlayPosition and Duration. Besides these, when the current playing position equals the song’s duration, it means the song has ended. In this example, we will replay the song once. You can change it in another way by moving to the next song.

Adding sound effects to your game

“The sound effects are artificially created or enhanced sounds or sound processes used to emphasize artistic or other content of films, television shows, live performance, animation, video game, music, or other media.” – Wiki.

When you are playing games such as Counter Strike or Quake, the sound you hear while firing is the sound effect. Every weapon has its corresponding sound effect. In the early times, the sound effect came from the sound synthesis, a kind of midi rhythm. Today, the game studio can sample the sound from real instances. In making a racing game, the engine sound of every car is different. The game studio can record the sound from a real car, maybe a Lamborghini or a Panamera Turbo, to make the game more realistic. The Windows Phone 7 XNA framework simplifies the work needed to control sound effects. It is up to you to use the sound effects in your game. In this recipe, you will learn how to make your game more interesting by applying sound effects.

Getting ready

In XNA, a SoundEffect contains the audio data and metadata (such as wave data and loop information) loaded from a sound file. You can create multiple SoundEffectInstance objects, and play them from a single SoundEffect. These objects share the resources of that SoundEffect. The only limit to the number of loaded SoundEffect instances is memory. A loaded SoundEffect will continue to hold its memory resources throughout its lifetime. When a SoundEffect instance is destroyed, all SoundEffectInstance objects previously created by that SoundEffect will stop playing and become invalid. Unlike the Song class, SoundEffect has a Play() method; usually, the sound effect is fast and short, plays once and then stops. If you do not want to loop a sound, the Play() method is enough. Otherwise, you should create an instance of the sound effect using the SoundEffect. CreateInstance() method. As the basic metadata, the SoundEffect class also has Name and Duration properties, and it is easy to get the name of any sound effect and its duration. The DistanceScale and DopplerScale properties will help you to simulate a realistic 3D sound effect, especially when you use the SoundEffectInstance.Apply3D() method.

For DistanceScale, if sounds are attenuating too fast, which means that the sounds get quiet too quickly as they move away from the listener, you need to increase the DistanceScale. If sounds are not attenuating fast enough, decrease the DistanceScale. This property will also affect Doppler sound.

The DopplerScale changes the relative velocities of emitters and listeners. If sounds are shifting (pitch) too much for the given relative velocity of the emitter and listener, decrease the DopplerScale. If sounds are not shifting enough for the given relative velocity of the emitter and listener, increase the DopplerScale.

In this example, we will use the SoundEffect class to play two different weapons’ sounds.

How to do it…

The following steps present a complete guide for controlling a sound effect in a Windows Phone 7 XNA game using a .wav file:

  1. Create a Windows Phone Game named PlaySoundEffect, and change the Game1. cs to PlaySoundEffectGame.cs. Add the audio file Laser.wav, MachineGun. wav and the sprite font file gameFont.spritefont to the project content.
  2. Add the following code as the required variables to the field of PlaySoundEffectGame class:
    // Sprite font for showing the name of current sound effect
    SpriteFont font;
    // Current weapon's name
    string CurrentWeapon;
    // Sound effect variables
    SoundEffect SoundEffectLaser;
    SoundEffect soundEffectMachineGun;
    // Current Sound effect
    SoundEffect soundEffectPlaying;
    
  3. Enable the Hold gesture for Windows Phone 7 TouchPanel. Add the following line to the Initialize() method:
    // Enable the hold gesture
    TouchPanel.EnabledGestures = GestureType.Hold;
    
  4. Load the game font, sound effects of weapons, and set the current sound effect of a weapon for playing. Paste the following code into the LoadContent() method:
    // Load the font
    font = Content.Load<SpriteFont>("gameFont");
    // Load the sound effect of laser gun
    SoundEffectLaser = Content.Load<SoundEffect>("Laser");
    // Load the sound effect of machine gun
    soundEffectMachineGun = Content.Load<SoundEffect>("MachineG
    un");
    // Set the sound effect of laser to the current sound effect
    // for playing
    soundEffectPlaying = SoundEffectLaser;
    // Set the name of current sound effect
    CurrentWeapon = "Laser";
    
  5. Play the sound effect and use the Hold gesture to switch the sound effects between different weapons. Add the following code to the Update() method:
    // Play the current sound effect when tap on the screen
    TouchCollection touches = TouchPanel.GetState();
    if (touches.Count > 0 && touches[0].State ==
    TouchLocationState.Pressed)
    {
    Point point = new Point((int)touches[0].Position.X,
    (int)touches[0].Position.Y);
    if (GraphicsDevice.Viewport.Bounds.Contains(point))
    {
    if (soundEffectPlaying != null)
    {
    soundEffectPlaying.Play();
    }
    }
    }
    // Using Hold gesture to change the sound effect of weapons
    while(TouchPanel.IsGestureAvailable)
    {
    // Read the gesture
    GestureSample gestures = TouchPanel.ReadGesture();
    if (gestures.GestureType == GestureType.Hold)
    {
    // If the Hold gesture is taking place, change the
    // sound effect.
    if (soundEffectPlaying.Equals(soundEffectLaser))
    {
    soundEffectPlaying = soundEffectMachineGun;
    CurrentWeapon = "Machine Gun";
    }
    else if (soundEffectPlaying.Equals
    (soundEffectMachineGun))
    {
    soundEffectPlaying = soundEffectLaser;
    CurrentWeapon = "Laser";
    }
    }
    }
    
  6. Draw the instructions and the name of the current sound effect. Insert the following code to the Draw() method.
    spriteBatch.Begin();
    // Draw the instructions
    spriteBatch.DrawString(font, "Tap and hold on for changing
    your" + "weapon.\nTap for firing", new Vector2(0,0), Color.
    White);
    // Draw the current weapon's name
    spriteBatch.DrawString(font, "Current Weapon: " +
    CurrentWeapon, new Vector2(0, 70), Color.White);
    spriteBatch.End();
    
  7. Build and run the application. It should run as shown in the screenshot to the left. When you tap the screen and hold it for a few seconds, the sound effect will be something similar to the screenshot on the right:
    Adding sound effects to your game

How it works…

In step 2, the font will be used to draw the name of the current sound effect and the controlling instructions; the CurrentWeapon indicates the name of the current weapon; soundEffectLaser and soundEffectMachineGun, the SoundEffect instances, individually represent the laser and machine gun sounds; soundEffectPlaying is the currently playing sound effect.

In step 3, we use the Hold gesture to switch the playing sound effect. It is required to enable the gesture type in TouchPanel.

In step 5, the first part is to check whether the user taps on the Windows Phone 7 screen. If so, then play the current sound effect if it is not null. The second part is to switch the sound effect for playing using the Hold gesture. If the on-going gesture is Hold, we will alternate the sound effects between the laser and the machine gun for playing.

Adding stereo sounds to your game

Sometimes, the music and simple sound effects are not enough for you, if you are pursuing the realistic feeling. You cannot determine the place where the sound comes from in your game world. If you have experience of playing Counter-Strike, it is easy to know how many enemies are near you when you stop moving, by listening to the sound. This technique is called Stereo Sound. It uses two or more independent audio channels through a symmetrical configuration of loudspeakers to create the impression of the sound heard from different directions, similar to natural hearing. For the stereo sound, Windows Phone 7 XNA simulates a sound emitter and listener, so that when the position of the emitter is changing, the listener will get a processed sound effect according to the distance between them. In this recipe, you will learn how to use the XNA framework to implement a stereo sound.

Getting ready

In this example, we will use the SoundEffectInstance class with its methods to simulate a 3D sound effect. SoundEffectInstance provides the single playing, paused, and stopped methods to control an instance of sound effect. You can create a SoundEffectInstance by calling the SoundEffect.CreateInstance() method. Initially, the SoundEffectInstance is created as stopped, but you can play it by calling the SoundEffectInstance.Play() method. The volume, panning, and pitch of SoundEffectInstance can be modified by setting the Volume, Pitch, and Pan properties. On Windows Phone 7, a game can have a maximum of 16 total playing SoundEffectInstance instances at one time, combined across all loaded SoundEffect objects. Attempts to play a SoundEffectInstance beyond this limit will fail.

The SoundEffectInstance.Apply3D() method simulates the 3D sound effect. It receives two parameters, the object of AudioEmitter and AudioListener classes. This method will calculate the 3D audio values between an AudioEmitter and an AudioListener object, and will apply the resulting values to the SoundEffectInstance instance. If you want to apply the 3D effect to a SoundEffectInstance, you must call the method before you call the SoundEffectInstance.Play()method. Calling this method automatically sets the Windows Phone 7 speaker mix for any sound played by this SoundEffectInstance to a value calculated by the difference in Position property values between the listener and the emitter. In preparation for the mix, the sound is converted to mono. Any stereo information in this sound is discarded.

How to do it…

The following steps give you a complete guide to implementing a stereo sound effect:

  1. Create a Windows Phone Game named PlayStereoSound and change the Game1. cs to PlayStereoSoundGame.cs. Add the audio file drums.wma and the model file BallLowPoly.fbx to the project content.
  2. Declare the essential variables to the field of the PlayStereoSoundGame class. Add the following code to the class:
    // Sound effect object loads the sound effect file
    SoundEffect soundEffect;
    // Instance of a SoundEffect sound.
    SoundEffectInstance soundEffectInstance;
    // AudioEmitter and AudioListener simulate 3D audio effects
    AudioEmitter emitter;
    AudioListener listener;
    // The world position represents the 3D position for
    AudioEmitter
    Vector3 objectPos;
    // A ball for visually presenting the varying AudioEmitter
    // world position.
    Model modelBall;
    Matrix worldBall = Matrix.Identity;
    // Camera
    Vector3 cameraPosition;
    Matrix view;
    Matrix projection;
    
  3. Initialize the camera, the audio emitter, and the audio listener. Add the following code to the Initialize() method:
    // Initialize the camera
    cameraPosition = new Vector3(0, 30, 50);
    view = Matrix.CreateLookAt(cameraPosition, Vector3.Zero,
    Vector3.Up);
    projection = Matrix.CreatePerspectiveFieldOfView(
    MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio,
    1.0f, 1000.0f);
    // Initialize the AudioEmitter and AudioListener
    emitter = new AudioEmitter();
    listener = new AudioListener();
    
  4. Load the ball model and the drum sound effect. Then, create the instance of the drum sound effect and apply the audio emitter to the audio listener of the instance. Finally, play the sound effect. Add the following code to the LoadContent() method:
    // Load the ball model
    modelBall = Content.Load<Model>("BallLowPoly");
    // Load the sound effect
    soundEffect = Content.Load<SoundEffect>("drums");
    // Create an instance of the sound effect
    soundEffectInstance = soundEffect.CreateInstance();
    // Apply 3D position to the sound effect instance
    soundEffectInstance.Apply3D(listener, emitter);
    soundEffectInstance.IsLooped = true;
    // Play the sound
    soundEffectInstance.Play();
    
  5. Rotate the audio emitter around the Y axis. Add the following lines to the Update() method:
    // Rotate around axis Y
    objectPos = new Vector3(
    (float)Math.Cos(gameTime.TotalGameTime.TotalSeconds) / 2,
    0,
    (float)Math.Sin(gameTime.TotalGameTime.TotalSeconds) /
    2);
    // Update the position of the audio emitter
    emitter.Position = objectPos;
    // Apply the new position of the audio emitter to the audio
    listener
    soundEffectInstance.Apply3D(listener, emitter);
    
  6. Define the DrawModel() method. Add the following code to the PlayStereoSoundGame class:
    // Draw the 3D model
    public void DrawModel(Model model, Matrix world, Matrix view,
    Matrix projection)
    {
    Matrix[] transforms = new Matrix[model.Bones.Count];
    model.CopyAbsoluteBoneTransformsTo(transforms);
    foreach (ModelMesh mesh in model.Meshes)
    {
    foreach (BasicEffect effect in mesh.Effects)
    {
    effect.EnableDefaultLighting();
    effect.World = transforms[mesh.ParentBone.Index] *
    world;
    effect.View = view;
    effect.Projection = projection;
    }
    mesh.Draw();
    }
    }
    
  7. Draw the ball model and rotate it around the Y axis to coincide with the position of the audio emitter. Add the following code to the Draw() method:
    // Draw the rotating ball
    DrawModel(modelBall, worldBall *
    Matrix.CreateTranslation(objectPos * 30), view,
    projection);
    
  8. Build and run the application, and it should run similar to the following screenshots:
    Adding stereo sounds to your game

How it works…

In step 2, the soundEffect will be used to load the sound effect file; the soundEffectInstance plays and applies the 3D sound effect; emitter and listener will combine with each other to simulate the 3D audio effects; objectPos represents the position changes around the Y axis, the latest value will be used to update the position value of the AudioEmitter object; modelBall loads the ball model; worldBall stores the world position of a ball model in 3D; the next three variables cameraPosition, view, and project depict the camera.

In step 4, after loading the ball model sound effect, we create a SoundEffectInstance object using the soundEffect.CreateInstance() method. Note that it is required to call the SoundEffectInstance.Apply3D() method with AudioListener and AudioEmitter objects before the Play() method. If you do not do so, the next time you call the Apply3D() method, it will throw an exception.

In step 5, we compute the objectPos for rotating around the Y axis. The X value comes from the Math.Cos() method; the Z value comes from the Math.Sin(). These two factors are equal to the value of a round in the XZ plain. After that, we use the newly created objectPos to update the position of the emitter and then call the SoundEffectInstance. Apply3D() method to re-calculate the playing 3D sound effect in the surroundings. In step 7, for the world parameter of the DrawModel() method, we use the latest objectPos to update the translation of the ball model in the 3D world. This will make the ball rotate around the Y axis along with the position of the sound effect emitter.

 

(XmasSale) PC USB Gaming Receiver for PC Windows 7 Xbox 360 Slim Wireless Controller Pad Game Accessory
For:Xbox 360; Accessory Type:Cable and Adapters; Interface:Wired; Connection:USB; Features:USB Hub; Color:Black; Material:Plastic; Dimensions (cm) :8.5 x 8.0 x 4.0; Weight (kg) :0.1; Package Contents:...
Merchant: LightInTheBox

$11.95

(XmasSale) Wired USB Game Pad Controller for Microsoft Xbox 360 Slim PC Windows
For:PC,Xbox 360; Accessory Type:Controllers; Interface:Wired; Connection:USB; Features:USB Hub; Color:White; Material:Plastic; Dimensions (cm) :17.0 x 13.0 x 4.0; Weight (kg) :0.258; Package Contents:...
Merchant: LightInTheBox

$19.99

Related Posts:

Both comments and pings are currently closed.

Comments are closed.

Powered by Blog.