objective-cavfoundationcore-audio

Crash when connecting an AVAudioSinkNode to my AVAudioEngine


I have tried to get audio input (and output at the same time) using the AVAudioSourceNode and AVAudioSinkNode. The problem is, I haven't been able to find a proper sample on how to set it up, even on Apple's website. I do basically this:

AVAudioEngine* m_engine = [AVAudioEngine new];
AVAudioSession* m_avSession = AVAudioSession.sharedInstance;

if (![m_avSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error] ||
    ![m_avSession setActive:true withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error])
{
    m_logger.Error("Could not activate Audio Session: ", error.description);
}

AVAudioSinkNode* CreateInputNode(AVAudioFormat* format)
{
    AVAudioSinkNodeReceiverBlock block = [checker, format] (const AudioTimeStamp* timestamp, AVAudioFrameCount frameCount, const AudioBufferList* inputData) {
        ProcessAudioForInput(format, inputData, frameCount);
        return OSStatus(noErr);
    };
    return [[AVAudioSinkNode alloc] initWithReceiverBlock:block];
}

AVAudioSessionRouteDescription* route = m_avSession.currentRoute;
AVAudioFormat* inputFormat = [m_engine.inputNode inputFormatForBus:FIRST_AUDIO_BUS];
auto sinkNode = CreateInputNode(inputFormat);
if (sinkNode) {
    [m_engine attachNode:sinkNode];
    [m_engine connect:sinkNode to:m_engine.inputNode format:inputFormat];
    channelCount = inputFormat.channelCount;
}
else {
    m_logger.Error("Could not create input node");
}

The [m_engine connect:sinkNode line generates an exception, which I have strictly no idea how to debug:

*** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: inSrcImpl->NumberOutputs() > 0'

Could anyone help or point me to proper resources explaining how to set this up, instead of going blind. Note that I have watched some videos from the WWC, like https://developer.apple.com/videos/play/wwdc2019/510/ but the source code and explanations are not helping me solve this problem.


Solution

  • I think you've got your arrows reversed, it should be

    inputNode -> sinkNode

    not

    sinkNode -> inputNode,

    so try this instead

    [m_engine connect: m_engine.inputNode to:sinkNode format:inputFormat];