今回はパラメータを追加してみました。
AudioUnit App Extensionのテンプレートでは
としてParameter 1というパラメータを追加しているようです。// Create parameter objects.AUParameter *param1 = [AUParameterTree createParameterWithIdentifier:@"param1" name:@"Parameter 1" address:myParam1 min:0 max:100 unit:kAudioUnitParameterUnit_Percent unitName:nil flags:0 valueStrings:nil dependentParameters:nil];
addressに指定しているmyParam1というのは
と定義されており、なにやら意味不明ですが、FilterDemoでは// Define parameter addresses. (These needn't be static).#define myParam1 0
とenumを指定しており、連番であれば良いのではないでしょうか。enum {FilterParamCutoff = 0,FilterParamResonance = 1};
ひとまず今回は
と、それっぽくしてみました。typedef NS_ENUM(AUParameterAddress, VibratoParameterAddress) {VibratoParameterAddressFrequency = 0,VibratoParameterAddressDepth = 1};
で、実際にパラメータを以下のように追加しました。
なお、AUParameter *freqParameter = [AUParameterTree createParameterWithIdentifier:VibratoParameterIdentifierFrequencyname:VibratoParameterNameFrequencyaddress:VibratoParameterAddressFrequencymin:0max:1unit:kAudioUnitParameterUnit_HertzunitName:nilflags:0valueStrings:nildependentParameters:nil];freqParameter.value = .0025;self.freq = freqParameter.value;AUParameter *depthParameter = [AUParameterTree createParameterWithIdentifier:VibratoParameterIdentifierDepthname:VibratoParameterNameDepthaddress:VibratoParameterAddressDepthmin:0max:250unit:kAudioUnitParameterUnit_SecondsunitName:nilflags:0valueStrings:nildependentParameters:nil];depthParameter.value = 250;self.depth = depthParameter.value;self.parameterTree = [AUParameterTree createTreeWithChildren:@[freqParameter, depthParameter]];
と定義しました。NSString *VibratoParameterIdentifierFrequency = @"VibratoParameterIdentifierFrequency";NSString *VibratoParameterIdentifierDepth = @"VibratoParameterIdentifierDepth";NSString *VibratoParameterNameFrequency = @"Frequency";NSString *VibratoParameterNameDepth = @"Depth";
で、これらのパラメータを外部から変更をどう感知するかですが、FilterDemoによると、
となっており、パラメータの設定や取得の際にはblockが実行されるようです。// implementorValueObserver is called when a parameter changes value._parameterTree.implementorValueObserver = ^(AUParameter *param, AUValue value) {filterKernel->setParameter(param.address, value);};// implementorValueProvider is called when the value needs to be refreshed._parameterTree.implementorValueProvider = ^(AUParameter *param) {return filterKernel->getParameter(param.address);};
ひとまず今回は
としてみました。MyAudioUnit *unit = self;self.parameterTree.implementorValueObserver = ^(AUParameter *param, AUValue value) {switch (param.address) {case VibratoParameterAddressFrequency:unit.freq = value;break;case VibratoParameterAddressDepth:unit.depth = value;default:break;}};self.parameterTree.implementorValueProvider = ^(AUParameter *param) {switch (param.address) {case VibratoParameterAddressFrequency:return unit.freq;case VibratoParameterAddressDepth:return unit.depth;default:break;}return 0.0f;};
あと、パラメータを文字列として表現するためのblockが必要なようですね。
FilterDemoでは
となっています。// A function to provide string representations of parameter values._parameterTree.implementorStringFromValueCallback = ^(AUParameter *param, const AUValue *__nullable valuePtr) {AUValue value = valuePtr == nil ? param.value : *valuePtr;switch (param.address) {case FilterParamCutoff:return [NSString stringWithFormat:@"%.f", value];case FilterParamResonance:return [NSString stringWithFormat:@"%.2f", value];default:return @"?";}};
これに倣って
としました。self.parameterTree.implementorStringFromValueCallback = ^(AUParameter *param, const AUValue *__nullable valuePtr) {AUValue value = valuePtr == nil ? param.value : *valuePtr;switch (param.address) {case VibratoParameterAddressFrequency:return [NSString stringWithFormat:@"%.f", value];case VibratoParameterAddressDepth:return [NSString stringWithFormat:@"%.0f", value];default:return @"?";}};
ひとまずこれでパラメータの設定は完了したと思います。
実際に外部からパラメータを変えてみようと思ったのですが……
なんと、AUV3HostでもHosting AUでもパラメータ設定用のUIが表示できない… orz
v3のAUだと自前のUIが必要かもしれません。
なので、パラメータの確認の前にUI作りを行いたいと思います…
今回はここまで!