Intro
I wanted to kick off the tutorials here on Paw Apps blog with a very simple introduction to the SimpleAudioEngine. For official documentation check out the Cocos2d API reference here: http://www.cocos2d-iphone.org/api-ref/1.0.0/interface_simple_audio_engine.html.
Before you get started working through the examples, the only setup required is that you drag an audio file into your Resources directory in Xcode. See here for information on what file formats are supported by SimpleAudioEngine.
One thing to mention before getting into the functionality is that the SimpleAudioEngine is in fact a singleton class. What is a singleton class you might be asking? A good quick tutorial can be found here. Basically it is a class that only gets instantiated once in an application. They are very handy, though. If you have used cocos2d at all, you should already have experience by using [CCDirector sharedDirector]. In the case of SimpleAudioEngine, you can call the class with [SimpleAudioEngine sharedEngine].
Preloading Audio
There are two types of audio that are common in every single game, background music and sound effects. Lucky for you, SimpleAudioEngine provides easy calls to get these up and running. But first lets talk a little behind the scenes. Audio, especially music, has the potential to have a large file size. And the last thing you want is your user to click PLAY and have the app freeze while the audio loads. To solve this problem, use SimpleAudioEngine’s preloadBackgroundMusic: or preloadEffect: depending on your circumstance.
Here is a quick example of preloading an audio file
[[SimpleAudioEngine sharedEngine] preloadBackgroundMusic:@"soundeffect.mp3"]; |
Playing Audio
Now that we have the audio preloaded, let’s make some noise! You really won’t believe how simple it is…
[[SimpleAudioEngine sharedEngine] playEffect:@"soundeffect.mp3"]; |
Need I say more? Well, ok… I will.
There are actually some really cool additional arguments you can add. I’m talking about playEffect:pitch:pan:gain:.
The pitch argument can be a little confusing, but here’s how it works. A value of 1.0 is no change to the pitch at all A value of 0.5 is one octave lower and a value of 2.0 is one octave higher. Do you see the equation? 2^x where x is how many octaves above or below the original pitch. So if you think like a musician and want to hear the sound effect exactly one halfstep above the original pitch, you should set the pitch to 2^(1/12). And just as a side note, documentation says the available range of values for pitch is from 0.5 to 2.0. However, in my own personal experience the range does extend past those two values.
Pan deals with what channel will produce the audio. Give a value of -1.0 for completely left and 1.0 for completely right.
Gain changes the attenuation and amplification (volume). This is the same scheme as pitch mentioned above. A value of 0.5 is an attenuation of -6dB and a value of 2.0 is an amplification of +6dB. And another side note, documentation mentions that a value greater than 1.0 has no effect in iOS 3.1.3 or 4.x. Oh well…
So let’s say I have a sound effect that is the pitch of middle C. I can play different notes with the following function
#import "SimpleAudioEngine.h" #import <math.h> - (void) playNote:(float)halfsteps { float p = powf(2.0f, halfsteps/12); [[SimpleAudioEngine sharedEngine] playEffect:@"noteC.mp3" pitch:p pan:0.0f gain:1.0f]; } |
One item worth mentioning real quick is the return value of playEffect:. It returns an unsigned int that is the ID for that sound effect. This gives you the ability to stop a sound effect before it has completed with stopEffect:.
Quick code
Here’s a few code snippets that you might find helpful with your dealings with SimpleAudioEngine.
/* Convert the pitch for SimpleAudioEngine to the number of halfsteps it represents */ +(float) halfstepsFromPitch:(float)pitch { return log2f(pitch) * 12; } |
/* Convert the number of halfsteps, positive or negative to the SimpleAudioEngine pitch */ +(float) pitchFromHalfsteps:(float)halfsteps { return powf(2.0f, halfsteps / 12); } |
/* Resume background music, see pauseBackgroundMusic for pausing */ if (![[SimpleAudioEngine sharedEngine] isBackgroundMusicPlaying]) [[SimpleAudioEngine sharedEngine] playBackgroundMusic:themeSong loop:YES]; |
Example Xcode
Check out an example we put together as an Xcode project: PawAppsExample_SimpleAudioEngine. You can find it and other tutorials on our github.
Updates
24OCT2011: Need more flexibility? Check out our CDAudioManager and CDSoundEngine tutorial!

Hi,
I am new at programming. I am building book app in Xcode with Cocos2D.
I have a button that plays a long effect, but I want the effect to stop if the page is turned. i know where to put that code and to use the “stopEffect” but I have no idea of where to get the “return value of play effect” .
Every tutorial I see says to just save the value returned – but I have no idea where that value appears or how to save it for when I use the stopEffect.
Any help would be greatly appreciated.
Thanks,
Sean
Hi Sean, thanks for the question.
You are heading in the right direction. Knowing where to put the stopEffect is half the battle. And as you said all you need to do is save the return value of the playEffect. Here’s a quick example:
unsigned int myEffect = [[SimpleAudioEngine sharedEngine] playEffect:@"noteC.mp3" pitch:p pan:0.0f gain:1.0f];
/* Other code between ... and then right when your page turns: */
[[SimpleAudioEngine sharedEngine] stopEffect:myEffect];
Hope this helps!
Thank you so much Jason! (I actually forgot where this page was, so i didn’t respond earlier)
But it’s not working somehow. Sorry for my inexperience, but where should I putting the code “unsigned init myEffect = [[SimpleAudioEngine sharedEngine}” ?
And on every page I’m going to have a different effect that plays. Is there a way to just stop whatever effect is playing (instead of a specific one)?
Thanks again,
Sean
Hi Jason,
Sorry to bother you again, I was just wondering if you could tell me where that first line of code should go. I still haven;t been able to find the answer anywhere.
Thanks,
Sean
Hi Sean, the first line should load and play the sound effect you give. If the file is a large file, then it might take a few seconds to load. Hopefully line endings didn’t confuse you, look for the semicolon at the end of the second line, that that is all the first line.
I do not know of a call that would stop ALL effects, the best thing I could tell you would be to store your return values from the playEffect and loop through stopping them.
If you are looking for a little more control, I recommend you check out this post