Hi Yoshimi-devs,
let me just brainstorm a bit further.
Through all this discussion it became clear that we have several
slightly related issues. Some may just be a minor itch, some may
be dangerous in certain scenarios.
In what follows, I'd like to expand a bit regarding "Instances"
Largely, Instances are a rather obscure feature, which was added
a long time ago, since at that time it seemed to be low hanging fruit.
Instances can be useful at times. Because the internal routing
and layering abilities have hard-wired limits. Sometimes you
want to create very dense, "fat" or orchestral sounds. Beyond
what you can do with unison or chorus.
An easy remedy in such case is to just run several "instruments"
at the same time. Modern computers have a lot of cores. And with
the Instances feature, the effort for the Audio-backend connection
can be shared, since all instances run in the same OS process.
And then, somewhat unrelated at first sight, there is LV2.
Due to the slightly clever trickish way this was approached,
we got something with tremendous value: namely a full-blown
Yoshimi magically hooked up behind a tiny LV2 plugin.
ZynAddSubFX was never created with that complexity in mind,
and, to put it bluntly, it would not be possible to build
a /proper/ by the rules LV2 implementation without a major
rewrite of the code base. But by this clever trick of using
a non-standard (and actually "deprecated") LV2-extension,
the project was able to squeeze out the full blown functionality
without having to touch any of the core parts.
There is a catch though. It just /might happen/ (and in fact
it always happens) that some Host "just chooses" to run several
LV2 plugins in the same Host process, and even "just happens"
to use its own GUI thread for all of its plugins as well.
So we ended using the obscure "Instances" feature also for
plug-in instances. Because it "accidentally happens" to be
the same internal structure, so we got away with minimal
effort. Which on itself is a nice thing (we would not have
been able to pull that off otherwise, to be honest).
But there are some fine points, and this is where the trouble starts.
We want *persistent* state, and distinct for each instance.
For the very least, we want them to remember the window positions
and scale and which window was opened. We might in fact have some of
the *Instance Config* set differently, like Oscil size or interpolation.
There is even the possibility to have several instances, one connected
to your on-board soundcard via ALSA, while other ones are connected
to Jack. And so on.
Anyway. The existing feature since a long time is able to
store persistent per-instance-Config. It uses the instance-ID
as a key to keep those configs apart.
For a given setup, this very easily gives us what we want.
But it creates the danger that settings can *alias* or leak
from one project to the other one.
And in most cases, this problem is just covered up by state
files. If you're setting up a complex project, either you use
some bash scripts and provide the state files directly, or you
let a session manager do the work, or you rely on the LV2
host to manage the state files and populate each plugin instance.
@ Kristian: regarding your options,
I agree with your analysis.
Basically the conclusion is that we're more or less forced
to stick with the current scheme, which has a *layering*
--- Option 1 ---
Leave it as is. There are both global and non-global (session s.ecific)
Its not only gloabal, also global per-instance and then a overlay
provided by the state file. This covers all settings with impact on the sound.
--- Option 2 ---
Make all options global, don't save them in state.
This would attempt to make "Config" and "Patch State" disjoint
Which is problematic because:
- some users need specific *Config* settings even to connect to sound
- some *Config* settings have a impact on the fine points of sound generation
- and not all users can or want to start with the same baseline.
- thus you want *your personal default* for *new instances*
--- Option 3 ---
Make all config options global, but move some options to other parts of the
save structure, such as Part or Controller.
Effectively this is like using always state files in the current solution.
And you need a way to create and explicitly save your state files.
On 22.01.2025 23:14, ichthyo wrote:
If we really think that config handling for LV2 is a serious problem,
shouldn't we rather consider to store config differently for LV2 and apart
from the standalone settings? Wouldn't it be sufficient just to use a
different instance-key (for the config files and the window layout files?)
Like e.g. a 6 digit hash-ID which is somehow derived from an identifier
which characterises the plugin instance reproducably?
On 23.01.25 18:13, Kristian Amlie wrote:
I may be misunderstanding, but do you mean to store the config for LV2 in
instance specific files in the `~/.config/Yoshimi` directory?
Under an instance key?
That is *precisely* what we do now and do since several years.
Whenever you start a LV2 plugin instance, it internally grabs a Synth-ID.
And it uses this Synth-ID as prefix for the *Instance Config*
If a config with that ID already exists, it loads this config.
Otherwise, it looks for the base config and Instance-0 config to fill
in defaults.
*After that* the state file is loaded *on top* of those baseline settings.
And when you *save* the Config settings from the Config-UI (which now happens
automatically), the instance settings also use the Synth-ID (Instance-ID) as
prefix to find the config to overwrite.
Note: this also covers window and UI layout. Like e.g. the scale of the UI
for people with very high resolution monitors. This is a lot of detail data
and it is stored in the windows/ subdirectory, also with the Instance-ID
as prefix.
What I propose is basically to use a more intelligent allocation of IDs.
Instead of using the plain Synth-ID, my idea was somehow to derive a more
distinctive instance-key. I do not know if this is possible. We'd need to
get some additional information from the LV2 host, like the session name
and the track name or some internal unique plugin instance ID.
We could hash these then and use the Hash as Key.
Standalone could use a different scheme.
If we're able to pull that off, then...
PRO: each Instance also recalls its window locations
PRO: we will much more often really detect the "new instance" situation
and populate from the dafault values, instead of aliasing to some
other usage which just happened to have the same Synth-ID
CON: over time, we will flood the user's config directory.
Would be a very localised change and thus easy to implement.
But not sure if its a relevant improvement....
We could consider how much digits to put into the hash key,
to control the trade-off between storage waste and accidental
clashes.
Anyway, I think there is one crucial question:
Can we think of situations where this config is essential for a plugin
instance to work? That would be the case if some host does not do the
extra trick with passing a state file. I mean the hooks in the LV2
plugin to retrieve and provide the state data (YoshimiLV2Plugin::stateSave)
Do we know how reliably these are used by the hosts?
I do not know the LV2 standard well enough, but are hosts required
to invoke these functions?
If this could be guaranteed, then we could indeed kind of amputate
the config handling and make a LV2 instance always behave as if it
has just not found its config, i.e. populate from baseline.
One caveat though: there is also the window layout config.
-- Hermann
_______________________________________________
Yoshimi-devel mailing list
Yoshimi-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/yoshimi-devel