JUCE 4.1: Automation Value Display in Logic

Logic seems to display the normalised value in its automation data display. Logic probably expects a non-normalised value, but JUCE seems to simplify this and always communicates with normalized values to the DAWs. Thats OK, but while other DAWs invoke juce::getParameterTex() Logic displays the value directly which ends up being a float between 0 and 1.
The JUCE demo plugin is not of any help here since it doesn’t display anything (How is this possible?).

What can be done to get Logic to display a user readable value?

You need to implement the code that converts the parameter values to text (either by overriding getParameterText or by using the new parameter classes and overriding getText). Otherwise Logic will always display the normalised values.

Thanks, fabian,
thats what I assumed and mentioned in the OP. Unfortunately - as stated above - juce::getParameterTex() never gets called.

Cheers,
raketa

… maybe there is some magic I overlook here, but getParameterText() is not referenced from juce_AU_Wrapper.mm.

Cheers,
racket

the problem relates probably to:

[details=ComponentResult GetProperty()]ComponentResult GetProperty (AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
void* outData) override
[/details]
case kAudioUnitProperty_ParameterStringFromValue:
{
if (AudioUnitParameterStringFromValue* pv = (AudioUnitParameterStringFromValue*) outData)
{
if (juceFilter != nullptr)
{
const float value = (float) *(pv->inValue);
String text;

                        if (AudioProcessorParameter* param = juceFilter->getParameters() [(int) pv->inParamID])
                            text = param->getText ((float) *(pv->inValue), 0);
                        else
                            text = String (value);

                        pv->outString = text.toCFString();
                        return noErr;
                    }
                }
            }
            break;

which should be changed to:

case kAudioUnitProperty_ParameterStringFromValue:
{
    if (AudioUnitParameterStringFromValue* pv = (AudioUnitParameterStringFromValue*) outData)
    {
        if (juceFilter != nullptr)
        {
            const float value = (float) *(pv->inValue);
            String text;

            if (AudioProcessorParameter* param = juceFilter->getParameters() [(int) pv->inParamID])
                text = param->getText ((float) *(pv->inValue), 0);
            else
                text = juceFilter->getParameterText (pv->inParamID);

            pv->outString = text.toCFString();
            return noErr;
        }
    }
}
break;

while actually the test

if (AudioProcessorParameter* param = juceFilter->getParameters() [(int) pv->inParamID])

doesn’t make sense. It will evaluate to true as soon as pv->inParamID is nonzero which is probably not intended if juceFilter->getParameters() is a nullptr.

that’s something we previously discussed here with fabian :

2 Likes

Thanks, lalala,
strange, that I haven’t seen it…

fabian,
any chance one of the proposed solutions will make it into the code base? Or any reason thats not a good idea.

Thanks,
raketa

1 Like

I don’t think there is an easy fix for this (see the other thread). This is one of the reasons why we deprecated the old parameter system. I think you’ll just need to use the new parameter classes. Sorry :frowning: