Attention! Translated article might be found on my English blog.

2016年8月4日木曜日

自作v3 AudioUnitのAUGenericViewを作りたかった

タイトルの通り、自作v3 AudioUnitのAUGenericViewを作りたかったのですが、できませんでした。
なぜなら、AUGenericViewのイニシャライザにはAudioUnitインスタンスが必要だからです。
私が調べた限りでは、AUAudioUnitオブジェクトからAudioUnitインスタンスを取得する方法が見つかりませんでした。

一方、AVAudioUnitオブジェクトであれば、そのaudioUnitプロパティでAudioUnitインスタンを取得できます。

というわけで、適当にホストアプリを作り、AUGenericViewをつくってみました。
コードは以下の通りです。
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    AudioComponentDescription desc;
    desc.componentType = 'aufx';
    desc.componentSubType = 'vbrt';
    desc.componentManufacturer = 'Symi';
    [AVAudioUnit instantiateWithComponentDescription:desc
                                             options:0
                                   completionHandler:^(__kindof AVAudioUnit * _Nullable audioUnit, NSError * _Nullable error) {
                                       self.unit = audioUnit;
                                       AudioUnit unit = [audioUnit audioUnit];
                                       AUGenericView *view = [[AUGenericView alloc] initWithAudioUnit:unit];
                                       view.frame = self.window.contentView.frame;
                                       [self.window.contentView addSubview:view];
                                   }];
}
結果、


ビューはできたものの、パラメータが表示されませんでした。
FilterDemoとの比較の結果、AUParameter作成時に以下のようにflags:kAudioUnitParameterFlag_IsReadableとkAudioUnitParameterFlag_IsWritableを指定するようにしました。

AUParameter *freqParameter = [AUParameterTree createParameterWithIdentifier:VibratoParameterIdentifierFrequency
                                                                           name:VibratoParameterNameFrequency
                                                                        address:VibratoParameterAddressFrequency
                                                                            min:0
                                                                            max:.01
                                                                           unit:kAudioUnitParameterUnit_Hertz
                                                                       unitName:nil
                                                                          flags:kAudioUnitParameterFlag_IsReadable | kAudioUnitParameterFlag_IsWritable
                                                                   valueStrings:nil
                                                            dependentParameters:nil];
その後、再び確認してみると 、
期待通りDepthとFrequencyを変更できるようになりました!

なお、Depthをwritableのみ、Frequencyをreadableのみにしてみると、
以下の画像のようになりました。
Depthにはスライダーが付いているものの、Frequencyは変更できないようでした。
なるほどー。

まとめ、

  • ホスト側では、v3 のAudioUnitのgeneric viewが欲しい場合、AVAudioUnitオブジェクトからAudioUnitインスタンスを取得する
  • クライアント側では、AUParameter生成の際にflagsとしてkAudioUnitParameterFlag_IsReadable | kAudioUnitParameterFlag_IsWritable を指定する。
以上です。