0

I am attempting to write incoming mic audio to a file. Because the audio samples are delivered 4096 frames (the set frame rate for my project) at a time in a time-critical callback I cannot simply write the bytes to a file with AudioFileWriteBytes. I also did not wish to go through the effort and complexity of setting up my own ring buffer to store samples to write elsewhere. So I am using Extended Audio File API for its ExtAudioFileWriteAsync function.

As per instructed by the documentation I create the ExtAudioFileRef with a CFURL and than run it once with a null buffer and 0 frames in main. Then I initiate my AUHAL unit and the input callback begins to be called.

ExtAudioFileWriteAsync(player.recordFile, 0, NULL);

There I have my code to write to this file asynchronously. I have the call nested in a dispatch queue so that it runs after the callback function exits scope (tho not sure if that is necessary but I get this error with all without the enclosing dispatch block). This is the callback as it is right now.

OSStatus InputRenderProc(void *inRefCon,
                         AudioUnitRenderActionFlags *ioActionFlags,
                         const AudioTimeStamp *inTimeStamp,
                         UInt32 inBusNumber,
                         UInt32 inNumberFrames,
                         AudioBufferList * ioData)
{
   MyAUGraphPlayer *player = (MyAUGraphPlayer*) inRefCon;

   // rendering incoming mic samples to player->inputBuffer
   OSStatus inputProcErr = noErr;
   inputProcErr = AudioUnitRender(player->inputUnit,
                                  ioActionFlags,
                                  inTimeStamp,
                                  inBusNumber,
                                  inNumberFrames,
                                  player->inputBuffer);


   printf("%i", inNumberFrames);
   dispatch_async(player->fileWritingQueue, ^{
      ExtAudioFileWriteAsync(player->recordFile, 4096, player->inputBuffer);
   });

   return inputProcErr;
}

It immediately bails out with the bad access exception on the first callback invocation. For clarity these are the settings I have for creating the file to begin with.

   // describe a PCM format for audio file
   AudioStreamBasicDescription format =  { 0 };
   format.mBytesPerFrame = 4;
   format.mBytesPerPacket = 4;
   format.mChannelsPerFrame = 2;
   format.mBitsPerChannel = 16;
   format.mFramesPerPacket = 1;
   format.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsFloat;
   format.mFormatID = kAudioFormatLinearPCM;

   CFURLRef myFileURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("./test2.wav"), kCFURLPOSIXPathStyle, false);


   ExtAudioFileCreateWithURL(myFileURL,
                             kAudioFileWAVEType,
                             &format,
                             NULL,
                             kAudioFileFlags_EraseFile,
                             &player.recordFile);
   player.fileWritingQueue = dispatch_queue_create("myQueue", NULL);

   ExtAudioFileWriteAsync(player.recordFile, 0, NULL);
  • Where does the debugger stop? Is anything `NULL` around that line of code? – Nicolas Miari Jan 13 '16 at 04:49
  • I can't find anything NULL. The player->inputBuffer contains an audioBufferList and player->recordFile is an extAudioFileRef. One thing it might be is a mismatch between the audiobufferList topology (amount of buffers/num of channels) and the extAudioFile I set up. I passed NULL for the channel layout struct when creating it but the Docs seemed to imply I could do that. However, stepping through the debugger i did notice that at the dispatch code it hops over the extWriteFile function and comes back after the callback ends. – Alexander Bollbach Jan 13 '16 at 05:16
  • actually it isn't the dispatch block. I removed the block and just called it normally and it still gets the bad access. – Alexander Bollbach Jan 13 '16 at 05:18
  • Which line of code does the debug cursor point? – Nicolas Miari Jan 13 '16 at 05:19
  • the cursor stops on the first ExtAudioFileWriteAsync call in the input callback. bad access exception, process terminates.. – Alexander Bollbach Jan 13 '16 at 05:38
  • Searching for the function name gave me this other SO question: http://stackoverflow.com/q/9278147/433373 – Nicolas Miari Jan 13 '16 at 05:46
  • @NicolasMiari i read that, and checking the error on the write function does indeed yield a (-50) OSStatus error. However, unlike that poster changing the function to the synchronous version still results in a crash. – Alexander Bollbach Jan 13 '16 at 06:27

0 Answers0