如何正确配置AVAudioUnitEffects链

时间:2015-10-05 12:11:47

标签: ios xcode xamarin avaudioengine

以下代码将iOS音频引擎配置为创建使用一种声音字体设置的采样器(为了简化讨论)。然后我使用这些样本播放MIDI音符,一切正常,直到我尝试引入一系列标准效果(失真 - >延迟 - >混响)。

如果采样器的输出只是直接连接到音频引擎MainMixerNode,它就可以工作。如果我将采样器连接到失真效果(链中的第一个效果),那么一旦我尝试播放第一个MIDI音符,我就会收到错误“AVAudioUnitMIDIInstrument.mm:103: - [AVAudioUnitMIDIInstrument startNote:withVelocity:onChannel:]:错误-10867“

注意:我在Mac上使用Xamarin进行编码,因此以下内容可能看起来不太熟悉,但我希望代码的可读性足以让您提供帮助。

问题在于我在初始化我的影响/或其链条时出错了吗?

提前致谢, 克里斯

    private void InitAudioEngine(NSUrl sampleFileUrl)
    {
        AVAudioSession.SharedInstance().Init ();

        NSError sessionErrorCode;
        sessionErrorCode = AVAudioSession.SharedInstance ().SetCategory (AVAudioSessionCategory.Playback);
        if(sessionErrorCode != null)
            Logger.Write ("Failed to set AudioSession category");

        sessionErrorCode = AVAudioSession.SharedInstance ().SetActive (true);
        if(sessionErrorCode != null)
            Logger.Write ("Failed to activate AudioSession");

        Logger.Write ("Instantiate Audio Engine");

        _audioEngine = new AVAudioEngine ();
        _samplers = new List<AVAudioUnitSampler> ();

        var distortion = new AVAudioUnitDistortion ();
        var delay = new AVAudioUnitDelay ();
        var reverb = new AVAudioUnitReverb ();

        distortion.Init ();
        delay.Init ();
        reverb.Init ();

        distortion.LoadFactoryPreset (AVAudioUnitDistortionPreset.SpeechGoldenPi);
        reverb.LoadFactoryPreset (AVAudioUnitReverbPreset.LargeHall2);

        delay.DelayTime = 300;
        delay.WetDryMix = 30;
        delay.Feedback = 30;

        _audioEngine.AttachNode (distortion);
        _audioEngine.AttachNode (delay);
        _audioEngine.AttachNode (reverb);

        _audioEngine.Connect (distortion, delay, delay.GetBusOutputFormat (0));
        _audioEngine.Connect (delay, reverb, reverb.GetBusOutputFormat (0));
        _audioEngine.Connect (reverb, _audioEngine.MainMixerNode, _audioEngine.MainMixerNode.GetBusOutputFormat (0));

        for (int index = 0; index < 15; index++) 
        {
            var sampler = new AVAudioUnitSampler ();
            sampler.Init ();

            _samplers.Add (sampler);
            _audioEngine.AttachNode (sampler);
            _audioEngine.Connect (sampler, distortion, distortion.GetBusOutputFormat(0));
        }

        // Connect all the samplers to a defined SoundFont
        ConnectSoundbank (sampleFileUrl);

        NSError engineErrorCode;
        _audioEngine.StartAndReturnError (out engineErrorCode);

        if(engineErrorCode != null)
            Logger.Write ("Failed to start AudioEngine after samplers attached");
    }

// ...
// Later code
// Play a MIDI note on one of the samplers configured above
//
_samplers[0].StartNote(58,127,0); // Crashes with error -10867 (uninitialised)
//...etc...

1 个答案:

答案 0 :(得分:0)

这里的问题是尝试为每个效果提供多个​​采样器。您似乎需要为每个采样器创建延迟/混响/失真。

基本上信号链需要是采样器 - &gt;失真 - &gt;延迟 - &gt;混响 - &gt;混合器。

在上面的陈述中有一些假设,如果你可以在延迟上使用多个输入总线将多个采样器连接到延迟,则可能是错误的。但是我无法在这种程度上进行测试。

一旦我使用了一对一的映射,我的代码就可以了。

因此必须在循环内创建并连接AvAudioUnitXXXX效果。