Audio Unit and getParameterText()


#1

I just switched from PC to Mac and build my first little AU/VST PlugIn.Everything works fine, except one little thing: When using the AU-“Version” of my plugin under Ableton Live, the standard (host provided) UI displays the parameter values that the getParameter() method returns (range 0.0 to 1.0), instead of the String-Values the getParameterText() method returns(i.e. “10dB”).The same with automation. I debugged my code and noticed, that the getParameterText() method doesn´t get called.

When I use the very same file as vst, everything works fine. Other commercial AU plugins (Blue Tubes, GuitarRig) I tried in Ableton Live work fine too.

Maybe, I´m making a simple mistake here, any help is appreciated.


#2

Don’t think the AU wrapper uses that function… it might be something I could add, I can’t remember the reason why I didn’t implement it.


#3

Would be great, if it is possible. Some hosts (Logic) only support Audio Units and automation might be a little difficult for the user without seeing the actual value of the parameter.


#4

Jule’s todo list is growing :slight_smile:
If I have time (probably don’t have any more than you though), I’ll try to look at it as well.

Salvator


#5

it is still missing right? would be nice to have it one of those days!


#6

I can confirm this seems to be missing. Other plugins seem to work fine, but one I'm making with JUCE returns 0-1.f in Ableton (and logic) for the generic parameter display.


#7

I was looking into that recently and though I'm not an expert on AU, it seems like AU does not have any method asking for the parameter's value as string that could be mapped to getParameterText().

AU will simply display the numeric value of the parameter. The reason why other plugins display the "right" values is because AU does not require the parameters to be passed normalized within [0.0 ; 1.0] - but the JUCE AU wrapper will still pass all values normalized for compatibility reasons.

Look at lines 482-484 of juce_AU_Wrapper.mm:

outParameterInfo.minValue = 0.0f;
outParameterInfo.maxValue = 1.0f;
outParameterInfo.defaultValue = juceFilter->getParameterDefaultValue (index);

That is where the denormalized value for each parameters would need to be set. Respectively, there would need to be a denormalized version of getParameter() that would need to replace the calls to getParameter() within the AU_Wrapper.

 

To sum it up: the AudioProcessor class would need several getters and setters for denormalized values, and these would need to be called from the wrapper - then, AU host should display the "right" values.


#8

I'm also no expert with AU, but it looks like it is possible to tell the AU host that it should query for a parameter text string.  I think the AU wrapper basically needs to implement kAudioUnitProperty_ParameterStringFromValue.  There are other AU plug-ins that do this, such as when implementing discrete list controls, so it's got to work somehow.

Thoughts?

 

    @constant        kAudioUnitProperty_ParameterStringFromValue

                        Scope:                any

                        Value Type:            AudioUnitParameterStringFromValue

                        Access:                read


                        This property is used with parameters that are marked with the

                        kAudioUnitParameterFlag_HasName parameter info flag. This indicates that some

                        (or all) of the values represented by the parameter can and should be

                        represented by a special display string.

                        

                        This is NOT to be confused with kAudioUnitProperty_ParameterValueStrings. That property

                        is used with parameters that are indexed and is typically used for instance to build

                        a menu item of choices for one of several parameter values.

                        

                        kAudioUnitProperty_ParameterStringFromValue can have a continuous range, and merely states

                        to the host that if it is displaying those parameter's values, they should request

                        a name any time any value of the parameter is set when displaying that parameter.

                        

                        For instance (a trivial example), a unit may present a gain parameter in a dB scale,

                        and wish to display its minimum value as "negative infinity". In this case, the audio unit

                        will not return names for any parameter value greater than its minimum value - so the host

                        will then just display the parameter value as is. For values less than or equal to the 

                        minimum value, the audio unit will return a string for "negative infinity" which the host can

                        use to display appropriately.

                        

                        A less trivial example might be a parameter that presents its values as seconds. However,

                        in some situations this value should be better displayed in a SMPTE style of display:

                            HH:MM:SS:FF

                        In this case, the audio unit would return a name for any value of the parameter.

                        

                        The GetProperty call is used in the same scope and element as the inParamID 

                        that is declared in the struct passed in to this property.

                        

                        If the *inValue member is NULL, then the audio unit should take the current value

                        of the specified parameter. If the *inValue member is NOT NULL, then the audio unit should

                        return the name used for the specified value.

                        

                        On exit, the outName may point to a CFStringRef (which if so must be released by the caller).

                        If the parameter has no special name that should be applied to that parameter value,

                        then outName will be NULL, and the host should display the parameter value as

                        appropriate.

#9

That seems like a better solution than what I suggested - I'd guess if a plugin supports kAudioUnitProperty_ParameterStringFromValue, it should also support kAudioUnitProperty_ParameterValueFromString.

Obviously, this is something that is not directly supported by juce::AudioProcessor, but it would be great to get that done - especially since VST3 has something similar that would be great to get it supported (IEditController::getParamStringByValue and IEditController::getParamValueByString).

I modified my AudioProcessor class and the VST3 wrapper to get the Steinberg versions of that supported (see https://github.com/MartinHH/JUCE/compare/julianstorer:master...developMH#files_bucket). Something like that would be needed and put to use in the AU_Wrapper (maybe I'll give it a try, but I'm not sure if I find the time as I would want to learn more about the AU interface before filddling around with it).


 


#10

Gave it a quick try: https://github.com/MartinHH/JUCE/commit/58621aa0e828ca92d57d21840b55b5cacfbbe89c

Along with the modificiations of juce::AudioProcessor (and the proper implementations of them within my plugin), i now get proper values diplayed when editing automation in GarageBand. I don't have Logic to test, the only other host I could test was Ardour where the fix does not work (but that might as well be due to Ardour not supporting those AU features...).


#11

Thanks for the heads-up on this, guys, I'll take a look and add something along those lines!


#12

thanks for the answer to this problem. me and my students have all confronted this.... would love to see this fix make it's way into JUCE (before i teach JUCE in music programming next quarter (9-14)??)

 

tom


#13

I would like to see that in juce also!

Jules, are you just not having time, or is there any special difficulty in adding that?


#14

I'm reluctant to add this because the class already has far too many virtual methods for accessing parameters. Sure, I can keep adding more and more methods like this for random bits of missing functionality, but it's becoming a mess - what really needs to happen is a rewrite of the whole class so that each parameter is controlled by an object which has accessors for all these things. That'll involve breaking everyone's code though, which is why I've not got around to it yet.


#15

Hi Jules I know this seems a lot to add to the wrapper and processor class but it's worth it... 

Having parameters mapped 0 to 1 at the front end level is a bit frustrating, the patch proposed in this thread works great and I would definately add it to Juce.

Hopefully you will reconsider your position :)

Best, Silvere


#16

Hi Silvere - things have moved on since this post and there's now an AudioProcessorParameter class that is replacing all the old parameter methods. There's also some new stuff to come shortly which shows how parameter subclass can be used for doing arbitrary range mappings..