Snerps
Snerps

Reputation: 636

JUCE: Slider, ValueTree error

I am trying to make a basic synthesiser plugin. I have a problem with my Slider. When I connect it with a ValueTree, I SOMETIMES get the following error. Sometimes it works without error.

// for a two-value style slider, you should use the setMinValue() and setMaxValue()
// methods to set the two values.
 jassert (style != TwoValueHorizontal && style != TwoValueVertical);

I can’t explain why I’m getting a error about a two-value-slider, even though im not using one. Am I missing something? I am new to JUCE and to C++ in general so please excuse me if I missed something obvious.

This is how I add the Parameter in PluginProcessor.cpp:

tree (*this, nullptr)

tree.createAndAddParameter("osc1_attack", "Osc1_Attack", "Osc1_Attack", envParam, 0, nullptr ,nullptr);

//Initialize Tree 
tree.state = ValueTree("SynthTree");

This is how I create the Slider in PluginEditor.cpp:

osc1AttackSlider.setSliderStyle(Slider::SliderStyle::LinearVertical);
osc1AttackSlider.setRange(0.1f, 500.0f);
osc1AttackSlider.setValue(0.1f);
osc1AttackSlider.addListener(this);
osc1AttackSlider.setTextBoxStyle(Slider::TextBoxBelow, false, 50, 20);
addAndMakeVisible(&osc1AttackSlider);

sliderTree = new AudioProcessorValueTreeState::SliderAttachment(processor.tree, "osc1_attack", osc1AttackSlider);

This is how I declared the sliderTree variable in PluginEditor.h:

AudioProcessorValueTreeState::SliderAttachment* sliderTree;

I followed the very good YouTube Tutorial of “theAudioProgrammer” and he used a ScopedPointer for this. For me that only works for ComboBoxes, if I use it here I get the following error:

/** Returns a raw pointer to the allocated data.
    This may be a null pointer if the data hasn't yet been allocated, or if it has been
    freed by calling the free() method.
*/
inline ElementType* get() const noexcept                                 { return data; }

Upvotes: 4

Views: 999

Answers (1)

Daniel Mountney
Daniel Mountney

Reputation: 1

I think i've had this problem before. The framework has been updated and instead of using the tree.addAndCreate to set your parameters you need to put this

 tree(*this, nullptr, "Parameters", createParameterLayout() )

in your constructor like this

 YourProjectAudioProcessor::YourProjectAudioProcessor(){
                 #if ! JucePlugin_IsMidiEffect
                  #if ! JucePlugin_IsSynth
                   .withInput  ("Input",  juce::AudioChannelSet::stereo(), true)
                  #endif
                   .withOutput ("Output", juce::AudioChannelSet::stereo(), true)
                 #endif
                   ), 
 

 tree(*this, nullptr, "Parameters", createParameterLayout() );
 #endif
 }

either you can put

 std::make_unique <AudioParameterInt>("oct", "Oct", -3.0f, 3.0f, 0.0f), std::make_unique <AudioParameterInt>("tone", "Tone", -12.0f, 12.0f, 0.0f), std::make_unique <AudioParameterFloat>("tune", "Tune", -1.0f, 1.0f, 0.0f)

(bare in mind that the floats at the end of this parameter statement take over the slider setRange function, I am not sure if you need to keep the setRange functions or if this would cause an error or crash. You can have to snap to int values instead of float values if you have had set snap values in you setRange function.)

in where "parameters" is in the tree() function or create a parameter layout as shown bellow in which case you just need to leave the "parameters" as it is.

juce::AudioProcessorValueTreeState::ParameterLayout YourProjectAudioProcessor::createParameterLayout(){

std::vector <std::unique_ptr<RangedAudioParameter>> params;
auto octVal = std::make_unique <AudioParameterInt>("oct", "Oct", -3.0f, 3.0f, 0.0f);
auto toneVal = std::make_unique <AudioParameterInt>("tone", "Tone", -12.0f, 12.0f, 0.0f);
auto tuneVal = std::make_unique <AudioParameterFloat>("tune", "Tune", -1.0f, 1.0f, 0.0f);

params.push_back(std::move(octVal));
params.push_back(std::move(toneVal));
params.push_back(std::move(tuneVal));
return { params.begin(), params.end() };}

also the value tree is now a scoped pointer, so where you declare slider attachments tree this now need to be a unique pointer instead of a scoped pointer or raw pointer.

std::unique_ptr <AudioProcessorValueTreeState::SliderAttachment> sliderOctTree;
std::unique_ptr <AudioProcessorValueTreeState::SliderAttachment> sliderToneTree;
std::unique_ptr <AudioProcessorValueTreeState::SliderAttachment> sliderTuneTree;

also you need to make your new sliderTree Value unique for example. change new to std::make_unique and put your slider attachment scope AKA AudioProcessorValueTreeState::SliderAttachment in angled brackets.

 sliderTree = std::make_unique <AudioProcessorValueTreeState::SliderAttachment>(processor.tree, "osc1_attack", osc1AttackSlider);

Upvotes: 0

Related Questions