2

私は新しい AUAudioUnits で、v3 API の使用方法を理解しようとしています。kAudioUnitSubType_MultiChannelMixerAUAudioUnitでパラメーターの変更をスケジュールして、時間の経過とともにゲインの変更を増やすことができるようにしようとしています。スライダーを使用してゲインを直接設定することができ、変更は次のようにすぐに反映されます。

/*...*/
// 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れ、正しい見た目の値でコンソールに出力されますが、実際のオーディオではゲインは変更されません。私が見たこれらの例は、実装者が dspKernel 関数に直接アクセスできるカスタム AUAudioUnits にもあるため、重要なものが欠落している可能性があります。もう 1 つの方法は、一連のランプ値を計算してから、各値のゲイン パラメータを直接設定する必要がありますが、あるので、それscheduleParameterBlockを使用できるはずです。どんな助けでも素晴らしいでしょう。ありがとう

4

1 に答える 1

1

オーディオ レンダリング スレッドで動作しているのAURenderEventヘッドを確認する必要があります。internalRenderBlockスケジュールされたパラメーター イベントがそこに表示され、応答することができます。

たとえば、次の関数に head を渡します。

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;
        }
    }
于 2021-06-28T00:30:01.317 に答える