Hello,
I am new with JUCE.
i try to learn how to use parameters in a simple way, but i am bloqued.
In the processor.h i have:
juce::AudioParameterFloat* test;
In the constructor i have:
addParameter (test = new juce::AudioParameterFloat ("test","Test", 0.0f, 1.0f, 0.5f));
In Processor::processBlock () i put:
cout<<"test="<< test->get() <<endl;
and i see indeed that the values of test change if the host change them by automation.
My question is: what is the simplest way to be informed that the value test has been changed by the host? (i imagine using a Listerner but i don’t find how to do exactly. I could compare the history of values of test, but i guess this is a bad solution?).
Thanks,
Frédéric.
Thanks a lot.
I am still at the beginner level of using the tutorials to understand JUCE. Thanks for them. I don’t understand enough the whole system to be able to use directly the documentation with all the modules and class list.
Following your link i did the following modifications of the code, it works, and i hope this is the good solution:
- In the header file processor.h, i added this:
class Processor : public juce::AudioProcessor
#if JucePlugin_Enable_ARA
, public juce::AudioProcessorARAExtension
#endif
, public juce::AudioProcessorParameter::Listener
{
...
juce::AudioParameterFloat* test;
void parameterValueChanged (int parameterIndex, float newValue) override;
void parameterGestureChanged(int parameterIndex, bool gestureIsStarting) override;
...
}
In the
- In the file processor.cpp, i added this:
Processor::Processor()
#ifndef JucePlugin_PreferredChannelConfigurations
: AudioProcessor (BusesProperties()
#if ! JucePlugin_IsMidiEffect
#if ! JucePlugin_IsSynth
.withInput ("Input", juce::AudioChannelSet::stereo(), true)
#endif
.withOutput ("Output", juce::AudioChannelSet::stereo(), true)
#endif
)
#endif
{
test = new juce::AudioParameterFloat(juce::ParameterID("test", 0), "Test", 0.0f, 1.0f, 0.5f);
addParameter (test);
test->addListener(this);
...
}
//==================================
void Processor::parameterValueChanged (int parameterIndex, float newValue)
{
cout<<"Processor::parameterValueChanged (), parameterIndex="<< parameterIndex<<" newValue="<< newValue<<endl;
}
//=======================
void Processor::parameterGestureChanged(int parameterIndex, bool gestureIsStarting)
{
cout<<"Processor::parameterGestureChanged() parameterIndex="<<parameterIndex<<" gestureIsStarting="<< gestureIsStarting<< endl;
}
This is how I do it’;
AudioProcessorValueTreeState::ParameterLayout createParameterLayout ()
{
AudioProcessorValueTreeState::ParameterLayout params;
params.add (std::make_unique<AudioParameterFloat> (String (module) +
"TGDutyCycleID", "TG " + String (module + 1) + " Phase Distortion",
10.0f, 90.0f, 50.0f));
}
MutineerAudioProcessor::MutineerAudioProcessor ()
#ifndef JucePlugin_PreferredChannelConfigurations
: AudioProcessor (BusesProperties ()
#if ! JucePlugin_IsMidiEffect
#if ! JucePlugin_IsSynth
.withInput ("Input", AudioChannelSet::stereo (), true)
#endif
.withOutput ("Output", AudioChannelSet::stereo (), true)
#endif
),
parameters (*this, nullptr, "Parameters", createParameterLayout ())
#endif
{
for (int module = 0; module < maxModules; module++) // Note maxModules is 8
{
// Tone Generators
synthParams.tgDutyCycleCKV[module] = parameters.getRawParameterValue
(String (module) + "TGDutyCycleID");
parameters.addParameterListener (String (module) + "TGDutyCycleID", this);
}
}
void MutineerAudioProcessor::parameterChanged (const String& parameterID,
float newValue)
{
ignoreUnused (newValue);
std::string moduleStr = parameterID.toStdString ();
int module = std::stoi (moduleStr);
// Tone Generator
if (parameterID.contains ("TGDutyCycleID"))
{
if (synthParams.tgDutyCycleTypeKV[module] > 14) calculateDutyModulationCycle
(module);
updateVoiceModuleParametersNew (module, 40);
}
}