MiMi-d - creating a new software synth for Zynthian

I have created a ticket in the Zynthian issue tracker regarding having zynthian_engine_jalv.py (or possibly another script if that turns out to be better) potentially load a default patch before loading a selected one, and then I can submit my suggestion if I get it working (my first attempt was utterly unsuccessful…).

This doubles the load time for presets. It’s not acceptable. We should look for a better solution.

1 Like

No. The brand new image comes with a given mimid version that was built when the image was created. For instance, the latest image in the repository, from this night, include the latest version of mimid.

We can “force” the build of the latest mimid version using the update system, but it’s not something we do on every update.

Regards,

2 Likes

Let’s put pre-compiled version of MiMi-d in our repo / file store so that an update script can pull the current version if it differs from that installed on the user machine. We shouldn’t be compiling on user-side during update.

Why not? I always liked the “gentoo” approach :wink:

I thought that’s exactly what is already happening with every update of zyncoder (and possibly some other components)…

And not just on updates. It seems to me that the zyncoder recompiles on every change of the “wiring profile”, doesn’t it?

Yes. The zyncoder library is recompiled each time you change wiring config. It’s the way it works.

Regards,

I guess it makes sense to minimize the amount of user side compilation needed, even if some of the infrastructure like zyncoder does require a recompile when things are changed.

There is a reason that zyncoder must be recompiled and it is very fast but other modules should be binary - IMHO.

1 Like

Yes that’s true. The actual time for jalv to load a preset seems to be very short though. In the suggestion I’ve been working on, the solution has been to add an extra ‘preset’ command sent to jalv with a specified Default preset in the zynthian_engine_jalv:set_preset method. So it’s not the whole set_preset method that is doubled (including setting the values in lv2_ztrcl_dict), only the jalv preset load.

I was hoping that the output from jalv when loading a preset would only reflect the parameters that were set in the URL being loaded, but in actual fact it’s all the parameters in the plugin, regardless of what was actually set or changed.

My original suggestion was for set_preset to first read the preset (.ttl) file to determine which parameters it sets, and then match them against lv2_zctrl_dict, which has been created based on the information in the running plugin itself, and either set them in a separate step after having let jalv load the preset as usual, or, since it now has access to all the parameters, set them all on a one-by-one basis by passing the values to jalv. But that means that the preset file must be read and interpreted, which seemed like a rather large task in this situation.

Do you have any other suggestion or idea how to accomplish this?

I measured the time it takes for jalv to load a preset (by measuring the time in the python code that it takes to run self.proc_cmd("preset … ") ), which is around 10 ms (it varied from 4 to 15 ms with the higher times being when the preset hadn’t been loaded previously, with the lower times being I think if the file has been loaded earlier and thus is in the file cache).

So while loading a default patch certainly increases the patch load time, it doesn’t seem to be by much. But I don’t have a good feeling for how much time is ‘too much’ under these circumstances.

Any unnecessary increase is too much! :wink:

Zynthian does a lot of stuff which can cumulate into undesirably long delays. Thick of snapshot loading where there may be lots of presets being loaded as well as all the other operations.

1 Like

I’m looking into other options.

One idea is to check jalv if it sends some form of notification to the plugin before loading a preset, which can be picked up by the plugin.

The other idea is for the Zynthian scripts to either set the defaults from the default values it already has from the engine before loading a patch, or actually reading the preset .ttl file and augmenting any parameters that aren’t present from the default values, before sending the whole bunch of parameters to jalv…

BTW before I go hunting fruitlessly, I assume there is a .ttl file parser somewhere already - after all, Zynthian can interpret manifest.ttl files to do bank management, even if it doesn’t actually seem to have the need to interpret preset files, it seems it leaves that up to jalv.

So after some research (please correct me if I’m wrong here), I’ve concluded that there is no special event or signal sent from jalv to the plugin when it loads parameters.

I’ve also noted that apart from loading a complete preset file, the only other way to set parameters via jalv, is to use one-at-a-time ‘parameter = value’ commands. Using that as the sole way of setting a preset is possible but not practical - it takes about 30 ms to load a MiMi-d preset that way (and proportionally longer for plugins with more parameters - I measured around 100 ms for Dexed). It would be nice if one could send a whole string of commands in one go, but that does not seem to be possible.

