Просто не может быть очень далеко в Core Audio. Моя цель - записать записанные аудиоданные с инструментального блока в файл. Я настроил вызов функции обратного вызова на блоке приборов с этим:Использование функции ExtAudioFileWriteAsync() в функции обратного вызова. Не удается запустить
CheckError(AudioUnitAddRenderNotify(player->instrumentUnit,
MyRenderProc,
&player),
"AudioUnitAddRenderNotify Failed");
Я создал файл и AudioStreamBasicDescription с этим:
#define FILENAME @"output_IV.aif"
NSString *fileName = FILENAME; // [NSString stringWithFormat:FILENAME_FORMAT, hz];
NSString *filePath = [[[NSFileManager defaultManager] currentDirectoryPath] stringByAppendingPathComponent: fileName];
NSURL *fileURL = [NSURL fileURLWithPath: filePath];
NSLog (@"path: %@", fileURL);
AudioStreamBasicDescription asbd;
memset(&asbd, 0, sizeof(asbd));
asbd.mSampleRate = 44100.0;
asbd.mFormatID = kAudioFormatLinearPCM;
asbd.mFormatFlags = kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
asbd.mChannelsPerFrame = 2; // CHANGED FROM 1 (STEREO)
asbd.mFramesPerPacket = 1;
asbd.mBitsPerChannel = 16;
asbd.mBytesPerFrame = 4;
asbd.mBytesPerPacket = 4;
CheckError(ExtAudioFileCreateWithURL((__bridge CFURLRef)fileURL, kAudioFileAIFFType, &asbd, NULL, kAudioFileFlags_EraseFile, &testRecordFile), "ExtAudioFileCreateWithURL failed");
CheckError(ExtAudioFileSetProperty(testRecordFile, kExtAudioFileProperty_ClientDataFormat, (UInt32)sizeof(asbd), &asbd), "ExtAudioFileSetProperty failed");
CheckError(ExtAudioFileWriteAsync(testRecordFile, 0, NULL), "ExtAudioFileWriteAsync 1st time failed");
Я проверить, что файл не получить создан. testRecordFile определена глобально (это единственный способ, которым я мог бы получить вещи, чтобы работать в данный момент):
ExtAudioFileRef testRecordFile;
Моя функция обратного вызова:
OSStatus MyRenderProc(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList * ioData)
{
if (*ioActionFlags & kAudioUnitRenderAction_PostRender){
static int TEMP_kAudioUnitRenderAction_PostRenderError = (1 << 8);
if (!(*ioActionFlags & TEMP_kAudioUnitRenderAction_PostRenderError)){
CheckError(ExtAudioFileWriteAsync(testRecordFile, inNumberFrames, ioData), "ExtAudioFileWriteAsync failed");
}
}
return noErr;
}
Когда я запускаю это программные завихрения и переходит в отладчик mode (lldb) в вызове ExtAudioFileWriteAsync. inNumberFrames = 512, и я подтвердил, что получаю стереоканалы аудиофайлов Float32 в ioData.
Что мне здесь не хватает?
Это имеет смысл. Я взял приманку в матче между ioData в шаблоне обратного вызова и ExtAudioFileWriteAsync. Мой код будет более обширным, поскольку я пишу в .aif, но у меня есть идея. Благодаря! –
Я проанализировал ваш код - в этом примере я использую CAF вместо AIF, потому что я хотел, чтобы этот пример был ясным и полезным для всех. Apple немного поработала со стандартом AIFF на машинах Intel, объявив линейную версию AIFF с линейным PCM-версией AIFF в качестве подтипа дополнений byte-swapped для добавления AIFC (aka SOWT) и еще более озадачивая формат, объединив стандарты AIFF и AIFC в "AIF". Береги себя. – user3078414
Это сработало! Еще раз спасибо.Надеюсь, когда-нибудь я смогу вернуть карму кому-то, когда я буду более опытным во всем этом. Для будущей ссылки я буду включать рабочий код для AIF ниже. Ура! –