Seeking a reliable system to manage pattrstorage presets for dynamic bpatchers
I can't find a reliable way to associate pattrstorage to bpatcher objects with dynamically loaded patchers. You can see the structure of the project below.
The idea is to have several slots for sound transformation. One can choose which fx is used in each slot. When a specific fx is selected using an umenu, the fx is loaded in a poly~ object and its GUI is loaded in a bpatcher. There are 5 slots but only one GUI can be seen at any moment. The user can choose which slot to see (buttons with yellow outline in the structure) and the offset in the global GUI container bpatcher is set to move the view over the corresponding sub-bpatcher containing that slot's GUI.
Each fx GUI's patch contains a local pattrstorage object for presets specific to this fx.
I want a global pattrstorage to remember which fx is loaded in each slot and the number of the most recently created/loaded preset. Any time a local preset is created or loaded its number is transmitted outside the fx GUI to the global GUI bpatcher where the number object containing it is associated with the global pattrstorage object. Presets for the global pattrstorage might be created when both an fx is selected and a preset is loaded/created in each slot.
When a preset is loaded in the global pattrstorage object the fx selection is set trough the five umenus (red outline). Each umenu then loads the right patchers in its correspoding poly~ and fx GUI sub-bpatcher (green and blue outlines). The preset number corresponding to each fx sub-bpatcher is loaded by the global pattrstorage.
However putting the preset number in the global GUI bpatcher doesn't work so easily. A 500 ms delay (pipe object) is mandatory before sending the number to the fx GUI sub-bpatcher. Also, another delay is mandatory inside the patcher loaded by the sub-bpatcher. This solution would be acceptable if it were completely reliable (althought it introduces a 1 sec. larency) but it is not. During one session it worked but the next day the preset numbers were not transmitted to local pattrstorage objects and I haven't any clue about the cause of this change.
Is there a reliable alternative ? Even better: a solution eliminating the need for delays ?
Please note the patcher runs under Max 5.1.9 on a Core 2 Duo MacBook Pro.
Thank you in advance for helping.
For those who had not guessed it: the GUI for each slot transmits the state of all its parameters as a list to the corresponding poly~ trough a send/receive connection.
I had a long fight against Max in this point. The weakness here is that asynchronous operations like loading a patcher file from disk do not report when they are finished. My workaround: every patcher which will be loaded at runtime contains a "loadbang" attached to "deferlow" and maybe a "delay" to send a bang to the patch which originated the "load" request. Inside there you find a construction like this:
t b stop
Every loaded patcher in the chain stops the delay and triggers it again, until all "late comers" have finished. Then continue with loading the pattrstorage data which will find in return all receiving pattrs now in place.
Secondly I put a "pattr" for every parameter used in a audio processing patch direct in there. Consider these as the "masters". The user interface bpatchers are "slaved" to them using "pattr foo @bindto master".
During loading of the bpatchers I use "pattrexists" in a loop to make sure that the "pattr"s exist before trying to bind to them. On a successful @bindto all parameter values are forwarded to the UI and all parts fall into place.
You can download the whole system here: http://mspcafe.g2312.de/download/ -> sources for tLb
An overview of the parts is here: http://mspcafe.g2312.de/tLb/framework/structure/
The concrete patcher example is in /tLb/lib/Sessions/tLb.OpenSessionController.maxpat
Attention: the whole thing is not yet Max 6 savy.
Thanks a lot Thomas !
Finally I found a simple solution: each dynamic bpatcher sends a bang to a specific outlet upon patcher loading and this bang triggers an int object where the preset number has been recalled by pattrstorage. I could even remove my pipe objects. Elle est pas belle la vie ?
any chance you could post a simple example? I’m struggling with something similar at the moment…
Here you are. Please note it’s a simplified version. Among other things only the default and fragmentation fx GUI+circuit are provided.
Local presets must be created and chosen before creation of a global preset. I am using Pelado’s p.storage for global presets but it is not mandatory.
I have tried to use a preset object to save and read local pattr’s presets. Actually the object reflects when a new preset is created with a "cabled" message to pattrstorage but I can’t manage to make the .json file updated when the shift+click on preset’s slot method is used. Grmbl.
With this updated version of the fx’s GUI I can combine the use of autowatch to update all instances of the same fx’s GUI upon preset storage with storage trough shift+click on the preset object.