Also, there doesn’t seem to be any generic .ttl parser, whenever .ttl files need to be interpreted, this is done using small compact inline custom parses where the need arises.

The best I can think of at this stage is to have set_preset do the following (only for plugins that have explicitly been flagged as such, i.e. not for all lv2 plugins):

  • Open the preset file, and load its contents into a dictionary as ‘parameter’ : ‘value’ pairs.
  • Compare the values that are set against the values in the zctrls dictionary, and create a list (or better still, dictionary) of parameters which are present in zctrls but not in the preset, together with their default values.
  • Load the missing parameters one-at-a-time using jalv ‘parameter = value’ commands.
  • Load the preset file using jalv as usual.

This of course lengthens the load time somewhat, as the .ttl file is read twice (although likely the second time will be fast than the first as it has been recently cached), and the missing parameters are sent one at a time. On the other hand, normally the number of missing parameters will be few.

As a twist, instead of sending the missing parameters one by one, one could create a copy of the preset .ttl file and add the missing parameters into it, and then send the updated file to jalv using the ‘preset’ command. This of course means writing an additional file (although it would only be necessary when there in fact are missing parameters) which takes time in itself.

A slightly different approach, especially given that the jalv version used in Zynthian seems to be Zynthian specific (it includes the ‘save preset’ command which doesn’t appear to be upstream), would be to modify jalv, which can create its own list of default parameter values based on the initial plugin load, and locally set all parameters to their defaults just before loading a new preset file. A downside of this is that will affect all plugins, so it requires rigorous testing with all lv2 plugins, compared to a solution in zynthian_engine_jalv.py which can be enabled on a per-plugin basis, thus only affecting specific plugins such as MiMi-d. On the plus side, the additional patch load time will certainly be minimal.

Hi @ricard !

AFAIK, each parameter have a default value defined in the plugin main (dsp) ttl.
When loading a preset, any parameter not explicitly defined by the preset should take the default value, right? So, if this is the desired behavior let’s implement it in the right place, that is jalv.

Anyway, we are going to modify jalv in the next weeks, so it’s a good time to also fix this.

Regards,

1 Like

I completely agree @jofemodo , architecturally, jalv is the obvious place to fix this, in the manner you describe, rather than trying to fix this deficiency in the Zynthian UI. It should be relatively straightforward; jalv already dumps the initial (default) parameter values to the console.

Do you want me to have a look at this or shall i dump it on^H^H^H^H^H^H^H^H^H^H leave it up to you guys?

Just as a moment of looking outwards on a problem is there anyone else who might be in the same programming area that might have interesting input into this issue?

1 Like

The logical solution is for jalv to populate all parameters, using default values for any missing from the preset. Do consider plugins that may have presets that modify parameters whilst expecting some to remain unchanged, e.g. amp models, which may not load a new impulse response for each preset. This may only be a flaw in our current integration of such plugins but we should be thorough in our testing.

Loading a preset that does not populate missing parameters gives inconsistent results which seems the opposite to the desired behaviour.

Agreed.

I’m probably missing something, but this would seem to contradict the previous statement. If jalv is managing a plugin with parameters A, B and C, and a preset is loaded which only specified A and B, then it can either leave parameter C alone is it does today, or consider it missing, and set it to its default value. There wouldn’t seem to be a way for it to know that parameter C actually should not be set in the plugin without further information.

I can certainly understand the need to have ‘partial presets’ like this for certain plugins though.

Again, agreed. But how does that work with for instance the amp models?

Since it seems we’re after two contradicting behaviors, my suggestion would be to have a command line switch which specifies if jalv is to have the old behavior, or if it should set default values for missing parameters That way, zynthian-ui can keep track of which plugins require one or the other and start jalv accordingly.

I am not sure whether we need two behaviours. I am highlighting the need to test any change of behaviour widely to ensure it does not break other workflows.

If we do need two behaviours, this may be better implemented within jalv with different commands or parameters, e.g. load preset, load partial preset.

1 Like