我正在尝试将传入的麦克风音频写入文件。因为音频样本在时间关键的回调中一次传送4096帧(我的项目的设置帧速率),所以我不能简单地将字节写入带有AudioFileWriteBytes的文件。我也不希望经历设置我自己的环形缓冲区以将样本存储到其他地方的努力和复杂性。所以我使用扩展音频文件API作为其ExtAudioFileWriteAsync函数。
根据文档的指示,我使用CFURL创建ExtAudioFileRef,然后使用空缓冲区和main中的0帧运行一次。然后我启动我的AUHAL单元并开始调用输入回调。
ExtAudioFileWriteAsync(player.recordFile, 0, NULL);
我有我的代码异步写入此文件。我将调用嵌套在一个调度队列中,以便它在回调函数退出作用域后运行(不确定是否有必要但是我在没有封闭调度块的情况下得到这个错误)。这是现在的回调。
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;
}
它在第一次回调调用时立即解决了错误的访问异常。为清楚起见,这些是我开始创建文件时的设置。
// 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);