Search code examples
iosobjective-cavfoundationavaudiosessionavaudiorecorder

Recording with AVAudioSession - Why do I get more bytes than expected?


I'm setting up a recording session as follow:

NSString *audioFilePath = [NSTemporaryDirectory() stringByAppendingString:@"temp.bin"];
_audioFileURL = [NSURL fileURLWithPath:audioFilePath];

NSDictionary *recordSettings = @{
        AVFormatIDKey: @(kAudioFormatLinearPCM),
        AVLinearPCMIsBigEndianKey: @NO,
        AVLinearPCMIsFloatKey: @NO,
        AVEncoderAudioQualityKey: @(AVAudioQualityHigh),
        AVEncoderBitRateKey: @128000,
        AVLinearPCMBitDepthKey: @32,
        AVNumberOfChannelsKey: @2,
        AVSampleRateKey: @44100.0f
    };

According to this, the number of bytes should be:

bytes = 4 * 44100 * 2 * 2 = 705600 bytes

But actually when I get the recorded data:

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
{
  if (flag) {
  
    NSData *recordedAudioData = [NSData dataWithContentsOfURL:_audioFileURL options:0 error:&error];
    NSUInteger recordedAudioLength = [recordedAudioData length];

The recordedAudioLenght is slightly bigger: 709696 bytes.

How can I avoid this? Is the problem how I setup the recording or how I retrieve the data?


Solution

  • The data from AVAudioRecorder is not just raw bytes. It's in a container, in this case the Apple Core Audio Format or CAF. The extra 4kB are the file header and chunk headers, plus padding ("free" chunk).

    I don't believe there's any way to get AVAudioRecorder to output audio samples without a format. You can find many versions of that question. You would either need to use a lower-level tool like AVAudioSinkNode, or read the file after writing it and extract the samples.

    (Note that your AVEncoderBitRateKey and AVEncoderAudioQualityKey keys don't apply here, since this is LPCM. But they're not hurting anything; they're just ignored.)