Okay, it took some painful digging through apple’s woeful documentation to figure this out, but the problem is that AudioUnitSetParameter does not notify the plugin’s editor that a parameter has changed. To fix it, I’ve made the following changes to juce_AudioUnitPluginFormat.mm:
[code]void setParameter (int index, float newValue)
{
const ScopedLock sl (lock);
if (audioUnit != 0 && isPositiveAndBelow (index, parameterIds.size()))
{
AudioUnitEvent ev;
AudioUnitSetParameter (audioUnit,
(UInt32) parameterIds.getUnchecked (index),
kAudioUnitScope_Global, 0,
newValue, 0);
ev.mEventType = kAudioUnitEvent_ParameterValueChange;
ev.mArgument.mParameter.mAudioUnit = audioUnit;
ev.mArgument.mParameter.mParameterID = (UInt32) parameterIds.getUnchecked (index);
ev.mArgument.mParameter.mScope = kAudioUnitScope_Global;
ev.mArgument.mParameter.mElement = 0;
//Notify any listeners (i.e. the plugin's editor) that the parameter's been changed.
AUEventListenerNotify(NULL, NULL, &ev);
}
}
[/code]
And then to get the editor to update when the preset is changed, I did this (it’s a bit hacky; I think there should be a way to do this with a single AUEventListenerNotify call, but I couldn’t get that to work):
[code]void setCurrentProgram (int newIndex)
{
AUPreset current;
current.presetNumber = newIndex;
current.presetName = CFSTR("");
AudioUnitSetProperty (audioUnit, kAudioUnitProperty_PresentPreset,
kAudioUnitScope_Global, 0, ¤t, sizeof (AUPreset));
for(int i=0;i<getNumParameters();++i)
setParameter(i, getParameter(i));
}[/code]
[code]void setCurrentProgramStateInformation (const void* data, int sizeInBytes)
{
CFReadStreamRef stream = CFReadStreamCreateWithBytesNoCopy (kCFAllocatorDefault,
(const UInt8*) data,
sizeInBytes,
kCFAllocatorNull);
CFReadStreamOpen (stream);
CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0;
CFPropertyListRef propertyList = CFPropertyListCreateFromStream (kCFAllocatorDefault,
stream,
0,
kCFPropertyListImmutable,
&format,
0);
CFRelease (stream);
if (propertyList != 0)
{
AudioUnitSetProperty (audioUnit,
kAudioUnitProperty_ClassInfo,
kAudioUnitScope_Global,
0, &propertyList, sizeof (propertyList));
for(int i=0;i<getNumParameters();++i)
setParameter(i, getParameter(i));
}
}[/code]
[edit]The technical note that details this (partly).[/edit]