iPhone Programming Part 5 : Audio

In this post I will talk about programming audio output on iPhone devices. This task comes like the arcade apothegm : “easy to learn but difficult to master”.


First I have to say that this article is based one this article.

The quickest (and easiest) way to make the iPhone spit out some sound is to use the audio system services:

First you have to add the AudioToolbox Framework to your application and import the header files:

 #import <AudioToolbox/AudioToolbox.h>

to load and play the sound :

NSString* path = [[NSBundle mainBundle] pathForResource:@"soundName" ofType:@"caf"];
NSURL * afUrl = [NSURL fileURLWithPath:path];
UInt32 soundID;
AudioServicesCreateSystemSoundID((CFURLRef)afUrl,&amp;soundID);
AudioServicesPlaySystemSound (soundID);

Allthough this is good enough to make some UI interaction sounds you probably want control on preloading files and play the sound synchronously to an action, especially on game development. On the other hand you want to keep your code as portable as possible. So lets go through a super quick introduction to openAL which is conform to all these aspects.

There are five consistently appearing terms openAL you may want to know more about :

  • LISTENER
  • SOURCE
  • BUFFER
  • DEVICE
  • CONTEXT or SESSION

The LISTENER is you. Any sound the listener can ‘hear’ comes out the speakers. OpenAL allows you to specify where the listener is in relation to the sources, but for this example we do not care, we are going to bare minimum static sound, so just keep in mind that there is a concept of ‘listener’ and that you could move this object around if you wanted to do more complicated stuff.

The SOURCE is something analogous to a speaker. It generates sound which the listener can ‘hear’. Like the listener, you can move the sources around.

The BUFFER contains the raw audio data of the sound that will be played.

The DEVICE is the actuial bit of harware that will be playing the sound.

The CONTEXT or SESSION is something like a room containing all the sources and the listener. Metaphorically speaking the sources are musicians the listener is a microphone and the CONTEXT is something like air the sound is going through. You will setup positions of Listener and Sources here and you can specify a category for this:

  • kAudioSessionCategory_UserInterfaceSoundEffects:Use this category for sound effects such as touch feedback, explosions, etc.
  • kAudioSessionCategory_AmbientSound : Use this category for backgound sounds such as rain, car engine noise, etc. Mixes with other music.
  • kAudioSessionCategory_SoloAmbientSound : Use this category for backgound sounds. Other music will stop playing.
  • kAudioSessionCategory_MediaPlayback : Use this category for music tracks.
  • kAudioSessionCategory_LiveAudio : Use this category for interactive music such as playing an instrument on the screen.
  • kAudioSessionCategory_RecordAudio : Use this category when recording audio.
  • kAudioSessionCategory_PlayAndRecord : Use this category when recording and playing back audio.

To get this all work you need five tasks to be done:

  1. get the device
  2. make a context with the device
  3. put some data into a buffer
  4. attach the buffer to a source
  5. play the source

Audioformats I successfully tested :

  • .CAF (16-Bit PCM) Not Compressed
  • .AIF (IMA4 16-Bit PCM) Compressed

.CAF
To convert a audiofile to this format simply open a terminal on your mac and type:

usr/bin/afconvert -f caff -d LEI16@44100 inputSoundFile.aiff outputSoundFile.caf

.AIF
To convert an audiofile to this format use export on quicktime pro.

In the next post I will discuss how to use openAL with multiple sound sources.


About this entry