Failure using LV2_PATCH__Set with a Object

Hi all,

I am in the process of developing a plugin for use with the mod dwarf. I have the DSP basically working but struggling to get the GUI working in the way I want to.

I have used the modspectre plugin as a source example for sending data from the DSP to the GUI and I can get this basically working, however right now I am passing a small vector of 7 floats from the DSP code to the GUI and then using the index in that array to identify what each float means.

This works but is not nice, I assumed I could change the vector to a Atom Object instead giving each float (and maybe later some items that are not floats) a key/name.

The relevant bit of code that is working based on modspectre is like:

static void
tx_to_gui (ModBLevelMatch* self, const float* bins, int32_t n_bins)
{
    LV2_Atom_Forge_Frame frame;
    lv2_atom_forge_frame_time (&self->forge, 0);
    lv2_atom_forge_object (&self->forge, &frame, 0, self->uris.patch_Set);

    lv2_atom_forge_key (&self->forge, self->uris.patch_property);
    lv2_atom_forge_urid (&self->forge, self->uris.stats);

    lv2_atom_forge_key (&self->forge, self->uris.patch_value);
    lv2_atom_forge_key (&self->forge, self->uris.stats_vector);
    lv2_atom_forge_vector (&self->forge, sizeof (float), self->uris.atom_Float, n_bins, bins);

    lv2_atom_forge_pop (&self->forge, &frame);
}

However I wanted to modify that to something like (but will add extra params later not just floats):

static void
tx_to_gui (ModBLevelMatch* self, float current_gain_db, float input_level_db)
{
    LV2_Atom_Forge_Frame frame;
    lv2_atom_forge_frame_time (&self->forge, 0);
    lv2_atom_forge_object (&self->forge, &frame, 0, self->uris.patch_Set);

    lv2_atom_forge_key (&self->forge, self->uris.patch_property);
    lv2_atom_forge_urid (&self->forge, self->uris.stats);

    lv2_atom_forge_key (&self->forge, self->uris.patch_value);
    {
        LV2_Atom_Forge_Frame object_frame;
        lv2_atom_forge_object (&self->forge, &object_frame, 0, self->uris.stats_object);

        lv2_atom_forge_key (&self->forge, self->uris.stats_current_gain_db);
        lv2_atom_forge_float (&self->forge, current_gain_db);

        lv2_atom_forge_key (&self->forge, self->uris.stats_input_level_db);
        lv2_atom_forge_float (&self->forge, input_level_db);

        lv2_atom_forge_pop (&self->forge, &object_frame);
    }

    lv2_atom_forge_pop (&self->forge, &frame);
}

However when I make changes as minimal as possible the GUI is just not getting any relevant messages from the DSP. I have been debugging into the javascript websocket onmessage and it seems the backend is just not sending the data (or something wrong).

I have read all related LV2 docs I could find and so far nothing is telling me what might be wrong. My intuition is just telling me maybe a PATCH Set doesnt work with an “object”. Or maybe I need to write an object body somehow without the atom header (If so I cant see any docs on how to do this)?

Part of my conclusion for that is that the following works ok:

static void
tx_to_gui (ModBLevelMatch* self, float current_gain_db)
{
    LV2_Atom_Forge_Frame frame;
    lv2_atom_forge_frame_time (&self->forge, 0);
    lv2_atom_forge_object (&self->forge, &frame, 0, self->uris.patch_Set);

    lv2_atom_forge_key (&self->forge, self->uris.patch_property);
    lv2_atom_forge_urid (&self->forge, self->uris.stats);

    lv2_atom_forge_key (&self->forge, self->uris.patch_value);
    lv2_atom_forge_float (&self->forge, current_gain_db);

    lv2_atom_forge_pop (&self->forge, &frame);
}
1 Like

I ended up just following the existing practice mentioned and not trying to create a new atom object for this since it was working fine for my current use case to pass a vector of floats instead.

1 Like

you are supposed to have a single key+value per object. the alternative would be to create an object of “tuple” type (alike a dictionary with many key-values) but this is not supported on MOD.

3 Likes

Thanks for the info.

1 Like