加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

iphone – 在向AUGraph添加kAudioUnitSubType_Reverb2时,AUGraph

发布时间:2020-12-14 19:22:15 所属栏目:百科 来源:网络整理
导读:我正在尝试将类型为kAudioUnitSubType_Reverb2的AudioUnit添加到AUGraph,并在AUGraphInitialize上获得-10868(kAudioUnitErr_FormatNotSupported)支持的错误.我的出发点是Apple的iPhoneMixerEQGraphTest示例应用程序,我基本上只是为混响添加了一个新的AudioUn
我正在尝试将类型为kAudioUnitSubType_Reverb2的AudioUnit添加到AUGraph,并在AUGraphInitialize上获得-10868(kAudioUnitErr_FormatNotSupported)支持的错误.我的出发点是Apple的iPhoneMixerEQGraphTest示例应用程序,我基本上只是为混响添加了一个新的AudioUnit,但无法让它工作.

这是代码 –

- (void)initializeAUGraph
{
    printf("initializeAUGraphn");

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

    printf("create client ASBDn");

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

    printf("create output ASBDn");

    // 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 AUGraphn");

    // create a new AUGraph
    result = NewAUGraph(&mGraph);
    if (result) { printf("NewAUGraph result %ld %08X %4.4sn",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 nodesn");

    // 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.4sn",(char*)&result); return; }

    result = AUGraphAddNode(mGraph,&eq_desc,&eqNode);
    if (result) { printf("AUGraphNewNode 2 result %lu %4.4sn",&mixer_desc,&mixerNode);
    if (result) { printf("AUGraphNewNode 3 result %lu %4.4sn",&reverb_desc,&reverbNode);
    if (result) { printf("AUGraphNewNode 4 result %lu %4.4sn",(char*)&result); return; }

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

    result = AUGraphConnectNodeInput(mGraph,reverbNode,outputNode,0);
    if (result) { printf("AUGraphConnectNodeInput reverb result %lu %4.4sn",(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.4sn",(char*)&result); return; }

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

    result = AUGraphNodeInfo(mGraph,&mEQ);
    if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4sn",&mReverb);
    if (result) { printf("AUGraphNodeInfo reverb result %ld %08X %4.4sn",(char*)&result); return; }

    // set bus count
    UInt32 numbuses = 2;

    printf("set input bus count %lun",numbuses);

    result = AudioUnitSetProperty(mMixer,kAudioUnitProperty_ElementCount,kAudioUnitScope_Input,&numbuses,sizeof(numbuses));
    if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4sn",(char*)&result); return; }

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

        printf("set AUGraphSetNodeInputCallbackn");

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

        printf("set input bus %d,client kAudioUnitProperty_StreamFormatn",i);

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

    printf("get EQ kAudioUnitProperty_FactoryPresetsn");

    // get the eq's 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,&mEQPresetsArray,&size);
    if (result) { printf("AudioUnitGetProperty result %ld %08X %4.4sn",(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_StreamFormatn");

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

    printf("set render notificationn");

    // 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.4sn",(char*)&result); return; }

    printf("AUGraphInitializen");

    // 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.4sn",(char*)&result); return; }
    // ---- result here is error code 10868

    CAShow(mGraph);
}

解决方法

出于某种原因,一些AU节点默认采用float格式的流格式,而其他节点则采用整数形式.如果流格式不匹配,则会出现此错误.因此,您需要在均衡器节点和混响节点之间添加格式转换器:

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);

确保将转换器节点输入的流格式设置为均衡器节点输出的格式:

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

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

并对转换器的输出执行相同操作,使用混响的输入格式进行设置.这应该使您的图形初始化并运行,但是如果您设法使混响节点实际上做某事,请告诉我,因为它对我不起作用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读