Failing to load MidiClip from state [EngineInPlugin]

Hi,
I’m working on a sequencer plugin using tracktion. I’m trying to figure out now how to save the sequence the user created in the plugin state, but the MidiClip I’m saving is restored without the sequence. I’m doing this:

void AudioPluginAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
{
    juce::ValueTree tree(PluginStateID);
    tree.setProperty("NAME", "PluginState", nullptr);

    te::MidiClip* midiClip = EngineUtils::getMidiClipFromTrack(engineWrapper->edit, 0);
    tree.addChild(midiClip->state.createCopy(), 0, nullptr);

    juce::MemoryOutputStream stream(destData, false);
    tree.writeToStream(stream);
}

void AudioPluginAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
    auto tree = juce::ValueTree::readFromData(data, sizeInBytes);
    if (!tree.isValid() || tree.getType() != juce::StringRef(PluginStateID)) {
        return;

    for (int i = 0; i < tree.getNumChildren(); i++) {
        auto child = tree.getChild(i);
        if (child.getType() == te::IDs::MIDICLIP) {
            auto sequenceTrack = dynamic_cast<te::ClipTrack *>(EngineUtils::getOrInsertAudioTrackAt(engineWrapper->edit, 0));
            te::MidiClip * midiClip = new te::MidiClip (child, engineWrapper->edit.createNewItemID(), *sequenceTrack);
            sequenceTrack->addClip(midiClip);
        } else {
            DBG("unexpected child type " << child.getType());
        }
    }

When I load a projcet I saved with a sequence in the plugin, it is reloaded but fails on assertion here. And Indeed the midi clip doesn’t contain the saved sequence.

What am I doing wrong here? Or maybe there’s a better way altogether to save clip/track state in a plugin?

Thanks.

I think you want to use Clip* ClipTrack::insertClipWithState (juce::ValueTree); instead of addClip

1 Like

Thanks! I still need to learn more how tracktion works with ValueTree. I watched Dave’s presentation on ADC 2017 but still got some code reading to do…
I tried using insertClipWithState and it didn’t work instantly, and I had to create a copy of the child first. In case someone else reads it, replace the addClip line in my example above with:
sequenceTrack->insertClipWithState(child.createCopy());