Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Windows-Phone-7

Using the AudioManager Class to Play Sounds and Music in XNA, WPXNA (5)

0.00/5 (No votes)
30 May 2013CPOL2 min read 10.9K  
Using the AudioManager class to play sounds and music in XNA, WPXNA (5)

Introduction/Catalog

I have developed some games on Windows Phone. Here, I'll share my experiences and gradually upload some classes, no good name, I just call it WPXNA. (Some example code may not be stringent enough.)

  • Manage Audios
  • AudioManager

Manage Audios

In XNA, you can use the SoundEffectInstance, SoundEffect, or MediaPlayer class to play audios, SoundEffect and SoundEffectInstance are both available to play a short sound file, but there are also subtle differences, you can refer to The differences between SoundEffect and SoundEffectInstance in XNA. MediaPlayer can play MP3 and other files that take longer.

In order to manage the audio, I created the AudioManager class. First of all, we need to load the resources:

C#
private readonly Dictionary<string, SoundEffectInstance> sounds = 
        new Dictionary<string, SoundEffectInstance> ( );
private readonly Dictionary<string, Song> music = new Dictionary<string, Song> ( );
internal void LoadContent ( ResourceManager resourceManager )
{
 if ( null == resourceManager )
  return;
 foreach ( Resource resource in resourceManager.Resources )
  if ( resource.Type == ResourceType.Sound )
   this.sounds.Add ( resource.Name, resourceManager.GetSound ( resource.Name ) );
  else if ( resource.Type == ResourceType.Music )
   this.music.Add ( resource.Name, resourceManager.GetMusic ( resource.Name ) );
}

Because all of our resources are managed and loaded by the ResourceManager, so here the LoadContent method gets all the resources which type is Sound or Music, and put them into the field sounds and music.

We do not need to go to release the resources, because they are managed by the ResourceManager, so in the UnloadContent method of AudioManager, we just stop the audios.

C#
internal void UnloadContent ( )
{
 this.StopAllSound ( );
 this.StopMusic ( );
 this.sounds.Clear ( );
 this.music.Clear ( );
}
internal void StopAllSound ( )
{
 foreach ( SoundEffectInstance sound in this.sounds.Values )
  sound.Stop ( );
}
internal void StopMusic ( )
{
 if ( !MediaPlayer.GameHasControl || !this.isMusicPlaying )
  return;
 MediaPlayer.Stop ( );
 this.isMusicPlaying = false;
}

In the above code, the StopAllSound and StopMusic methods will stop playing the sounds and music. For StopMusic, we use the MediaPlayer class, so I need to use the property GameHasControl to judge the control power. In addition, you also need to add ID_CAP_MEDIALIB to file WMAppManifest.xml:

Using PlayMusic and PlaySound to play audios, which you can use the parameter isLoop to specify whether to loop the music. Every time you call PlayMusic will immediately start playing the music.

C#
internal void PlaySound ( string name )
{
 if ( !IsSoundOn || string.IsNullOrEmpty ( name ) || !this.sounds.ContainsKey ( name ) )
  return;
 if ( this.sounds[name].State != SoundState.Playing )
  this.sounds[name].Play ( );
}
internal void PlayMusic ( string name, bool isLoop )
{
 if ( !IsMusicOn || !MediaPlayer.GameHasControl || 
         string.IsNullOrEmpty ( name ) || !this.music.ContainsKey ( name ) )
  return;
 if ( MediaPlayer.State != MediaState.Stopped )
  MediaPlayer.Stop ( );
 try
 {
  MediaPlayer.Play ( this.music[name] );
  MediaPlayer.IsRepeating = isLoop;
  this.isMusicPlaying = true;
 }
 catch { }
}

Using the field IsSoundOn and IsMusicOn to control whether to play the sounds and music.

C#
internal static bool IsSoundOn = true;
internal static bool IsMusicOn = true;

AudioManager

Like the previous examples, we need to define a ResourceManager.

C#
private readonly ResourceManager resourceManager;
private readonly AudioManager audioManager;
private int step = 1;

In the constructor, we define the audio resources and create the AudioManager.

C#
public World ( Color backgroundColor )
 : base ( )
{
 // ...
 
 this.resourceManager = new ResourceManager ( new Resource[] {
  new Resource ( "click.s", ResourceType.Sound, @"sound\click" ),
  new Resource ( "music1", ResourceType.Music, @"sound\music1" )
 } );
 this.resourceManager.World = this;
 this.audioManager = new AudioManager ( );
}

After the page loaded, we use ResourceManager to load all the resources and give them to the AudioManager, so AudioManager can control the audios.

C#
protected override void OnNavigatedTo ( NavigationEventArgs e )
{
 // ...
 
 this.resourceManager.LoadContent ( );
 this.audioManager.LoadContent ( this.resourceManager );
 base.OnNavigatedTo ( e );
}
private void OnUpdate ( object sender, GameTimerEventArgs e )
{
 this.step++;
 if ( this.step <= 60 )
  this.audioManager.PlaySound ( "click.s" );
 else if ( this.step == 61 )
  this.audioManager.PlayMusic ( "music1" );
 else if ( this.step == 300 )
  this.audioManager.StopMusic ( );
}

Get code at http://wp-xna.googlecode.com/, for more contents, please visit WPXNA.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)