5 Simple XNA Audio
ITP4710
2D/3D Graphics Programming
05
Simple Audio Control
There are two simple ways to play an audio sound in an MonoGame application
Play sounds for background music or sound effects using SoundEffect and SoundEffectInstance classes
Longer sound samples such as songs can be played using media playing features of XNA.
Using MediaPlayer and Song classes
allows you to play compressed .mp3 and .wma files as background music.
2
Simple Audio Playback
© VTC 2016
As in using other meida contents (e.g. images), using SoundEffect in your game project involves the similar steps:
You need to first add the sound files to the folder inside your Content Pipeline Tool.
Only .wav file is supported for SoundEffect class
After saving and building the Content, you will declare a variable to hold the content in your project.
The sound content is then loaded into the variable using Content.Load() method.
After loading the content into the variable, you can use the Play() method in SoundEffect to play the sound.
3
Adding Sounds to your Project
© VTC 2016
Declare SoundEffect variable at module level
SoundEffect soundEffect;
string soundName = “kaboom”;
Load sound in LoadContent() method
soundEffect = Content.Load
Play sound when necessary
soundEffect.Play();
4
Sound Play Sample
© VTC 2016
Usually, background music will repeat after it finishes playing and you would also like to
pause/resume the music when the player pause/resume the game
stop/restart the music when the player exit a game / enter a new game
SoundEffectInstance class controls how the SoundEffect is played.
SoundEffectInstance object is created through the Play() method in SoundEffect
If you want to control your sound play, you would like to store the SoundEffectInstance object in a variable
5
Playing Background Music
© VTC 2016
Starting a playback
SoundEffect music;
SoundEffectInstance musicInstance = null;
if (musicInstance == null) musicInstance = music.Play();
else musicInstance.Play();
Pausing a playback
if (musicInstance != null) musicInstance.Pause();
Resuming a paused playback
musicInstance.Resume();
musicInstance.Play();
6
Controlling Sound Playback
© VTC 2016
If you are going to loop the sound, you should create your SoundEffectInstance object through CreateInstance() method instead of Play() method in SoundEffect.
SoundEffectInstance instance = soundEffect.CreateInstance();
instance.IsLooped = true;
instance.Play();
The IsLooped property is set to true to make the SoundEffectInstance play repeatedly
7
Repeating the Sound
© VTC 2016
Other useful properties in SoundEffectInstance class includes
Pitch
Pitch adjustment, ranging from -1.0f (down one octave) to 1.0f (up one octave).
0.0f is unity (normal) pitch.
Pan
Panning, ranging from -1.0f (full left) to 1.0f (full right).
0.0f is centered
Volume
Volume, ranging from 0.0f (silence) to 1.0f (full volume).
1.0f is full volume relative to SoundEffect.MasterVolume.
8
Pitch, Pan and Volume
© VTC 2016
On Windows Phone, a game can only have a maximum of 64 total playing SoundEffectInstance instances at one time, combined across all loaded SoundEffect objects.
On Windows, there is no hard limit.
Playing too many instances can lead to performance degradation.
On Xbox 360, the limit is 300 sound effect instances loaded or playing.
Dispose of old instances if you need more
9
Limitation on SoundEffect
© VTC 2016
SoundEffect is not suitable for playing long sound samples such as songs
sound data may take up too much program memory
compressed (mp3, mp4, wma or ogg) files save more space
While XNA is not able to use the compressed files as content for sound effects, it does have the ability to play these files using MediaPlayer class
Need to include the using Meida statement:
using Microsoft.Xna.Framework.Media;
The files are loaded into Song object through Content.Load() method
MediaPlayer class’s static methods and properties can be used in playing a single song
10
Playing Songs Using MediaPlayer Class
© VTC 2016
Available MediaPlayer methods:
MediaPlayer.Play(Song s)
MediaPlayer.Pause() and MediaPlayer.Resume()
MediaPlayer.Stop()
Available MediaPlayer properties:
MediaPlayer.IsMuted: set to true to mute
MediaPlayer.IsRepeating: set to true to repeat
MediaPlayer.PlayPosition (value: TimeSpan): retrieve and/or set the play position
MediaPlayer.Volume: set to value between 0.0 and 1.0
© VTC 2016
11
Playing Songs Using MediaPlayer Class
// Need to include the using Meida statement
using Microsoft.Xna.Framework.Media;
protected override void LoadContent() {
spriteBatch = new SpriteBatch(GraphicsDevice);
this.song = Content.Load
MediaPlayer.Play(song);
MediaPlayer.MediaStateChanged +=
MediaPlayer_MediaStateChanged; // event handler added here
}
// event handler: play the song again with lower volume once the media state changed, i.e., the song completed.
void MediaPlayer_MediaStateChanged(object sender, System.EventArgs e) {
// 0.0f is silent, 1.0f is full volume
MediaPlayer.Volume -= 0.1f;
MediaPlayer.Play(song);
}
© VTC 2016
12
Sample Code of MediaPlayer
3D game audio typically implements at least three effects:
speaker positioning,
volume attenuation over distance, and;
Doppler pitch shifting.
Monogame does have support for 3D audio positioning effects.
AudioEmitter and AudioListener classes are used
SoundEffectInstance.Apply3D() method is also needed
The effects simulate 3D positioning for sound by adjusting speaker mix for different sound effects that use the 3D values
Any stereo information in the sound is discarded.
13
Positional Audio Playback
© VTC 2016
The two classes represent 3D audio emitter and listener respectively
Main properties
Forward – the forward orientation vector for this emitter/listener
Position – the position of this emitter/listener
Up – the upward orientation vector for this emitter/listener
Velocity – the velocity vector of this emitter/listener
14
AudioEmitter and AudioListener
© VTC 2016
The Doppler Effect is the change in frequency of a wave for a listener moving relative to the source of the wave.
It is commonly heard when a vehicle sounding a horn approaches, passes, and moves away from an observer.
The received frequency is higher than the emitted frequency during the approach
It is identical at the instant of passing by
It is lower during the moving away.
The Doppler Effect value applied to a sound is based on the relative velocity of the AudioEmitter and AudioListener with respect to the Forward and Up vectors of each.
15
Doppler Effect
© VTC 2016
Declare variables for SoundEffectInstance and SoundEffect
Declare variables for an AudioEmitter, an AudioListener, and Vector3 variables to store the 3D position, forward and other properites of the sound entity.
Load the SoundEffect and create a SoundEffectInstance to play the sound.
Call Apply3D() on the SoundEffectInstance, passing the emitter and listener as parameters
Call Play() to play the sound. Set the IsLooped property to true before calling Play() if you want the sound to repeat.
16
Applying Positional Playback to a SoundEffect
© VTC 2016
In your Update() method
Set the Vector3 to the position from which you want the sound to come
Set the AudioEmitter.Position property as this vector.
As an option, set the Vector3 to the position where you want the listener of the 3D sound to be, and then set the AudioListener.Position property to this vector.
Call SoundEffectInstance.Apply3D() on the sound, passing in the AudioEmitter and AudioListener.
17
Process Audio Data for
Positional Playback
© VTC 2016
protected override void LoadContent() {
spriteBatch = new SpriteBatch(GraphicsDevice);
soundEffect = Content.Load
instance = soundEffect.CreateInstance();
instance.IsLooped = true;
listener = new AudioListener();
emitter = new AudioEmitter();
// WARNING!! Apply3D requires MONO soundeffect!
// Stereo will throw exception
instance.Apply3D(listener, emitter);
instance.Play();
}
© VTC 2016
18
Sample of Using Positional Playback
protected override void Update(GameTime gameTime) {
if (GamePad.GetState(PlayerIndex.One).Buttons.Back
== ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown( Keys.Escape))
Exit();
if (Keyboard.GetState().IsKeyDown(Keys.Left))
listener.Position.X -= 0.1f;
if (Keyboard.GetState().IsKeyDown(Keys.Right))
listener.Position.X += 0.1f;
if (Keyboard.GetState().IsKeyDown(Keys.Up))
listener.Position.Y += 0.1f;
if (Keyboard.GetState().IsKeyDown(Keys.Down))
listener.Position.Y -= 0.1f;
instance.Apply3D(listener, emitter);
base.Update(gameTime);
}
© VTC 2016
19
Sample of Using Positional Playback
Microsoft Developer Network (MSDN) Library
Development Tools and Languages > XNA Game Studio > XNA Game Studio 4.0 Refresh > Writing Game Code > Creating and Playing Sounds
(http://msdn.microsoft.com/en-us/library/bb195038.aspx)
MonoGame Tutorial: Audio, GameFromScratch.com (http://www.gamefromscratch.com/post/2015/07/25/MonoGame-Tutorial-Audio.aspx)
© VTC 2016
20
Reference