Advertisement

iPhone Coding: Recording Audio

%Gallery-5616%

Yesterday, I figured out how to record audio on the iPhone. Today, by popular request, I'll go through the how-to part. And, for those of you paying close attention, I've updated the application with lots of nice new features. For those of you playing along at home, here are the basics you'll need to know to get started with audio recording.

Frameworks. Surprisingly the whole audio recording thing does not derive from CoreAudio. You'll find the AVRecorder class in the Celestial framework. So in order to use this code, you're going to need to class-dump Celestial.framework. You'll find it on your phone in /System/Library/Frameworks. Copy the framework to your Mac and perform the dump there. Use the class dump as an include file and trim away anything that keeps it from compiling. You'll need to keep AVRecorderPrivate and AVRecorder at a minimum. Make sure you've got some sort of NSObject.h included somewhere in your includes.

#import <celestial.h>

Add an AVRecorder as an instance variable. Since you'll want to start and stop your recording at separate times, make sure whatever class you build can set a new AVRecorder and refer to it later. After you start recording, you'll need to return to that instance and deactivate the recorder.

@interface MyAudioApp : UIApplication {
AVRecorder *recorder; }
@end

Reaquaint yourself with CFURLRef. I know. CFURLRefs are supposed to be pretty interchangable with their NS cousins. But they're not. So you need to use CFURLRef to point to the file you want to record to. For example:

NSMutableString *fullpathname = @"/var/root/foo.amr";
CFURLRef url;
CFStringRef sref;

sref = CFStringCreateWithCString(nil,
[fullpathname cStringUsingEncoding:
[NSString defaultCStringEncoding]],
kCFStringEncodingASCII);

url = CFURLCreateWithFileSystemPath(nil, sref,
kCFURLPOSIXPathStyle, 0);

Start recording by initializing. Once you get this far, it's just a matter of bookkeeping to get your recorder started. Here's the relevant code. Allocate and initiate the recorder instance, activate it and assign it the CFURLRef URL you've created. Then tell it to start. Recording starts instantly.

// Start recording

recorder = [[AVRecorder alloc] init];
[recorder activate:self];
[recorder setFilePath:url];
[recorder start];

Stop the recording with "stop". When you're ready to finish recording, just send a stop message to your recorder and deactivate it. The file has already saved automatically to disk. If you want, you can query the number of bytes written before deactivating by sending a recordedFileSizeInBytes message.

[recorder stop];
[recorder deactivate];

And that's pretty much the whole shebang. It took a lot of work to figure this all out but once figured out it is exceptionally easy to use.