External bpatcher loading and saving

rpg aleksy's icon

Hi there,

Recently I've been trying to create a plugin that makes it able to randomize up to 8 parameters with every incoming MIDI note.

My first few versions have been a success and everything has been working fine until I tried to decrease the file size by keeping a single Map button (-> bpatcher) object as reference and trying to create new bpatchers like it with scripting.

There are two problems I'm currently running into with that:
1. The created bpatchers don't save when saving the Live Set they are in. Meaning everytime the set is reloaded they are created again from scratch and any mappings to parameters are lost.
2. A seperate .maxpat file inside the plugin folder seems to be necessary to create new bpatchers, which is quite annoying for end-user friendliness.

Until now I've tried a few different things to fix the first issue but nothing has worked.
I'm starting to believe that saving "scripted bpatchers" and their content is near to impossible but even alternatives like reading out their contents and saving them within the main plugin doesn't seem to work either.

For the second one I'm not even sure if Max4Live supports something like embedding maxpats straight into an amxd or something similar so that all the needed data is stored within one file.

Hopefully you can lead me the right way to solving those problems :)
Cheers, rpg

tyler mazaika's icon

Indeed working with scripted creation of live objects has it's challenges, but it's possible to get it working. Live can't restore data to an object id N if the object doesn't exist, hence your apparent data loss.

For (1) you could persist the assignments made by the map_button bpatchers by storing their mapped id's in a [dict] object embedded into your device.

For (2) you can explicitly include a file in the project in Max even if the file isn't in the project's folder, and then when you export your M4L device that file is included in the .amxd. Just drag the file from Finder/Explorer into the project window. (This might also be related to differing workflows as I never edit devices by opening them out of Live because that did incomprehensible/undesirable things with included project files).

FWIW I've also found that operations like duplicating (copy+paste) of M4L devices with scripting-created-objects does not work as expected.

Cheers,
Tyler

rpg aleksy's icon

Thanks Tyler and sorry for taking so long to respond :)

Both points really helped fixing the problems with the plugin. which is awesome!
It took a bit of time to get everything just right and adjusted but in the end everything works fine.

The construction for creating and connecting up the MapButton bpatchers and loading them with the correct data got pretty big though, but the whole device turned out to be around almost 600kB smaller that way.

All in all it seems like a big success, I guess it's time for some final quality assurance ;)

Anyway, thanks again!
Cheers, rpg

tyler mazaika's icon

Just as an FYI, there is a noteworthy caveat to using a [dict] to store LOM ids:

LOM mappings made in preset (.adv) files saved by the user will be bogus when the preset is recalled. This also applies to track groups imported from .als files into different sets and .adg (device rack) presets.

Basically, any time the user adds a preset/saved device setup into their Live Set the parameter ids change (from what they were when the preset was saved). [live.object] (and friends) have mechanisms that update ids appropriately in these cases (as much as possible, anyway, there are many cases to test for this) which can't be replicated in the blob stored by [dict] in parameter mode.

And unfortunately, anyone mapping enough controls to want dynamic bpatchers means they are probably losing quite a lot of configuration/mapping effort when those ids become invalid.**

** I've tried cooking up a (really tricky) path-based system for persisting this kind of thing and restoring it correctly in such cases, but its a disgusting amount of code and requires updating things frequently to keep the paths up-to-date if the device/track hierarchy changes. Long story short I think for this kind of system the better approach is probably to just have a large bank of live.objects to cache mapped LOM ids outside of the bpatchers.