sendAUEvent


#1

Hi,

I have a plugin which can be controlled via an external control surface and have a problem with automation using Logic Pro X. A plugin is instantiated on a per channel basis and each plugin will write data to the host automation lane. If a single fader is moved on the controller all works fine, if multiple faders are moved only the last one touched will write automation data to the host. I don't see this behaviour with Pro Tools AAX or VST.

In AU automation is start -> automation value change [any number of times] -> end

 

Anyone have any ideas?

 

Many thanks,

Alan


#2

Hi Alan,

I am unable to reproduce your bug. I have applied two JUCE demo plugins built as AudioUnits to two individual tracks and mapped four controls of an external controller to the gain and delay of the first and the gain and deley of the second track. Automation works as expected and I can control all four parameters and record the automation. I tried this with Logic 10 on OS X 10.10 64-bit. Any pointers for us to reproduce your problem?

Thanks!

Fabian


#3

Can you write automation with all four parameters simultaneously? Individually it works fine for us but with multiple faders whichever fader was the last to send the begingesture message wins.

Thanks,

Alan


#4

Automation works fine for me with JUCE's audio plugin demo in Logic Pro controlling two parameters simultaneously with a Korg nanoKONTROL2. However, having re-read your initial post, I think I may have misunderstood your problem. Is your plug-in generating the parameter changes itself, i.e. your plug-in's parameters aren't controlled via Logic's MIDI Learn feature? 


#5

Hi Fabian,

 

Yes our plug-in is generating the parameter changes, we aren't using MIDI. Are you able to instantiate a plugin on another channel and automate 2 parameters at the same time? 

 

 


#6

Hi Alan,

I've tried reproducing this bug by having the PlugIn itself change two parameters at the same time and I don't have any issues. I basically took the audio demo plugin and added the following timer callback to the JuceDemoPluginAudioProcessor:

void JuceDemoPluginAudioProcessor::timerCallback()
{
    double x = (Time::getCurrentTime() - startTime).inSeconds();
    float gainValue = (float) sin (x / M_PI);
    float delayValue = (float) cos (x / M_PI);

    if (gainValue >= 0.f)
    {
        if (! gainBeingChanged)
        {
            gain->beginChangeGesture();
            gainBeingChanged = true;
        }
        gain->setValueNotifyingHost (gainValue);
    }
    else
    {
        if (gainBeingChanged)
        {
            gain->endChangeGesture();
            gainBeingChanged = false;
        }
    }

    if (delayValue >= 0.f)
    {
        if (! delayBeingChanged)
        {
            delay->beginChangeGesture();
            delayBeingChanged = true;
        }
        delay->setValueNotifyingHost (delayValue);
    }
    else
    {
        if (delayBeingChanged)
        {
            delay->endChangeGesture();
            delayBeingChanged = false;
        }
    }
}

