18 Apr 2011

Play Audio on the iPhone

I want to teach you how to play audio files on the iPhone by clicking a button. I will show you the correct way to handle memory management when playing an audio file (since this often is not addressed).

I will skip the uber-basics of creating an iPhone App since it has been done over and over. If you need to learn from square 1, I suggest reading iPhone and iPad Apps for Absolute Beginners.

First, create a project. I called mine Audio. Next, add the AVFoundation framework. Then, #import <AVFoundation/AVAudioPlayer.h> into your header file. Make your header file implement the <AVAudioPlayerDelegate>.

Create a pointer to an AVAudioPlayer object: AVAudioPlayer *audioPlayer;

Declare the property for the audioPlayer: @property (nonatomic, retain) AVAudioPlayer *audioPlayer;

Declare a method in the header file: - (void)playAudio;

Synthesize your audioPlayer in the .m file: @synthesize audioPlayer;

Be certain to release the audioPlayer in the dealloc method. It is a good idea to use the dealloc method to release any object that has been synthesized.

Finally, we implement the method for playAudio:

We create a NSString which specifies the file name “ha”, it’s type “m4a”, and location: in the main bundle. This is a sample sound from our Hawaiian Names & Hawaiian Words Apps.

The key to this tutorial is memory management, which is why we now create a new AVAudioPlayer pointer object called newAudio and initialize it with the contents of our soundPath (but in URL format as AVAudioPlayer requires).

We can then set audioPlayer equal to newAudio and release newAudio from memory (since it was allocated, we are responsible for releasing it).

Next, set the delegate of audioPlayer to this class (we added the AVAudioPlayerDelegate to the header).

Finally, play the sound.

In order for this App to work, you must connect a button or some other action to call the - (void)playAudio method. This is covered in the book I mentioned.

Why do we create audioPlayer, and not just newAudio? Because we would need to release newAudio somewhere within the method, and if we release it right after we play, the sound gets clipped. There are cases when we could release the AVAudioPlayer object after its BOOL property isPlaying is no longer true, but the structure I have presented allows more flexibility in playing multiple sounds at once and sequentially, such as in our app: Animal Translate.

Full code below:

AudioViewController.h

AudioViewController.m