AudioProcessorParameterGroup and xml export

I’m not sure if I understand it the right way. I try to make use of the group feature for audio parameters.
The plan was to use it to create a readable preset file.

I tried the following:

    AudioProcessorValueTreeState::ParameterLayout layout;
    auto pads = std::make_unique<AudioProcessorParameterGroup>("pads", "Pads", " | ");

    for (int i = 0; i < TalSampler::NumberOfPads; i++)
    {
        auto outputParam = std::make_unique<AudioParameterInt>("output" + getPadPostfix(i), "Output " + getPadPostfix(i), 0, 7, 0);
        pads->addChild(std::move(outputParam));

        auto mappings = std::make_unique<AudioProcessorParameterGroup>("mappings", "Mappings", " | ");
        for (int j = 0; j < TalPad::NumberOfMappings; j++)
        {
            auto mappingVolumeParam = std::make_unique<AudioParameterInt>("volume" + getPadMappingPostfix(i, j), "Volume " + getPadPostfix(i), 0, 7, 0);
            mappings->addChild(std::move(mappingVolumeParam));
        }

        pads->addChild(std::move(mappings));
    }

    layout.add(std::move(pads));

I expected to get a hierarchical XML as an output where the groups are also visible in the XML but i got the following result with all parameters in the root:

<?xml version="1.0" encoding="UTF-8"?>

<ProjectX>
  <PARAM id="midinote00" value="36.0"/>
  <PARAM id="midinote01" value="36.0"/>
  <PARAM id="midinote02" value="36.0"/>
  <PARAM id="midinote03" value="36.0"/>
  <PARAM id="midinote04" value="36.0"/>
  <PARAM id="midinote05" value="36.0"/>
...

Can anybody tell me what I’m doing wrong?

I’m using following to create the XML:

audioProcessorValueTreeState.state.createXml()

Any help is welcome.

After having a closer look it looks like this is by design. It looks like a hierarchical XML structure is only possible with Sub-ValueTrees.

I have to find out if this is possible with the AudioProcessorValueTreeState. Had no success so far.

Any help is welcome.

Yes, the AudioProcessorValueTreeState predates the ParameterGroups, and if it was changed all saved sessions would break.

Maybe it could be an opt-in feature, but I am guessing you would need to implement your own serialisation and deserialisation method. It is not too hard.

FWIW since that data is never visible to the user you have to decide if it’s worth it.

Thanks for the answer. I really hoped this works that way. For a sampler plugin, it would be nice to have a readable preset format. But i see the point with the breaking change.