AUGraph Analyze error code -10868 when adding kAudioUnitSubType_Reverb2 to AUGraph

I am trying to add an AudioUnit type kAudioUnitSubType_Reverb2in AUGraphand get a -10868 (kAudioUnitErr_FormatNotSupported)supported error on AUGraphInitialize. My starting point was the Apple iPhoneMixerEQGraphTest app, I just added a new AudioUnit for reverb, but I can't get it to work.

Here is the code -

- (void)initializeAUGraph
{
    printf("initializeAUGraph\n");

    AUNode outputNode;
    AUNode eqNode;
    AUNode mixerNode;
    AUNode reverbNode;

    printf("create client ASBD\n");

    // client format audio goes into the mixer
    mClientFormat.SetCanonical(2, true);                        
    mClientFormat.mSampleRate = kGraphSampleRate;
    mClientFormat.Print();

    printf("create output ASBD\n");

    // output format
    mOutputFormat.SetAUCanonical(2, false);                     
    mOutputFormat.mSampleRate = kGraphSampleRate;
    mOutputFormat.Print();

    OSStatus result = noErr;

    // load up the audio data
    [self performSelectorInBackground:@selector(loadFiles) withObject:nil];

    printf("new AUGraph\n");

    // create a new AUGraph
    result = NewAUGraph(&mGraph);
    if (result) { printf("NewAUGraph result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    // create three CAComponentDescription for the AUs we want in the graph

    // output unit
    CAComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple);

    // iPodEQ unit
    CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple);

    // multichannel mixer unit
    CAComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple);

    // reverb unit
    CAComponentDescription reverb_desc(kAudioUnitType_Effect, kAudioUnitSubType_Reverb2, kAudioUnitManufacturer_Apple);

    printf("add nodes\n");

    // create a node in the graph that is an AudioUnit, using the supplied AudioComponentDescription to find and open that unit
    result = AUGraphAddNode(mGraph, &output_desc, &outputNode);
    if (result) { printf("AUGraphNewNode 1 result %lu %4.4s\n", result, (char*)&result); return; }

    result = AUGraphAddNode(mGraph, &eq_desc, &eqNode);
    if (result) { printf("AUGraphNewNode 2 result %lu %4.4s\n", result, (char*)&result); return; }

    result = AUGraphAddNode(mGraph, &mixer_desc, &mixerNode);
    if (result) { printf("AUGraphNewNode 3 result %lu %4.4s\n", result, (char*)&result); return; }

    result = AUGraphAddNode(mGraph, &reverb_desc, &reverbNode);
    if (result) { printf("AUGraphNewNode 4 result %lu %4.4s\n", result, (char*)&result); return; }

    // connect a node output to a node input
    // mixer -> eq -> output
    result = AUGraphConnectNodeInput(mGraph, mixerNode, 0, eqNode, 0);
    if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result, (char*)&result); return; }

    result = AUGraphConnectNodeInput(mGraph, eqNode, 0, reverbNode, 0);
    if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result, (char*)&result); return; }

    result = AUGraphConnectNodeInput(mGraph, reverbNode, 0, outputNode, 0);
    if (result) { printf("AUGraphConnectNodeInput reverb result %lu %4.4s\n", result, (char*)&result); return; }

    // open the graph AudioUnits are open but not initialized (no resource allocation occurs here)
    result = AUGraphOpen(mGraph);
    if (result) { printf("AUGraphOpen result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    // grab the audio unit instances from the nodes
    result = AUGraphNodeInfo(mGraph, mixerNode, NULL, &mMixer);
    if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    result = AUGraphNodeInfo(mGraph, eqNode, NULL, &mEQ);
    if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    result = AUGraphNodeInfo(mGraph, reverbNode, NULL, &mReverb);
    if (result) { printf("AUGraphNodeInfo reverb result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    // set bus count
    UInt32 numbuses = 2;

    printf("set input bus count %lu\n", numbuses);

    result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_ElementCount, kAudioUnitScope_Input, 0, &numbuses, sizeof(numbuses));
    if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    for (int i = 0; i < numbuses; ++i) {
        // setup render callback struct
        AURenderCallbackStruct rcbs;
        rcbs.inputProc = &renderInput;
        rcbs.inputProcRefCon = &mUserData;

        printf("set AUGraphSetNodeInputCallback\n");

        // set a callback for the specified node specified input
        result = AUGraphSetNodeInputCallback(mGraph, mixerNode, i, &rcbs);
        if (result) { printf("AUGraphSetNodeInputCallback result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

        printf("set input bus %d, client kAudioUnitProperty_StreamFormat\n", i);

        // set the input stream format, this is the format of the audio for mixer input
        result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, i, &mClientFormat, sizeof(mClientFormat));
        if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }
    }

    printf("get EQ kAudioUnitProperty_FactoryPresets\n");

    // get the eq factory preset list -- this is a read-only CFArray array of AUPreset structures
    // host owns the retuned array and should release it when no longer needed
    UInt32 size = sizeof(mEQPresetsArray);
    result = AudioUnitGetProperty(mEQ, kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, &mEQPresetsArray, &size);
    if (result) { printf("AudioUnitGetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    /* this code can be used if you're interested in dumping out the preset list
    printf("iPodEQ Factory Preset List:\n");
    UInt8 count = CFArrayGetCount(mEQPresetsArray);
    for (int i = 0; i < count; ++i) {
        AUPreset *aPreset = (AUPreset*)CFArrayGetValueAtIndex(mEQPresetsArray, i);
        CFShow(aPreset->presetName);
    }*/

    printf("set output kAudioUnitProperty_StreamFormat\n");

    // set the output stream format of the mixer
    result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &mOutputFormat, sizeof(mOutputFormat));
    if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    printf("set render notification\n");

    // add a render notification, this is a callback that the graph will call every time the graph renders
    // the callback will be called once before the graph’s render operation, and once after the render operation is complete
    result = AUGraphAddRenderNotify(mGraph, renderNotification, &mUserData);
    if (result) { printf("AUGraphAddRenderNotify result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }

    printf("AUGraphInitialize\n");

    // now that we've set everything up we can initialize the graph, this will also validate the connections
    result = AUGraphInitialize(mGraph);
    if (result) { printf("AUGraphInitialize result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }
    // ---- result here is error code 10868

    CAShow(mGraph);
}
+5
source share
1 answer

For some reason, some AU nodes accept the default stream format in float, while others accept it in integers. If the stream formats do not match, you get this error. Therefore, you need to add a format converter between your equalizer node and your node reverb:

    AudioComponentDescription convertUnitDescription;
convertUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
convertUnitDescription.componentType          = kAudioUnitType_FormatConverter;
convertUnitDescription.componentSubType       = kAudioUnitSubType_AUConverter;
convertUnitDescription.componentFlags         = 0;
convertUnitDescription.componentFlagsMask     = 0;
result = AUGraphAddNode (graph, &convertUnitDescription, &convertNode);
NSCAssert (result == noErr, @"Unable to add the converted unit to the audio processing graph. Error code: %d '%.4s'", (int) result, (const char *)&result);

, node node:

    AudioStreamBasicDescription eqStreamFormat;
UInt32 streamFormatSize = sizeof(eqStreamFormat);
result = AudioUnitGetProperty(eqUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &eqStreamFormat, &streamFormatSize);
NSAssert (result == noErr, @"Unable to get eq output format. Error code: %d '%.4s'", (int) result, (const char *)&result);

result = AudioUnitSetProperty(convertUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &eqStreamFormat, streamFormatSize);
NSAssert (result == noErr, @"Unable to set converter input format. Error code: %d '%.4s'", (int) result, (const char *)&result);

, . , , node - , .

+4

All Articles