Next, you define the audio unit factory presets, again by editing the source files for the audio unit custom subclass, TremoloUnit.h and TremoloUnit.cpp.
The steps, described in detail below, are:
Name the factory presets and give them values.
Modify the TremoloUnit class declaration by adding method signatures for handling factory presets.
Edit the audio unit’s constructor method to set a default factory preset.
Override the GetPresets method to set up a factory presets array.
Override the NewFactoryPresetSet method to define the factory presets.
Note: The work you do here does not make use of the factory presets, per se. It is the DSP code that you implement in “Implement Signal Processing” that makes use of the presets. Here, you are simply defining the presets so that they will appear in the audio unit generic view and so that they're ready to use when you implement the DSP code.
Name the Factory Presets and Give Them Values
Add Method Declarations for Factory Presets
Set the Default Factory Preset
Implement the GetPresets Method
Define the Factory Presets
Define the constants for the factory presets. A convenient location for this code in the TremoloUnit.h header file is below the parameter constants section.
Listing 5-5 Factory preset names and values (TremoloUnit.h)
#pragma mark ____TremoloUnit Factory Preset Constants |
static const float kParameter_Preset_Frequency_Slow = 2.0; // 1 |
static const float kParameter_Preset_Frequency_Fast = 20.0; // 2 |
static const float kParameter_Preset_Depth_Slow = 50.0; // 3 |
static const float kParameter_Preset_Depth_Fast = 90.0; // 4 |
static const float kParameter_Preset_Waveform_Slow // 5 |
= kSineWave_Tremolo_Waveform; |
static const float kParameter_Preset_Waveform_Fast // 6 |
= kSquareWave_Tremolo_Waveform; |
enum { |
kPreset_Slow = 0, // 7 |
kPreset_Fast = 1, // 8 |
kNumberPresets = 2 // 9 |
}; |
static AUPreset kPresets [kNumberPresets] = { // 10 |
{kPreset_Slow, CFSTR ("Slow & Gentle")}, |
{kPreset_Fast, CFSTR ("Fast & Hard")} |
}; |
static const int kPreset_Default = kPreset_Slow; // 11 |
Here’s how this code works:
Defines a constant for the frequency value for the “Slow & Gentle” factory preset.
Defines a constant for the frequency value for the “Fast & Hard” factory preset.
Defines a constant for the depth value for the “Slow & Gentle; Hard” factory preset.
Defines a constant for the depth value for the “Fast & Hard” factory preset.
Defines a constant for the waveform value for the “Slow & Gentle” factory preset.
Defines a constant for the waveform value for the “Fast & Hard” factory preset.
Defines a constant for the “Slow & Gentle” factory preset.
Defines a constant for the “Fast & Hard” factory preset.
Defines a constant representing the total number of factory presets.
Defines an array containing two Core Foundation string objects. The objects contain values for the menu items in the user interface corresponding to the factory presets.
Defines a constant representing the default factory preset, in this case the “Slow & Gentle” preset.
Now, provide method declarations for overriding the GetPresets and NewFactoryPresetSet methods from the AUBase superclass. Add these method declarations to the public: portion of class declaration in the TremoloUnit.h header file. You implement these methods in a later step in this chapter.
Listing 5-6 Factory preset method declarations (TremoloUnit.h)
#pragma mark ____TremoloUnit |
class TremoloUnit : public AUEffectBase { |
public: |
TremoloUnit (AudioUnit component); |
... |
virtual ComponentResult GetPresets ( // 1 |
CFArrayRef *outData |
) const; |
virtual OSStatus NewFactoryPresetSet ( // 2 |
const AUPreset &inNewFactoryPreset |
); |
protected: |
... |
}; |
Here’s how this code works:
Declaration for the GetPresets method, overriding the method from the AUBase superclass.
Declaration for the NewFactoryPresetSet method, overriding the method from the AUBase superclass.
Now you return to the TremoloUnit constructor method, in which you previously added code for setting the audio unit parameters. Here, you add a single statement to set the default factory preset, making use of the kTremoloPreset_Default constant.
Listing 5-7 Setting the default factory preset in the constructor (TremoloUnit.cpp)
TremoloUnit::TremoloUnit (AudioUnit component) : AUEffectBase (component) { |
CreateElements (); |
Globals () -> UseIndexedParameters (kNumberOfParameters); |
// code for setting default values for the audio unit parameters |
SetAFactoryPresetAsCurrent ( // 1 |
kPresets [kPreset_Default] |
); |
// boilerplate code for debug dispatcher |
} |
Here’s how this code works:
Sets the default factory preset.
For users to be able to use the factory presets you define, you must add a generic implementation of the GetPresets method. The following generic code works for any audio unit that can support factory presets.
A convenient location for this code in the TremoloUnit.cpp implementation file is after the GetPropertyInfo and GetProperty methods.
Note: You can refer to “Control Code: Parameters, Factory Presets, and Properties” for an architectural description of the GetPresets method, and how it fits into audio unit operation.
Listing 5-8 Implementing the GetPresets method (TremoloUnit.cpp)
#pragma mark ____Factory Presets |
ComponentResult TremoloUnit::GetPresets ( // 1 |
CFArrayRef *outData |
) const { |
if (outData == NULL) return noErr; // 2 |
CFMutableArrayRef presetsArray = CFArrayCreateMutable ( // 3 |
NULL, |
kNumberPresets, |
NULL |
); |
for (int i = 0; i < kNumberPresets; ++i) { // 4 |
CFArrayAppendValue ( |
presetsArray, |
&kPresets [i] |
); |
} |
*outData = (CFArrayRef) presetsArray; // 5 |
return noErr; |
} |
Here’s how this code works:
The GetPresets method accepts a single parameter, a pointer to a CFArrayRef object. This object holds the factory presets array generated by this method.
Checks whether factory presets are implemented for this audio unit.
Instantiates a mutable Core Foundation array to hold the factory presets.
Fills the factory presets array with values from the definitions in the TremoloUnit.h file.
Stores the factory presets array at the outData location.
The NewFactoryPresetSet method defines all the factory presets for an audio unit. Basically, for each preset, it invokes a series of SetParameter calls.
A convenient location for this code in the TremoloUnit.cpp implementation file is after the implementation of the GetPresets method.
Listing 5-9 Defining factory presets in the NewFactoryPresetSet method (TremoloUnit.cpp)
OSStatus TremoloUnit::NewFactoryPresetSet ( // 1 |
const AUPreset &inNewFactoryPreset |
) { |
SInt32 chosenPreset = inNewFactoryPreset.presetNumber; // 2 |
if ( // 3 |
chosenPreset == kPreset_Slow || |
chosenPreset == kPreset_Fast |
) { |
for (int i = 0; i < kNumberPresets; ++i) { // 4 |
if (chosenPreset == kPresets[i].presetNumber) { |
switch (chosenPreset) { // 5 |
case kPreset_Slow: // 6 |
SetParameter ( // 7 |
kParameter_Frequency, |
kParameter_Preset_Frequency_Slow |
); |
SetParameter ( // 8 |
kParameter_Depth, |
kParameter_Preset_Depth_Slow |
); |
SetParameter ( // 9 |
kParameter_Waveform, |
kParameter_Preset_Waveform_Slow |
); |
break; |
case kPreset_Fast: // 10 |
SetParameter ( |
kParameter_Frequency, |
kParameter_Preset_Frequency_Fast |
); |
SetParameter ( |
kParameter_Depth, |
kParameter_Preset_Depth_Fast |
); |
SetParameter ( |
kParameter_Waveform, |
kParameter_Preset_Waveform_Fast |
); |
break; |
} |
SetAFactoryPresetAsCurrent ( // 11 |
kPresets [i] |
); |
return noErr; // 12 |
} |
} |
} |
return kAudioUnitErr_InvalidProperty; // 13 |
} |
Here’s how this code works:
This method takes a single argument of type AUPreset, a structure containing a factory preset name and number.
Gets the number of the desired factory preset.
Tests whether the desired factory preset is defined.
This for loop, and the if statement that follows it, allow for noncontiguous preset numbers.
Selects the appropriate case statement based on the factory preset number.
The settings for the “Slow & Gentle” factory preset.
Sets the Frequency audio unit parameter for the “Slow & Gentle” factory preset.
Sets the Depth audio unit parameter for the “Slow & Gentle” factory preset.
Sets the Waveform audio unit parameter for the “Slow & Gentle” factory preset.
The settings for the “Fast & Hard” factory preset. The three SetParameter statements that follow work the same way as for the other factory preset.
Updates the preset menu in the generic view to display the new factory preset.
On success, returns a value of noErr.
If the host application attempted to set an undefined factory preset, return an error.
Last updated: 2007-10-31