I'm on the way to developing a vibrato unit by referring to FilterDemo at AudioUnitV3Example: A Basic AudioUnit Extension and Host Implementation.
In this article, I tried to add parameters.
In the template code of AudioUnit App Extension, it is seemed to add "Parameter 1" parameter as follows:
A myParam1 is defined as// 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];
In FilterDemo, the addresses are defined as enum as:// Define parameter addresses. (These needn't be static).#define myParam1 0
I think any unique values will be OK.enum {FilterParamCutoff = 0,FilterParamResonance = 1};
In my case, I defined the paas follows
Then, I actually added parameters as:typedef NS_ENUM(AUParameterAddress, VibratoParameterAddress) {VibratoParameterAddressFrequency = 0,VibratoParameterAddressDepth = 1};
where, name and identifier strings were defined asAUParameter *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]];
By the way, as for detecting the changes in these parameters from outside, FilterDemo's implementation isNSString *VibratoParameterIdentifierFrequency = @"VibratoParameterIdentifierFrequency";NSString *VibratoParameterIdentifierDepth = @"VibratoParameterIdentifierDepth";NSString *VibratoParameterNameFrequency = @"Frequency";NSString *VibratoParameterNameDepth = @"Depth";
I think this code means that blocks are executed when parameters were set/got.// 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);};
In my case, I implemented as
By the way, it is noted that a block is needed to express these parameters as strings.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;};
In FilterDemo, the implementations are
So, I implemented as follows:// 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 @"?";}};
Finally, parameter setting will be completed.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 @"?";}};
Nextly, I tried to change the parameters from outside.
However, my AudioUnit's UI was not displayed on host applications such as AUV3Host or Hosting AU...
For v3 AudioUnits, custom UIs may be required.
So, before checking parameter changes, I think I'm going to make a custom UI...
That's all for today!!