以编程方式获取AVAudioEngineGraph

时间:2018-10-19 17:13:01

标签: ios objective-c avfoundation core-audio

在我的应用中,我创建了一个AVAudioEngine并在其上附加了AVAudioNodes。

  • 是否可以通过编程方式获取连接的节点?
  • 是否可以将节点连接到给定的AVAudioNode?

当我记录引擎的描述时,我可以看到所有的AVAudioEngineGraph,但是我找不到以编程方式获取此信息的方法,有人可以给我解决方案吗?

(lldb) po _engine

________ GraphDescription ________
AVAudioEngineGraph 0x7fb04541ac60: initialized = 1, running = 1, number of nodes = 4

 ******** output chain ********

 node 0x600002448c00 {'auou' 'rioc' 'appl'}, 'I'
     inputs = 1
         (bus0, en1) <- (bus0) 0x60000244cd00, {'aumx' 'mcmx' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]

 node 0x60000244cd00 {'aumx' 'mcmx' 'appl'}, 'I'
     inputs = 1
         (bus0, en1) <- (bus0) 0x600002473680, {'aumx' 'mcmx' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]
     outputs = 1
         (bus0, en1) -> (bus0) 0x600002448c00, {'auou' 'rioc' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]

 node 0x600002473680 {'aumx' 'mcmx' 'appl'}, 'I'
     inputs = 1
         (bus0, en1) <- (bus1) 0x600002462580, {'auou' 'rioc' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]
     outputs = 1
         (bus0, en1) -> (bus0) 0x60000244cd00, {'aumx' 'mcmx' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]

 node 0x600002462580 {'auou' 'rioc' 'appl'}, 'I'
     outputs = 2
         (bus0, en0) -> (bus0) 0x0, {}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]
         (bus1, en1) -> (bus0) 0x600002473680, {'aumx' 'mcmx' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]

 ******** input chain ********

 node 0x600002462580 {'auou' 'rioc' 'appl'}, 'I'
     outputs = 2
         (bus0, en0) -> (bus0) 0x0, {}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]
         (bus1, en1) -> (bus0) 0x600002473680, {'aumx' 'mcmx' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]

 node 0x600002473680 {'aumx' 'mcmx' 'appl'}, 'I'
     inputs = 1
         (bus0, en1) <- (bus1) 0x600002462580, {'auou' 'rioc' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]
     outputs = 1
         (bus0, en1) -> (bus0) 0x60000244cd00, {'aumx' 'mcmx' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]

 node 0x60000244cd00 {'aumx' 'mcmx' 'appl'}, 'I'
     inputs = 1
         (bus0, en1) <- (bus0) 0x600002473680, {'aumx' 'mcmx' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]
     outputs = 1
         (bus0, en1) -> (bus0) 0x600002448c00, {'auou' 'rioc' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]

 node 0x600002448c00 {'auou' 'rioc' 'appl'}, 'I'
     inputs = 1
         (bus0, en1) <- (bus0) 0x60000244cd00, {'aumx' 'mcmx' 'appl'}, [ 2 ch,  44100 Hz, 'lpcm' (0x00000029) 32-bit little-endian float, deinterleaved]

1 个答案:

答案 0 :(得分:0)

为了管理自定义初始化,我为要加载的每个类别(或特定的)audioUnit创建了audioUnit包装器。这些包装器由工厂提供,并由我的应用程序的业务对象引用。

我到目前为止主要研究的包装器是所谓的AUMIDISynth

componentType = kAudioUnitType_MusicDevice;
componentSubType = kAudioUnitSubType_MIDISynth;
componentManufacturer = kAudioUnitManufacturer_Apple;

允许同时从soundBank文件加载和播放不同的音色。

AUMIDISynth的子类包装器公开了一个名为

的方法
-(NSError*)loadProgramChange:(uint8_t)programChange channel:(uint8_t)channel;

其他对象(SynthPlayers)观察从AudioEngine启动发送的通知,并通过将上述方法调用到自己的实现如下的audioUnit包装器来响应此通知

-(NSError*)loadProgramChange:(uint8_t)programChange channel:(uint8_t)channel{  
    NSError *error;
    if (!self.audioUnit.engine || !self.audioUnit.engine.isRunning) {
        error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:nil];
    }
    uint32_t enabled = 1;
    OSStatus status = AudioUnitSetProperty(
                                           self.audioUnit.audioUnit,
                                           kAUMIDISynthProperty_EnablePreload,
                                           kAudioUnitScope_Global,
                                           0,
                                           &enabled,
                                           sizeof(enabled));
    if (status != noErr) {
        NSLog(@"error %d",status);
        error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:nil];
    }
    uint8_t pcCommand = 0xC0 | channel;
    status = MusicDeviceMIDIEvent(self.audioUnit.audioUnit, pcCommand, programChange, 0, 0);
    if (status != noErr) {
        NSLog(@"error %d",status);
        error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:nil];
    }

    enabled = 0;
    status = AudioUnitSetProperty(
                                  self.audioUnit.audioUnit,
                                  kAUMIDISynthProperty_EnablePreload,
                                  kAudioUnitScope_Global,
                                  0,
                                  &enabled,
                                  sizeof(enabled));
    if (status != noErr) {
        NSLog(@"error %d",status);
        error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:nil];
    }
    return error;
}