EXC_BAS_ACCESS в Core Audio - запись данных микрофона в файл с расширенными службами AudioFile
Я пытаюсь записать входящий звук с микрофона в файл. Поскольку аудиосэмплы доставляются 4096 кадров (установленная частота кадров для моего проекта) за один раз в критичном по времени обратном вызове, я не могу просто записать байты в файл с AudioFileWriteBytes. Я также не хотел испытывать усилия и сложность настройки моего собственного кольцевого буфера для хранения сэмплов для записи в другом месте. Поэтому я использую API расширенного аудиофайла для его функции ExtAudioFileWriteAsync.
В соответствии с указаниями документации я создаю ExtAudioFileRef с CFURL и затем запускаю его один раз с нулевым буфером и 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);