This article is the third in a three-part Audio Tutorial series covering audio topics of interest to the iPhone developer.
So far in this Audio Tutorial series we’ve talked about the difference between file and data formats and how to convert and record audio on your Mac. Now we’ll get to the fun part – actually playing audio on your phone!
There are many ways to play audio on the iPhone – System Sound Services,
AVAudioPlayer, Audio Queue Services, and OpenAL. Without outside support libraries, the two easiest ways by far are System Sound Services and
AVAudioPlayer – so let’s talk about when you would (and wouldn’t) want to use those, and how you can use them.
System Sound Services
System Sound Services provides an extremely easy way to play short audio files. This is particularly useful for audio alerts and simple game sounds (such as making a ‘click’ when moving a game piece). All you have to do is the following:
NSString *pewPewPath = [[NSBundle mainBundle] pathForResource:@"pew-pew-lei" ofType:@"caf"]; NSURL *pewPewURL = [NSURL fileURLWithPath:pewPewPath]; AudioServicesCreateSystemSoundID((__bridge CFURLRef)pewPewURL, &self.pewPewSound); AudioServicesPlaySystemSound(self.pewPewSound);
It is important to define pewPewSound as an iVar or property, and not as a local variable so that you can dispose of it later in dealloc. It is declared as a SystemSoundID.
If you were to dispose of it immediately after
AudioServicesPlaySystemSound(self.pewPewSound), then the sound would never play.
Doesn’t get much easier than that. However there are some strong drawbacks to this method:
- It only supports audio data formats linear PCM or IMA4.
- It only supports audio file formats CAF, AIF, or WAV.
- The sounds must be 30 seconds or less in length
- The sound plays at once.
- Only one sound can play at a time
- And more – see the Multimedia Programming Guide.
So what if you have an audio file encoded with AAC or MP3 that you want to play as background music? Another easy way to play music is via the
AVAudioPlayer class. Since the
AVAudioPlayer class is part of
AVFoundation, you will need to
@import AVFoundation into your project.
For the most part, it again is quite simple:
NSError *error; self.backgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:backgroundMusicURL error:&error]; [self.backgroundMusicPlayer prepareToPlay]; [self.backgroundMusicPlayer play];
There are many advantages of using
AVAudioPlayer; it gives you a lot of bang for the buck. You can also play several sounds at once (using a different
AVAudioPlayer for each sound), and you can play sounds even when your app is in the background.
However, the drawback of
AVAudioPlayer is it can be extremely slow. If you tap a button and try to trigger a sound with
AVAudioPlayer, there will be a noticeable small delay. But if that doesn’t matter to you (like for starting up background music),
AVAudioPlayer is a fine choice. By the way,
prepareToPlay is optional; if you don’t call it, it will be called implicitly when the
And there are a couple other things to keep in mind:
- If you’re playing background music, you should check to see if other audio (like the iPod) is playing first, so you don’t have two layers of music going on at once!
- If a phone call arrives and the user chooses “Decline,” by default your
AVAudioPlayerwill stop. You can start it back up again by registering for the
AVAudioPlayerDelegateand resuming music in the
I put together some sample code showing how to use System Sound Services and
AVAudioPlayer that you might want to check out. It also illustrates how to use AVAudioSessions, how to handle interruptions, and how to set audio to play in the background. And in addition to demonstrating those APIs, it has some mighty funky beats and a cool spaceship to boot. Pew-pew!
If you’re writing a game or another app where you want fine grained control of audio with low latency, you probably don’t want to use the above methods. Instead, you might want to use
OpenAL, a cross-platform audio library supported by the iPhone.
OpenAL can be a beast with a steep learning curve. Luckily, Alex Restrepo has made a nice Sound Engine library using
OpenAL that you can either use in your projects or use as a reference.
Another option is the Cocos2D game library, which includes an extremely easy to use sound engine that makes playing audio a snap. You can learn how to use it the tutorial on How To Make a Simple iPhone Game With Cocos2D 3.0.
Where to go from here?
That’s about all I’m going to cover about audio topics in iPhone programming for now – but keep in mind I’ve barely scratched the surface. If you’re interested in more, I’d recommend reading Apple’s docs, especially the Core Audio Overview and the Audio Session Programming Guide, and possibly digging into OpenAL a bit more. You might also like to look at the tutorial How To Make a Music Visualizer that contains some additional examples of iPhone audio.
I hope this Audio Tutorial series has been useful to other developers who may be new to audio concepts. Feel free to share any additional info you’re aware of regarding audio programming that may be useful to others!