在AUAudioUnit v3上使用来自主机的AUScheduleParameterBlock

时间:2016-03-15 15:47:01

标签: ios ios9 core-audio audiounit avaudioengine

我是新的AUAudioUnits并试图了解如何使用v3 API。我正在尝试在kAudioUnitSubType_MultiChannelMixer AUAudioUnit上安排参数更改,以便我可以随时间推移增加更改。 我可以使用滑块直接设置增益,并且更改会立即生效:

/*...*/
// Inside my ViewController

  @IBAction func slider1Changed(sender: UISlider) {
    player.gainParameter.setValue(sender.value, originator: nil)
  }

// Inside my AudioPlayerClass

    guard let parameterTree = self.multichannelMixer.parameterTree else {
      print("Param Tree")
      return
    }

    self.gainParameter = parameterTree.parameterWithID(
      kMultiChannelMixerParam_Volume,
      scope: kAudioUnitScope_Input,
      element: 0)

但是当我尝试使用scheduleParameterBlock将其添加到上面的AudioPlayerClass时,我希望增益在10秒内从1增加到0,但没有变化:

    let scheduleMixerParamBlock = self.multichannelMixer.scheduleParameterBlock
    let rampTime = AUAudioFrameCount(10.secondsToSampleFrames)
    scheduleMixerParamBlock(AUEventSampleTimeImmediate, rampTime, self.gainParameter.address, 0)

我在苹果示例中看到它的例子包括这样的代码(没有dispatch_async部分):

parameterTree.implementorValueObserver = {param, value in
  dispatch_async(dispatch_get_main_queue()) {
    print(param, value)
  }
  scheduleMixerParamBlock(AUEventSampleTimeImmediate, rampTime, param.address, value)
}

当我运行此操作并使用滑块更改增益参数时,将运行该块,paramvalue将以正确的值显示在控制台上但增益不会更改实际的音频。 我见过的这些例子也是定制的AUAudioUnits,其中实现者可以直接访问dspKernel函数,所以我可能会遗漏那里至关重要的东西。 另一种选择我必须计算一系列斜坡值,然后直接为每个值设置增益参数,但由于scheduleParameterBlock似乎我应该能够使用它。任何帮助都会很棒。感谢

1 个答案:

答案 0 :(得分:0)

您必须查看在音频渲染线程上运行的 AURenderEvent 中的 internalRenderBlock 头。您的预定参数事件将出现在那里供您响应。

例如,将头部传递给这个函数:

void doEvents(AURenderEvent const* event)
    {
        while (event != nullptr) {
            switch (event->head.eventType) {
                case AURenderEventParameter:
                    doParameterEvent(event->parameter);
                    break;
                default:
                    break;
            }
            event = event->head.next;
        }
    }

void doParameterEvent(AUParameterEvent const &event) {
        switch (event.parameterAddress) {
            case FilterParameterAddressFoo:
                doFoo();
                break;
            case FilterParameterAddressBar:
                doBar();
                break;
            default:
                break;
        }
    }