where startTime is a member variable of type Time and delayBeingChanged, gainBeingChanged is of type bool (note that the way I've written the above timerCallback, both parameters will not always be changing at the same time. Wait for a full cycle of the sin and cos  to observe them changing simultaneously). I've uploaded the complete code example here. The above code looks like this in Logic:

Can you try to reproduce your problem with this code?

 


#7

I'll compile the DemoPlugin for Logic and see if that gives us the same problem.

 

Our setup is;

external controller channel 1 controls Plugin#1 delay param in host lane 1

external controller channel 2 controls Plugin#2 delay param in host lane 2


#8

OK I can re-produce this now. I thought I had tested this. Really quite strange that it occurs only across several instances. I'm slightly suspicious that this may be a Logic bug as this seems to work in Reaper, for example. I'll try reproducing this with Apple's AudioUnitExample.


#9

Hi Alan,

I get the same bug when I try this with Apple's own AudioUnitExamples without using any JUCE. I've changed the Filter.cpp of their AudioUnitEffectSample and added the following code:

OSStatus            Filter::Initialize()
{
    OSStatus result = AUEffectBase::Initialize();
    if(result == noErr )
    {
        // in case the AU was un-initialized and parameters were changed, the view can now
        // be made aware it needs to update the frequency response curve
        PropertyChanged(kAudioUnitCustomProperty_FilterFrequencyResponse, kAudioUnitScope_Global, 0 );
    }
    
    CFTimeInterval interval = 50. / 1000.;
    startTime = CFAbsoluteTimeGetCurrent();
    CFRunLoopTimerContext timerContext;
    memset(&timerContext, 0, sizeof(CFRunLoopTimerContext));
    timerContext.info = this;
    timer = CFRunLoopTimerCreate (NULL, startTime + interval, interval,
                                  0, 0, staticTimerCallback, &timerContext);
    CFRunLoopAddTimer( CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
    gainBeingChanged = false;
    delayBeingChanged = false;
    return result;
}


void Filter::Cleanup()
{
    if (timer != NULL)
    {
        CFRunLoopTimerInvalidate(timer);
        CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes);
        CFRelease(timer);
        timer = NULL;
    }
}


void Filter::staticTimerCallback (CFRunLoopTimerRef timer,void *info)
{
    if (Filter* f = static_cast<Filter*>(info))
    {
        f->timerCallback();
    }
}


void Filter::sendAnAUEvent (const AudioUnitEventType type, const int index)
{
    AudioUnitEvent auEvent;
    
    memset (&auEvent, 0, sizeof(AudioUnitEvent));
    auEvent.mArgument.mParameter.mAudioUnit = GetComponentInstance();
    auEvent.mArgument.mParameter.mScope = kAudioUnitScope_Global;
    auEvent.mArgument.mParameter.mElement = 0;
    
    auEvent.mEventType = type;
    auEvent.mArgument.mParameter.mParameterID = (AudioUnitParameterID) index;
    AUEventListenerNotify (0, 0, &auEvent);
}


void Filter::timerCallback()
{
    double x = CFAbsoluteTimeGetCurrent() - startTime;
    float gainValue = (float) sin (x / M_PI);
    float delayValue = (float) cos (x / M_PI);

    AudioUnitEventType type;

    if (gainValue >= 0.f)
    {
        if (! gainBeingChanged)
        {
            sendAnAUEvent (kAudioUnitEvent_BeginParameterChangeGesture, kFilterParam_CutoffFrequency);
            gainBeingChanged = true;
        }

        SetParameter (kFilterParam_CutoffFrequency, gainValue);
        sendAnAUEvent (kAudioUnitEvent_ParameterValueChange, kFilterParam_CutoffFrequency);
    }
    else
    {
        if (gainBeingChanged)
        {
            sendAnAUEvent (kAudioUnitEvent_EndParameterChangeGesture, kFilterParam_CutoffFrequency);
            gainBeingChanged = false;
        }
    }

    if (delayValue >= 0.f)
    {
        if (! delayBeingChanged)
        {
            sendAnAUEvent (kAudioUnitEvent_BeginParameterChangeGesture, kFilterParam_Resonance);
            delayBeingChanged = true;
        }

        SetParameter (kFilterParam_Resonance, delayValue);
        sendAnAUEvent (kAudioUnitEvent_ParameterValueChange, kFilterParam_Resonance);
    }
    else
    {
        if (delayBeingChanged)
        {
            sendAnAUEvent (kAudioUnitEvent_EndParameterChangeGesture, kFilterParam_Resonance);
            delayBeingChanged = false;
        }
    }
}

I've also pm-ed you with a link to an archive containing the complete source code (as posting it here would go against their T&Cs). If there is anything we could do to fix this, I would be more than happy to help. However, If you cannot find a mistake in my above changes, then I have the feeling that we might need to pass this on to Apple. What do you think?

-Fabian


#10

Hi Fabian,

 

Yes this does appear to be Logic related and would be worth passing on to Apple.

 

Thanks,

Alan


#11

Hi Alan,

I've passed this on to Apple as bug #20833029. I don't think the bug is public but I'll keep you posted.

Fabian


#12

Hi Fabian,

Have you received a response from Apple about the bug you submitted? 

Cheers,

Mark


#13

Hi Mark,

sadly I've received no response yet. It might help filing another bug report from your side and refer to my bug number #20833029.

Cheers,

Fabian


#14

Hi Fabian,

I've chased up the bug with my contacts at Apple. They are going to give the Logic team a nudge to find out what's going on!

Cheers,

Mark


#15

Hi Fabian,

Did Apple ever provide any feedback on this bug? We have yet to test the recent Logic 10.2 release; I had a quick look through the release notes but could not see anything related.

Cheers,

Mark


#16

Sadly the bug hasn't received any attention as far as I can tell. It's still marked as "Open".