iPhone Coding: Recording Audio
Gallery: VRecord
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.

Get a WordPress.com Blog
![TUAW [Cafepress]](http://www.blogsmithmedia.com/www.tuaw.com/media/tuaw-cafepress-promo.png)


Reader Comments (Page 1 of 2)
jtbandes said 4:44PM on 8-06-2007
Wow, that's amazing. Mind posting the full code so we can see how you got the delete buttons and stuff working?
Reply
Lance said 4:49PM on 8-06-2007
Very nicely done! This is extremely promising stuff. Keep up the great work. ;)
Reply
Robert said 4:55PM on 8-06-2007
Posted on previous thread but mire timely here:
I have a real problem now - what to do when one installs MORE than four applications (Recorder, Terminal, Tic Tac Toe, Zune2 and iTetris - Zune2 is barely a game and iTetris is far from complete)? SpringBoard doesn't seem to let you scroll.
Thoughts?
Reply
tendo said 6:28PM on 8-06-2007
some one should make a spring board2 app, similar to an application folder.
Reply
liosha said 6:44PM on 8-06-2007
Can't get it working. It starts but nothing happens — background only — and then quits.
Reply
Lance said 6:17PM on 8-06-2007
@liosha
Did you chmod +x the app files? Sounds like that's the problem.
Reply
buzzert said 9:26PM on 8-06-2007
This is actually really impressive! Looks like we've still got to figure out how to indent the text when in 'edit' mode (the circle delete button overlaps the text), I guess that's not built into the UIKit framework.
It's nice to see an actual woman geek/programmer! Those are quite rare these days.
Reply
David D said 6:57PM on 8-06-2007
Erica, nice progress.
here's some testing help:
Sleep - Wake notes:
I've run some tests. It appears to stop recording now, when the iPhone is put to sleep manually. It also stops recording if, after going to sleep manually, you wake it up in order to hit the Finish Recording button.
Sound error notes:
Several times after recording for more than ten minutes, it either went silent (but kept creating file length on disk), or recorded the strange echoing sounds of a one-second piece. Then it started to 'feedback' and became total static for the duration.
Other glitch (potentially big bug):
One time I recorded for about 12 minutes, but the app created a 45 minute recording! The size seemed correct for a 45 minute recording too - meaning that you could chew up a large amount of disk space if this bug were to multiply more. Imagine if I recorded for an hour and it multiplied that 10 times, resulting in a file over 100Mb or ?
Overall - the start of a great app, as I've said before you have my support.
Reply
liosha said 8:01PM on 8-06-2007
@Lance
Thanks. It's a late night here :) Got it for now.
Reply
AJ said 1:15AM on 8-07-2007
Hey Erica - I have an icon for you for this app :) Email me and I'll send it to you
Reply
mannyv said 2:29AM on 8-07-2007
What happens when you run out of space?
This is a real problem on handhelds, and there isn't really a good solution to it. Can anyone who installs this report on what happens when your filesystem is full?
Reply
Alin Almasan said 5:36AM on 8-07-2007
So how do you play back the files without having to get file to your pc?Thanks
Reply
Lance said 6:32AM on 8-07-2007
@Alin
Download the newest version of the app at the bottom of the OP. It supports playback directly through the iPhone.
Reply
Gregg said 8:41AM on 8-07-2007
How do you install an app to the phone?
Reply
seth exis said 8:58AM on 8-07-2007
so, i'm jailbreaking into the phone, using iphoneinterface to putfile VRecord.app to /Applications, then SSHing to VRecord.app to chmod +x it then restoring my Services.plist and rebooting the phone.
the app still doesn't show up in the springboard. is there a step i'm missing?
i'm excited to check this out. if anyone has any suggestions as to something i may be missing in my workflow, please let me know. thanks!
Reply
David said 10:06PM on 8-07-2007
I have an older version of the vrecord and I want to delete it before adding the new version. I have SSH running but when I try and use rmdir on any of the files or VRecord.app directory it tells me permission denied. Any ideas?
Reply
Sean said 1:49PM on 8-09-2007
Can you use an external mic with this?
Reply
a said 2:28AM on 8-12-2007
What is the pattern for the number in the filenames?
Could the next version name files by date and time? Pretty please? ^_^
Reply
Jesper said 7:30PM on 8-16-2007
You can cast an NSString (or NSMutableString) to a CFStringRef:
NSMutableString *fullpathname = @"/var/root/foo.amr";
CFURLRef url;
CFStringRef sref;
sref = (CFStringRef)fullpathname;
It's called "toll-free bridging", it's odd, but it works and it is supported. Google for it for more info.
Reply
Jesper said 7:34PM on 8-16-2007
Toll-free bridging may not work on the iPhone, of course. But with both NSString and CFString there, it makes sense that it would.
Reply