RSS

Exploring iPhone Audio Part 4

April 2nd, 2008 Posted in Software Development, iPhone

Old Fashioned Microphone
In Part 3 of this series of articles we created the AudioInputCallback function that does nothing more than log that it is being called. In this article we’ll learn how to create an audio file in the Document directory of the iPhone flash memory and write audio data to the file.




First of all we’ll need to include the header file that contains the audio file handle functions with the following #import directive:

1
#import <AudioToolbox/AudioFile.h>

Remember, #import is the same as #include with the added benefit of it not trying to include the same header file more than once.

The following variable declaration needs to be added to the RecordState struct:

1
AudioFileID audioFile;

This will be assigned the handle to the audio file we’ll be creating.

The following code needs to be added at a point before we start recording.

The first thing we need to do is find the path to our application’s Document directory. For the simulator this is a path on your computer’s hard drive. See the Where is the iPhone Simulator Filesystem Stored? article for information on where our file will end up when run on the simulator. The path will be different for the iPhone so we cannot hard code it. The following function will return a C string containing the full path to a file named recording.aif in our application’s Document directory:

1
2
3
4
5
6
7
8
- (BOOL)getFilename:(char*)buffer maxLenth:(int)maxBufferLength
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
            NSUserDomainMask, YES); 
    NSString* docDir = [paths objectAtIndex:0];
    NSString* file = [docDir stringByAppendingString:@"/recording.aif"];
    return [file getCString:buffer maxLength:maxBufferLength encoding:NSUTF8StringEncoding];
}

We need a C string instead of a NSString object because the AudioFile API is a C library and needs C strings. The C string needs to be converted to a CFURLRef object with the following call:

1
CFURLRef fileURL = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)path, strlen(path), false);

Now we are ready to create the file:

1
2
3
4
5
OSStatus status = AudioFileCreateWithURL(fileURL,
            kAudioFileAIFFType,
            &recordState.dataFormat,
            kAudioFileFlags_EraseFile,
            &recordState.audioFile);

Parameters:

  1. The CFURLRef set to the full path of the file to be created.
  2. This is the type of file we want to create. In this case we are creating an AIFF file.
  3. The format of our audio data that we specified earlier.
  4. kAudioFileFlags_EraseFile causes an existing file to be overwritten.
  5. The last parameter is a pointer to the AudioFileID variable of the our RecordState structure.

The audio file has now been created and we are ready to start writing audio data to it in the AudioOutputCallback function.

When writing data to the audio file we need to keep track of what packet we are on. We’ll keep track of this by adding another variable to the RecordState structure:

1
SInt64 currentPacket;

The following call will write the data received in the callback function to the audio file:

1
2
3
4
5
6
7
8
9
10
11
OSStatus status = AudioFileWritePackets(recordState->audioFile,
                false,
                inBuffer->mAudioDataByteSize,
                inPacketDescs,
                recordState->currentPacket,
                &inNumberPacketDescriptions,
                inBuffer->mAudioData);
if(status == 0)
{
     recordState->currentPacket += inNumberPacketDescriptions;
}

AudioFileWritePackets parameters:

  1. The AudioFileID we created earlier.
  2. This parameter turns caching off.
  3. The size of the audio data buffer to be written.
  4. The packet description passed to the callback function.
  5. The current packet number.
  6. The number of packets.
  7. The actual audio data that was recorded.

If the call to AudioFileWritePackets succeeds we increment the currentPacket variable of the RecordState structure by the number of packets recorded.

So now we’ve opened an audio file and are writing recorded audio data to it. The next article will discuss how to use the iPhone’s GUI interface to control the recording process.

[del.icio.us] [Digg] [Reddit] [Technorati]

RSS feed | Trackback URI

1 Comment »

2008-04-05 20:28:08

[…] Part 4 of this series talked about writing recorded audio data to a file. In this article we will set create a very simple user interface so we can control the audio functions. […]

 
Name (required)
E-mail (required - never shown publicly)
URI
Subscribe to comments via email
Your Comment (smaller size | larger size)
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong> in your comment.