antanasbruzas / abNinjam

NINJAM client
MIT License
12 stars 2 forks source link

[feature] Make server URI part of plugin state/preset #13

Open ventosus opened 4 years ago

ventosus commented 4 years ago

The server URI should be part of the plugin state/preset and not in a global config file, imho.

LV2 supports arbitrary string properties, no idea about VST.

cbix commented 4 years ago

It's implemented in VST3 already but not exposed as an "automatable" parameter I guess. For LV2 I was trying out a few configurations today with Carla, Ardour and Jalv but couldn't get an Atom port with bufferType String to show up in the generic UI.

I believe you are more experienced regarding that as several of your plugins use atom:String parameters, e.g. moony or mephisto:

https://github.com/OpenMusicKontrollers/moony.lv2/blob/master/plugin/moony.ttl.in#L127

moony:code
    a lv2:Parameter ;
    rdfs:label "Code" ;
    rdfs:comment "shows script code" ;
    rdfs:range atom:String .

It's probably just lack of support in the hosts that I tried, also that only concerns the UI. State/preset management should work for any Atom parameter.

ventosus commented 4 years ago

It's implemented in VST3 already but not exposed as an "automatable" parameter I guess.

Nice.

For LV2 I was trying out a few configurations today with Carla, Ardour and Jalv but couldn't get an Atom port with bufferType String to show up in the generic UI.

Yeah, that's not how this works, parameters are get/set via patch messages [2] on an atom:Sequence port. All major hosts support that. Example at [1], it involves quite some boiler plate, though.

With this you would get a generic UI for free.

But a custom UI that allows to change the (already present) internal URI would do, too.

[1] https://gitlab.com/lv2/lv2/-/tree/master/plugins/eg-params.lv2 [2] http://lv2plug.in/ns/ext/patch

cbix commented 4 years ago

With this you would get a generic UI for free.

Unfortunately it's neither supported by Carla ... Screenshot from 2020-11-25 00-55-35 ...nor Ardour (it shows it as float and doesnt accept any text)... Screenshot from 2020-11-25 00-58-11 ...nor Jalv:

> controls
bool = 0.000000
double = 0.000000
float = 0.000000
int = 0.000000
long = 0.000000
path = 0.000000
spring = 0.000000
string = 0.000000
> string = "hello"
error: invalid command (try `help')

I agree this project would benefit from a decent (cross-platform) LV2 GUI, it's probably a bigger task though ;)

ventosus commented 4 years ago

uff, then I was wrong, I guess, sorry for that, those two still seem to only support parameters of type atom:Path.

cbix commented 3 years ago

@ventosus I started reading more about Atom ports and would like to implement this in abNinjam for both configuration/state as well as the chat function + MIDI Clock (+ maybe host sync somehow in the future). However, I wouldn't consider the "connect" control + chat input/output to be part of a plugin's preset/state. Would you say there should be separate Atom ports for patch:Message (parameters) and atom:Sequence or should it be a single port?

abnj:connect
  a lv2:Parameter;
  rdfs:label "Connect"
  rdfs:range atom:Bool.

abnj:host
  a lv2:Parameter;
  rdfs:label "Host";
  rdfs:range atom:String.

abnj:user
  a lv2:Parameter ;
  rdfs:label "Username" ;
  rdfs:range atom:String.

abnj:pass
  a lv2:Parameter ;
  rdfs:label "Password" ;
  rdfs:range atom:String.

# ...

# atom inputs
[
  a lv2:InputPort, atom:AtomPort;
  atom:bufferType atom:Sequence;
  atom:supports patch:Message;
  lv2:designation lv2:control;
  lv2:symbol "params_in";
],
[
  a lv2:InputPort, atom:AtomPort;
  atom:bufferType atom:Sequence;
  atom:supports atom:String;
  lv2:symbol "events_in";
],
[
  a lv2:InputPort, atom:AtomPort;
  atom:bufferType atom:Sequence;
  atom:supports time:Position;
  lv2:symbol "transport_in";
],

# atom outputs
[
  a lv2:OutputPort, atom:AtomPort;
  atom:bufferType atom:Sequence;
  atom:supports patch:Message;
  lv2:designation lv2:control;
  lv2:symbol "params_out";
],
[
  a lv2:OutputPort, atom:AtomPort;
  atom:bufferType atom:Sequence;
  atom:supports atom:String;
  lv2:symbol "events_out";
],
[
  a lv2:OutputPort, atom:AtomPort;
  atom:bufferType atom:Sequence;
  atom:supports midi:MidiEvent;
  lv2:symbol "mclk";
],
# ...
patch:writable abnj:host, abnj:user, abnj:pass.

Compared to

# ...
[
  a lv2:InputPort, atom:AtomPort;
  atom:bufferType atom:Sequence;
  atom:supports patch:Message, atom:String, time:Position;
  lv2:designation lv2:control;
  lv2:symbol "events_in";
],
[
  a lv2:OutputPort, atom:AtomPort;
  atom:bufferType atom:Sequence;
  atom:supports patch:Message, atom:String, midi:MidiEvent;
  lv2:designation lv2:control;
  lv2:symbol "events_out";
],
# ...

Still have to read about how state works because not all of the parameters should be part of it. There are no plugins out there doing anything like this because usually loading patching parameters is stateless... Does this make sense?

One idea is then to only use custom .ttl files for configuration and shipping a few "presets" that connect to popular open servers.

<http://hippie.lt/lv2/abNinjam#ninbot.com:2049> a pset:Preset;
  state:state [
    abnj:host "ninbot.com:2049"
  ].
<http://hippie.lt/lv2/abNinjam#ninjam.discordonlinejammingcentral.com:2051> a pset:Preset;
  state:state [
    abnj:host "ninjam.discordonlinejammingcentral.com:2051"
  ].
# ...

and users could create their own preset ttl with user/password for specific servers or use the host's ability to save the current configuration as a preset.