Exploring iPhone Audio Part 6
April 14th, 2008 Posted in Software Development, iPhone
In Part 5 of this series we added a simple user interface to control the audio recording process. A UILabel was added to display the status. Also two buttons were added to control both recording and playback. Up to this point we have only discussed recording audio. This article will begin to see how to play back audio on the iPhone.
For audio playback we need a structure to keep track of the state of the playback just like we did with the recording process.
1 2 3 4 5 6 7 8 9 | typedef struct { AudioStreamBasicDescription dataFormat; AudioQueueRef queue; AudioQueueBufferRef buffers[NUM_BUFFERS]; AudioFileID audioFile; SInt64 currentPacket; bool playing; } PlayState; |
For this example I’ve created a new stuct called PlayState that is very similar to the RecordState struct used for recording. A single structure could be created to manage both playback and recording if desired. We need to keep track of the same types of data for playing audio as we did for recording audio. We need the format of the audio data to be played, an audio queue, some audio buffers from which to play audio data, the handle of an audio file, an integer to keep track of where we are in the playback process and a flag keeping track of whether or not we are currently playing.
To the app delegate class we’ll add an instance of the new PlayState struct. We’ll also add declarations for startPlayback and stopPlayback methods that will be called from our Play UIButton to control the audio playback process.
1 2 3 4 | PlayState playState; - (void)startPlayback; - (void)stopPlayback; |
The setupAudioFormat method doesn’t change and we’ll be using it to populate the dataFormat variable of our PlayState structure just like we did for the RecordState structure. Since this example application only plays back the audio data it has recorded we don’t need to worry about the actual audio data in the file being different from the format we expect.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - (void)setupAudioFormat:(AudioStreamBasicDescription*)format { format->mSampleRate = 8000.0; format->mFormatID = kAudioFormatLinearPCM; format->mFramesPerPacket = 1; format->mChannelsPerFrame = 1; format->mBytesPerFrame = 2; format->mBytesPerPacket = 2; format->mBitsPerChannel = 16; format->mReserved = 0; format->mFormatFlags = kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; } |
We need to add a handler for the Play UIButton.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | - (void)playPressed:(id)sender { if(!recordState.recording) { if(!playState.playing) { printf("Starting playback\n"); [self startPlayback]; } else { printf("Stopping playback\n"); [self stopPlayback]; } } } |
This handler is very similar to the one to handle the Record button being pressed. It is a simple toggle that either calls the startPlayback method or the stopPlayback method based on the status of the playing flag of our PlayState struct.
Next time we’ll get into the nitty-gritty of audio playback and see how to actually start and stop audio playback using the iPhone SDK.












Related Articles:

[...] the last article of this series we started looking at iPhone audio playback. This time we are going to see how to [...]
Hi, thanks for the tutorials. I have been researching around for 3 days on how to play two audio files at the same time on my iphone. It mostly crashes. At one point I had it working well on the simulator but it crashed on the trials on the phone. I tried making 2 audioplayer objects derived from the same audioqueue with no success.
Any help would be greatly appreciated.
[...] ?????http://trailsinthesand.com/exploring-iphone-audio-part-6/ [...]
This is great thanks you so much!!
But please can I ask your advice, for the life of me I can’t get this to work…
format->mSampleRate = 8000.0;
format->mFormatID = kAudioFormatLinearPCM;
format->mFramesPerPacket = 1;
format->mChannelsPerFrame = 1;
format->mBytesPerFrame = 1;
format->mBytesPerPacket = 1;
format->mBitsPerChannel = 8;
format->mReserved = 0;
format->mFormatFlags = kLinearPCMFormatFlagIsBigEndian |
kLinearPCMFormatFlagIsSignedInteger |
kLinearPCMFormatFlagIsPacked;
Always comes back with format error which is most frustrating, and I can’t find any info on this anywhere - well apart from here - and I really need to use 8 bit.
Thanks in advance