I’m working on a new module where I want to provide multiple physics models for creating sounds. The models are collections of finite elements hooked together in different ways. There is no way to edit or create new models from the limited UI controls in my module. (That would be far too complicated.)
Instead, I’m thinking of providing several models as factory presets in *.vcvm files. Loading the preset will load one of these physics models (along with initial parameter settings that the user can control through the UI). Ideally, I can document the JSON format of the physics model so advanced users could create novel physics models, and place their home-made vcvm file into the preset folder and load it. And of course, I can easily add new factory presets over time in version updates.
So my real question is, if I go down this road, I would like to designate one of these presets as a default that is loaded automatically when the module is instantiated in a patch for the first time. Is there a good way to trigger automatically loading a given vcvm file from code, just like the user navigated through the context menu and selected it?
This will be helpful because the new module will not be able to create any sounds until I load some physics model into it, and I would like it to be instantly functional as soon as it’s instantiated.
Thanks in advance for any ideas.
why not just init your module to the state that you want it in? Or if you have a parameter that is “which model”, just give it a default value like any parameter?
I would go like @Squinky recommends and use default values for all parameters. Because there’s also the
Initialize Ctrl+I functionality that resets all parameters to default values.
template.vcvm is created when you Save default from the Preset menu, and that is used each time the module is loaded into a patch
maybe I am missing something but the Palette port of the Mutable instruments Macro Oscillator changes knob labels depending on mode selected to reflect actual workings in that mode. Might at least get you there part of the way…
Thanks everyone. The physics model is a complex data structure (a network of particles and connectors), not just a flat list of parameters, but that doesn’t really matter. The unusual thing here is, there is no way to create the different models from my UI’s sliders and knobs; they have to be created externally. That is why I need (not just want) something like factory presets. (Factory presets are convenient because the UI work is already done for me.)
It sounds like it may go against convention (or be inefficient) to automatically load a file at creation time and during reset.
@Squinky makes a lot of sense here. After everyone’s feedback, I’m leaning toward including my default model JSON as a string inside my source code, and ship the same JSON text as one of the several factory preset vcvm files. Even though this is redundant, it satisfies all my goals but doesn’t require filesystem activity for initialization and reset. In general, I try to follow DRY (Don’t Repeat Yourself), but this is a case where violating DRY may be the best engineering choice.
@PaulPiko mentioning the template.vcvm is worth considering, especially if I can include a pre-installed template.vcvm in my plugin. Is that possible? I would have to be careful to not overwrite a user’s existing template during an upgrade, etc. Something says don’t do this, but I at least wanted to consider it.
Sure it’s too complex to model with sliders. But you could have a selector to pick one of n models, and that selector could be a normal float32 parameter.
I’m trying to leave open extensibility by other people to create and install new physics model files and load them right into the module. Presets look like a good way to do this because the UI work is already done for me.
I will document the preset JSON format, and I may even create a web-based CAD tool for designing the models and downloading the JSON. So that’s why I don’t just want a fixed list of models baked into the code.
It looks like it will work well to have a single baked-in model to start with, so I always have a reasonable starting state. So thanks for suggesting that! I was resisting it at first, but it makes a lot of sense now.
The cool thing is, once someone loads a physics model from a file, it will get serialized into the patch and just work. Even with a user-created model, the model will live inside the patch file and people can share them in a fully functional state, even though it might be a model I never imagined or anticipated. That’s the part that excites me most about this whole thing.
anything is possible, but that doesn’t mean it’s worth doing
I believe I have recently done exactly what you are asking for. I would say it is a bit of a hack, but …
I created a file called
template.vcvm. The format of that file is a preset file, and the data portion contains “my physics model”. I put that in the preset directory of my module. Rack filters out that particular filename from that directory. When you bring up the menu you see user presets but not that one.
I essentially call
json_loadf(asset::plugin(pluginInstance, "presets/template.vcvm")) from the module constructor and then call
dataFromJson from the constructor too - passing the “data” node from the returned json root of the file. I also make sure
dataToJson writes out all that same data in the same format. If they load a different factory preset into the module, they will have the thing they last loaded the next time they load that patch.
So, it is essentially a factory preset that you can’t see and I load it at construction. The downside is it results in a double read. If there is any preset or module save. If there is a way to know whether dataFromJson will be called later (from the constructor), then I could avoid the double read. Haven’t gotten that far yet.
Going back to some of the previous comments. You could hard code the json string for your default construction, and parse that from dataFromJson (just make it look like your data section of a preset). Then you include other physics models as real factory preset files. You get the hardcoded one out of the box, and then can choose from these others. Once they load one it will get written out in the dataToJson when the patch is saved so they have it on restart. The only advantage I found to loading the factory defaults from a file is that I can quickly iterate by modifying the file without building / installing.
But a user could save the hardcoded defaults as their own user preset, and then hand edit that JSON file just as esily