如何将AUGraph的输出写入文件?

How*_*ack 5 core-audio ios

我正在尝试编写(应该是)一个简单的应用程序,它在AUGraph中按顺序包含一堆音频单元,然后将输出写入文件.我使用AUGraphAddRenderNotify添加了回调.这是我的回调函数:

OSStatus MyAURenderCallback(void *inRefCon,
                        AudioUnitRenderActionFlags *actionFlags,
                        const AudioTimeStamp *inTimeStamp,
                        UInt32 inBusNumber,
                        UInt32 inNumberFrames,
                        AudioBufferList *ioData) {
    if (*actionFlags & kAudioUnitRenderAction_PostRender) {
        ExtAudioFileRef outputFile = (ExtAudioFileRef)inRefCon;
        ExtAudioFileWriteAsync(outputFile, inNumberFrames, ioData);
    }
}
Run Code Online (Sandbox Code Playgroud)

这种作品.该文件是可播放的,我可以听到我录制的内容,但是有大量静电使其几乎听不见.

有人知道这有什么问题吗?或者有没有人知道将AUGraph输出记录到文件的更好方法?

谢谢您的帮助.

How*_*ack 6

关于音频单元我刚才有一个顿悟,帮助我解决了自己的问题.我对音频单元连接和渲染回调的工作方式存在误解.我认为它们是完全不同的东西,但事实证明连接只是渲染回调的简写.

从音频单元A的输出到音频单元B的输入执行kAudioUnitProperty_MakeConnection与在单元B的输入上执行kAudioUnitProperty_SetRenderCallback并且在音频单元A的输出上具有回调函数调用AudioUnitRender相同.

我在设置渲染回调后通过make连接测试了这个,并且不再调用渲染回调.

因此,我能够通过执行以下操作来解决我的问题:

AURenderCallbackStruct callbackStruct = {0};
callbackStruct.inputProc = MyAURenderCallback;
callbackStruct.inputProcRefCon = mixerUnit;

AudioUnitSetProperty(ioUnit,
                     kAudioUnitProperty_SetRenderCallback,
                     kAudioUnitScope_Input,
                     0,
                     &callbackStruct,
                     sizeof(callbackStruct));
Run Code Online (Sandbox Code Playgroud)

而他们我的回调函数做了这样的事情:

OSStatus MyAURenderCallback(void *inRefCon,
                        AudioUnitRenderActionFlags *actionFlags,
                        const AudioTimeStamp *inTimeStamp,
                        UInt32 inBusNumber,
                        UInt32 inNumberFrames,
                        AudioBufferList *ioData) {

    AudioUnit mixerUnit = (AudioUnit)inRefCon;

    AudioUnitRender(mixerUnit,
                    actionFlags,
                    inTimeStamp,
                    0,
                    inNumberFrames,
                    ioData);

    ExtAudioFileWriteAsync(outputFile, 
                           inNumberFrames, 
                           ioData);

    return noErr;
}
Run Code Online (Sandbox Code Playgroud)

这对我来说应该是显而易见的,但是因为不是我敢打赌,其他人也会以同样的方式感到困惑,所以希望这对他们也有帮助.

我仍然不确定为什么我遇到AUGraphAddRenderNotify回调问题.我稍后会深入研究这个问题,但现在我找到了一个似乎有效的解决方案.