Missing Parameters In Logic X Automation Menu

We’re encountering an issue with JUCE parameters in Logic X. We have 39 parameters in a plugin as shown in Logic’s generic editor:

However the automation menu reflects a fraction of that:

I thought it may be some strange parameter ID issue such as Automation not working in Studio One 3, however when I change all the “band” parameter IDs to more unique/shorter names I get the following result:

So my “non-band” parameters were pushed out of the menu, and even then Logic still isn’t showing all the band parameters.

Has anyone encountered this issue before? Is there some sort of limit to how many parameters Logic will show in that menu? The automation curves can still be written (via controlling the plugin GUI) for the parameters that are not visible but this isn’t really ideal.

Does this still happen after pulling the most recent changes from the develop branch? If so, are you able to create a minimal working example?

Hey @t0m,

I’m on commit 40c9488 from develop currently (can’t pull any of the newer JUCE commits without fixing some legacy related things in our projects).

Also for reference I’m currently running Logic Pro X 10.4.1

I made some quick & dirty changes to the demo NoiseGate plugin and was able to reproduce the issue:

I added const StringRefs for my param IDs and gave them a similar naming convention to what our plugin currently uses (<plugin_name>_band_n).

I added an AudioProcessorValueTreeState (named params) to the plugin and created the two existing parameters via createAndAddParameter, giving them the similar ID naming convention as before.

Then we iterate and create the 31 band parameters:

...

const juce::StringRef BAND_GAIN[31] = {
    "abcd_band_0",  "abcd_band_1",  "abcd_band_2",  "abcd_band_3",
    "abcd_band_4",  "abcd_band_5",  "abcd_band_6",  "abcd_band_7",
    "abcd_band_8",  "abcd_band_9",  "abcd_band_10", "abcd_band_11",
    "abcd_band_12", "abcd_band_13", "abcd_band_14", "abcd_band_15",
    "abcd_band_16", "abcd_band_17", "abcd_band_18", "abcd_band_19",
    "abcd_band_20", "abcd_band_21", "abcd_band_22", "abcd_band_23",
    "abcd_band_24", "abcd_band_25", "abcd_band_26", "abcd_band_27",
    "abcd_band_28", "abcd_band_29", "abcd_band_30",
};


//==============================================================================
class NoiseGate  : public AudioProcessor
{
public:
    //==============================================================================
    NoiseGate()
        : AudioProcessor (BusesProperties().withInput  ("Input",     AudioChannelSet::stereo())
                                           .withOutput ("Output",    AudioChannelSet::stereo())
                                           .withInput  ("Sidechain", AudioChannelSet::stereo())),
                                           params(*this, nullptr)
    {
//        addParameter (threshold = new AudioParameterFloat ("abcd_threshold", "Threshold", 0.0f, 1.0f, 0.5f));
//        addParameter (alpha     = new AudioParameterFloat ("abcd_alpha",     "Alpha",     0.0f, 1.0f, 0.8f));

        threshold = (AudioParameterFloat*)params.createAndAddParameter("abcd_trim", "Trim", "dB", NormalisableRange<float>(0.0f, 1.0f, 0.1f), 0.5f, nullptr, nullptr, false, true, false);

        alpha = (AudioParameterFloat*)params.createAndAddParameter("abcd_alpha", "Alpha", "", NormalisableRange<float>(0.0f, 1.0f, 0.1f), 0.5f, nullptr, nullptr, false, true, false);

        const juce::StringRef freqs[31] = {
        "20Hz",    "25Hz",   "32Hz",   "40Hz",
        "50Hz",    "63Hz",   "80Hz",   "100Hz",
        "125Hz",   "160Hz",  "200Hz",  "250Hz",
        "315Hz",   "400Hz",  "500Hz",  "630Hz",
        "800Hz",   "1kHz",   "1.3Hz",  "1.6kHz",
        "2kHz",    "2.5kHz", "3.2kHz", "4kHz",
        "5kHz",    "6.3kHz", "8kHz",   "10kHz",
        "12.5kHz", "16kHz",  "20kHz"
    };

        for (int i = 0; i < 31; ++i)
        {
             params.createAndAddParameter(BAND_GAIN[i], freqs[i] + " Band", "dB", NormalisableRange<float>(0.0f, 1.0f, 0.1f), 0.5f, nullptr, nullptr, false, true, false);
        }

        params.state = ValueTree(Identifier("ABCDState"));
    }

...

It’s not exactly the structure of our real project, but it did reproduce the issue. The same happens whether I use the AudioProcessorValueTreeState or the regular parameter classes. Not all of the bands show up anymore and the “alpha” parameter has been pushed out of the menu:

Interestingly my first test - which kept threshold & alpha the same and generated 64 parameters with names & IDs set to “a0 … a63” - does work and every parameter shows up.

I can reproduce this - when I have 29 to 46 parameters Logic is only displaying the first 28 in the automation dropdown. However, I can’t see anything obviously wrong with what JUCE is doing. Even if you force legacy parameter IDs you see the same behaviour, which is not present in other hosts. I’m not sure what to suggest.

Just one extra note: if you’re browsing the code in the post above do not copy

    param = (AudioParameterFloat*) params.createAndAddParameter (...);

which was probably only done to get the code to compile quickly. This approach will not work (and is unrelated to this specific issue).

Are there any non-JUCE plug-ins which are able to get around this?

Check out BFD3 (you should have access to that :wink:)

It has 512 automated params

Rail

Yes, that’s working fine - it’s specifically 29 to 46 parameters that are problematic.

I’m going to modify some of Apple’s sample AU code to see if that runs into the same issue.

Apple’s AU demo code also only displays 28 parameters in the automation lane. So it looks like it’s a weird Logic bug.

Thanks @t0m, I wasn’t sure if it was a Logic thing or if there was something weird with how I had my parameter IDs…

That would explain why the test I did that had 64 random parameters showed them all!