Can't connect converter Audio Unit to Reverb Effect

I am trying to reshape an AUGraph that looks like this:

multichannel mixer -> remote I/O

into something like this:

callback -> converter1 -> bandpass -> reverb -> converter2 -> mixer(bus 0) -> remote I/O

after the graph has been initialized and started (ie, "on the fly"). To allow the stream formats to propagate and the audio units to negotiate the format of each connection, I am appending the newly created audio units in this order:

  • Clear all existing connections ( AUGraphClearConnections() ).
  • Rebuild default connections ( mixer -> remote I/O )
  • Attach converter2 to mixer , bus #0 (converter2 matches its output to mixer: integer)
  • Attach reverb to converter2 (converter1 matches its input to reverb: float)
  • Attach bandpass to reverb (both use float)
  • Attach converter1 to bandpass (converter1 should match its output to bandpass: float)
  • (converter1's input was previously set to integer, manually, using AudioUnitSetProperty )

    ...and finally, connect a render callback to converter #1's input.

    I check the return value (error code) of all Core Audio functions. In addition, after connecting each node, I call AUGraphUpdate() and CAShow() on the graph.

    The final step ("5. Connect converter #1 to bandpass effect"), fails with code -10868 ( kAudioUnitErr_FormatNotSupported ).

    This is the CAShow() output just before the offending call to AUGraphUpdate() :

    AudioUnitGraph 0x305A000:
      Member Nodes:
        node 1: 'aumx' 'mcmx' 'appl', instance 0x17822d0e0 O I
        node 2: 'auou' 'rioc' 'appl', instance 0x17822cd80 O I
        node 3: 'aufc' 'conv' 'appl', instance 0x170833e40 O  
        node 4: 'aufx' 'bpas' 'appl', instance 0x170827b60 O I
        node 5: 'aufx' 'rvb2' 'appl', instance 0x170835100 O I
        node 6: 'aufc' 'conv' 'appl', instance 0x170a21460 O I
      Connections:
        node   1 bus   0 => node   2 bus   0  [ 2 ch,  44100 Hz, 'lpcm' (0x00000C2C) 8.24-bit little-endian signed integer, deinterleaved]
        node   6 bus   0 => node   1 bus   0  [ 2 ch,  44100 Hz, 'lpcm' (0x00000C2C) 8.24-bit little-endian signed integer, deinterleaved]
        node   5 bus   0 => node   6 bus   0  [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]
        node   4 bus   0 => node   5 bus   0  [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]
      CurrentState:
        mLastUpdateError=0, eventsToProcess=F, isInitialized=T, isRunning=T (1)
    

    So, What's going on?

    NOTE the last call to AUGraphConnectNodeInput() itself returns noErr ; It it the graph update after that that throws the error.


    So, the Golden Rule Of Stack Overflow hits again:

    Post a question, and within 5 minutes you will find the answer on your own. But only if you post it!

    Jokes aside, this is how I solved it:

    Before connecting the outer converter #1 (between the source render callback, and the first filter) I grabbed the filter's native stream format, and manually set it to the converters stream format (output scope), like this:

    AudioStreamBasicDescription filterStreamDesc = { 0 };
    
    UInt32 size = sizeof(filterStreamDesc);
    
    // GET
    result = AudioUnitGetProperty(reverbUnit,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Input, // output or global should work, too?
                                  0,
                                  &(filterStreamDesc),
                                  &size);
    
    [self checkAudioResult:result]; // (custom method that compares against noErr)
    
    // SET
    result = AudioUnitSetProperty(converterUnit0,
                                  kAudioUnitProperty_StreamFormat,
                                  kAudioUnitScope_Output,
                                  0,
                                  &(filterStreamDesc),
                                  size);
    
    //(input stream format already set above)
    
    [self checkAudioResult:result]; // (custom method that compares against noErr)
    

    So to sum it up, for some reason I had to directly set both stream formats: input(int) and output (float) before I could connect this converter. The one between the existing multichannel mixer and the new reverb filter somehow manages to set itself up automatically... (still a bit puzzled, but then again... Core Audio, right?)

    链接地址: http://www.djcxy.com/p/62314.html

    上一篇: 在AudioUnit子类型kAudioUnitSubType上设置速率

    下一篇: 无法将转换器音频单元连接至混响效果