Hosted AudioUnit editors not updating (fix included)

I’ve got an issue where the editors of AudioUnit plugins hosted in my Pedalboard app don’t get updated when their parameters change (either via preset selection or with individual parameters being changed via MIDI). I don’t have any problems with VST plugins.

I’ve tried calling repaint() on the editor, but that doesn’t seem to work either. Is there something specific I need to do to update AudioUnit editors?

(I should note that I’m still on OSX 10.6 and XCode 3; I was hoping I could hold off on upgrading until I got this latest release out)

(also, doing some testing it turns out previous versions of my Pedalboard had the same issue, I just hadn’t noticed it; so it’s not a recent thing)

Sounds odd. Have you tried it in different hosts?

Well, running the plugins I’ve been testing with (the default Apple ones, plus AudioDamage’s Fuzz+) in AULab, their editors update as expected when you change their preset. I don’t think it’s a problem with specific plugins though?

(to be clear, my app’s a host, not a plugin)

Ok, gotcha.

Sorry… don’t really know then. It’s the plugin’s job to redraw its interface, I don’t know what else you could do to make them do that…

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

[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);

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, &current, sizeof (AUPreset));
	for(int i=0;i<getNumParameters();++i)
		setParameter(i, getParameter(i));

[code]void setCurrentProgramStateInformation (const void* data, int sizeInBytes)
CFReadStreamRef stream = CFReadStreamCreateWithBytesNoCopy (kCFAllocatorDefault,
(const UInt8*) data,
CFReadStreamOpen (stream);

    CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0;
    CFPropertyListRef propertyList = CFPropertyListCreateFromStream (kCFAllocatorDefault,
    CFRelease (stream);

    if (propertyList != 0)
        AudioUnitSetProperty (audioUnit,
                              0, &propertyList, sizeof (propertyList));

		for(int i=0;i<getNumParameters();++i)
			setParameter(i, getParameter(i));

[edit]The technical note that details this (partly).[/edit]

Thanks! Just taking a look at this, and have checked something in - would appreciate you trying it out and letting me know if it works!

Just had a chance to check out your changes. It’s working perfectly, thanks!