The issue can easily be reproduced by creating an AudioProcessorValueTreeState
and calling createAndAddParameter()
without subsequently assigning an initialised ValueTree
to AudioProcessorValueTreeState::state
.
The docs say:
To use:
1) Create an AudioProcessorValueTreeState, and give it some parameters using createAndAddParameter().
2) Initialise the state member variable with a type name.
But in JUCE 5.3.1 you could get away with not performing ‘2’.
However, in JUCE 5.3.2 you get a crash because of this change, specifically removing the check if (state.isValid())
from copyValueToValueTree()
The call stack for the crash is:
|#0|0x00000001002c02b6 in juce::ValueTree::setPropertyExcludingListener(juce::ValueTree::Listener*, juce::Identifier const&, juce::var const&, juce::UndoManager*) at /Users/jamie/Desktop/TestCrash/Builds/MacOSX/../../../../Documents/JUCE5/modules/juce_data_structures/values/juce_ValueTree.cpp:737|
|---|---|
|#1|0x00000001002bee5d in juce::ValueTree::setProperty(juce::Identifier const&, juce::var const&, juce::UndoManager*) at /Users/jamie/Desktop/TestCrash/Builds/MacOSX/../../../../Documents/JUCE5/modules/juce_data_structures/values/juce_ValueTree.cpp:730|
|#2|0x0000000100142d27 in juce::AudioProcessorValueTreeState::Parameter::copyValueToValueTree() at /Users/jamie/Desktop/TestCrash/Builds/MacOSX/../../../../Documents/JUCE5/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp:132|
|#3|0x0000000100142143 in juce::AudioProcessorValueTreeState::flushParameterValuesToValueTree() at /Users/jamie/Desktop/TestCrash/Builds/MacOSX/../../../../Documents/JUCE5/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp:349|
|#4|0x0000000100142d89 in juce::AudioProcessorValueTreeState::timerCallback() at /Users/jamie/Desktop/TestCrash/Builds/MacOSX/../../../../Documents/JUCE5/modules/juce_audio_processors/utilities/juce_AudioProcessorValueTreeState.cpp:359|
The solution is to initialise AudioProcessorValueTreeState::state
as stated in the docs, e.g.
AudioProcessorValueTreeState paramState(*this, nullptr);
String paramID = "foo";
paramState.createAndAddParameter (paramID, paramID, paramID,
NormalisableRange<float>(0.f, 1.f),
0.f, nullptr, nullptr);
paramState.state = ValueTree("Foo"); /* <--- initialise!!! */