OSCdevice: int and float in the same message

Hi,

I’m trying to talk to the VST host Carla using an OSCdevice. Carla expects the following kind of message:

/Carla/0/set_parameter_value int float

Zero in this example is the VST number, while the int is for the parameter number of that VST and the float, in turn, is for setting the value of that specific parameter. For each VST I imagine I will only have one child named set_parameter_value available. So, say I want to create a process to interpolate the float for parameter number(int) 3. Is there a way to achieve that? Lists? Scripting?

Cheers!

Hi !

Currently in score there is no easy way for this case.
There are two possibilties going forward that I could see :

  • Specify the whole address with some kind of pattern / wildcard for “where the value should go” in the automation e.g.

    /Carla/0/set_parameter_value 12 $val

  • Have an alias device, that is, a device that allows some kind of scripting (see for instance the websocket or serial devices which behave like this: https://github.com/OSSIA/libossia/blob/master/Tests/testdata/websocket/ws_example.qml), where you would create a new address that maps to the existing one and use this mapped address in the score.

What do you (also including @bltzr @avilleret @jln and others) think would be more useful / easy ?

I think it would be best to keep the address and the parameters separated. And it seems to me that what I’m trying to pass to the address is a list. Would it break things a lot if there was a way to script lists? I imagine creating a list where you can use something like:
[
{type: int,
value: 12},
{type: float,
value: $1}
]

And $1 there being the value updated by the automation. Couldn’t that make things simpler and allow you to remove vec2f and all those after adding something like this?

EDIT: and also new processes with multiple outputs could benefit from having $1, $2… and so on.

Those are present as a performance optimization, in particular when sending a lot of color cues - basically, they don’t trigger any dynamic memory allocation which can be a pitfall when doing audio.

More generally, I’m wondering if the best course of action wouldn’t be to have directly a proper language to express such things since at some point someone will ask to be able to do

 [
   {type: int, value: 12},
   {type: float, value: $1 * $2 + 10}
 ]

e.g. it could be a small, inline JS object (oof, right in the performance!) or something like exprtk used for small math expressions … all the way to a JIT or other horrors of some kind :stuck_out_tongue:

Hi !

We’ve been discussing this at great length in the past and, while it’s important to keep things open in order for users to hack/misuse the software in the way they wish, I think it would be nice that we be able to cater with those kinds of situations (which are pretty common, actually) in a generic way, that would stay in line with ossia’s global namespace management philosophy (if I can say so)

In my understanding of this “ossia philosophy” and of this kind of OSC pattern,
while, in this case, OSC-wise, /Carla/0/set_parameter_value is the address and int float is the message.
Though, structurally, here the int part of the message is actually more of the address part, in my understanding, and the float part is the actual message (or value)
(well, I guess things are expressed this way because of some internal VST specs logics, or for some kind of legacy, or whatever…).

So, a possibility would be that we added a kind of alias/pattern system, which would allow to display those address/double values schemes as a set of parameters, that would be e.g. represented in ossia as:

  • /Carla/0/set_parameter_value.int float which is: the int part of the message being an instance number, it would be represented with ossia’s instance syntax (aka dots)
    and this would be output to the OSC device as:
  • /Carla/0/set_parameter_value int float

Would that make sense ?

If that does, then I guess we would need to find some kind of pattern creation UI in the device editor or the device’s node’s editor.
that could be an extra field (to be activated with a checkbox, or something), with some simplified wildcard/pattern-matching syntax - in the given example, that could be (with /Carla/0/ defined as the parent node hierarchy) done so in the set_parameter_value node edition window:

instance management [x] pattern: [set_parameter_value.$i1] values: [$f2]

(where $i1 would mean that the first int from the messages part is expressed as an instance, and $f2 that the second, float, element would be used a the value)

I guess we would then have to define a max number of parameter instances, so that those adresses be automatically created in score.
(eg. if this particular VST had 23 parameters, score would create:
/Carla/0/set_parameter_value.1 (single float parameter)
/Carla/0/set_parameter_value.2 (single float parameter)

/Carla/0/set_parameter_value.23 (single float parameter)
that could be managed individually in the score

and would be mapped on the OSC output to:
/Carla/0/set_parameter_value 1 (single float parameter value)
/Carla/0/set_parameter_value 2 (single float parameter value)

/Carla/0/set_parameter_value 23 (single float parameter value )

what do you think ?
would that make sense ?
was my description clear enough ?

If the answers are yes, we should do some kind of survey of OSC devices/softwares using this kind of syntax, so we can devise the most generic possible syntax.

p

NB: I’ve been doing some editing, improving the layout, after first publishing my reply, so if you received the last message by email, I’d advice that you read it online

Yes, some kind of addresses converters/pattern editors would be great.

As an example to fill the survey, worst case I’ve seen has been LiveOSC2. (I started sketching a Max-based addresses converter at some point but gave up…).

An address example would be:

/live/track/device/param 1 2 34 0.163435 2 Frequency A

Making this user/Ossia-friendly would be:

/live/track.($1+1)/device.($2+1)/$3 $4

Or better:

/live/track.($1+1)/device.($2+1)/$6$7.$5 $4

yikes

thanks @jln , that’s a very good (meaning really really ugly ! ) use case
I don’t think we can find something more convoluted than this ! :smiley:

Well, I hope we cant…

1 Like

hmmm… for something like this, what I (as an user) would like is for instance to specify this mapping when creating the device, and then have the input addresses / messages automatically map to relevant parts when doing an OSC learn. Would it make sense ?

sure!

though, I guess that it might be good to also have the possibility manually specify ranges for variables for cases when “OSC learning” is not possible and/or desirable

This is all very interesting and I’m not sure I can’t add much to the discussion. Although, I might be able to share my experience with Csound and OSC, where talking to Carla would involve passing:

“/Carla/0/set_parameter_value”, “if”, 1, kValue

The int and the float there can both be expressions that are being evaluated at each control cycle. I know a text-based audio design language is a completely different thing from a sequencer with a GUI, but it would be great to have that kind of flexibility.

@bltzr, for me both the int and the float are part of the message and should be treated equally, so I’m not sure I would go for that thing with the instances.

I guess as a user I would like to have a tabs system in the devices node editor for adding parameters to the right side of each final child, or maybe even change the “philosophy” so that parameters become visible children in the device panel. Then each of those parameters could be the destination for a process’ output (and possibly a nightmare to sync those signals at each control period?)

@jln, I was thinking that a solution for me with Carla could be to code an OSC router in JUCE, so that I could compile it as a VST and then actually load it inside the host. But I’ll stick to writing my scores with Csound for now.

Well, unless I completely misunderstand what you’re expressing here, that is more or less what I was proposing

In other words, what we are both saying is that we want to be able (in the described case) to have one node for each int in the device explorer, in order to easily create processes for just the float part of the message.
Do we agree on this?

Also, about instances (which is maybe not the best possible denomination for the concept), there is a little explanation with an illustration here :
https://ossia.github.io/#creating-nodes

I’m probably mistaken, but aren’t you implying that the ints of my example will become -in practical terms- treated as part of the address and therefore will contain fixed values within a range?

What I was saying was: If the parameters become visible children in the device panel then at the end of the hierarchy I should see a parent called “set_parameter_value” and then its two children: param1(int) and param2(float). Then both could be subjected to automation and whenever there’s a change in any of the those a new message is sent by the OSCdevice. Was that what you were saying?

I’m probably mistaken, but aren’t you implying that the ints of my example will become -in practical terms- treated as part of the address and therefore will contain fixed values within a range?

you aren’t mistaken :stuck_out_tongue:

What I was saying was: If the parameters become visible children in the device panel then at the end of the hierarchy I should see a parent called “set_parameter_value” and then its two children: param1(int) and param2(float). Then both could be subjected to automation and whenever there’s a change in any of the those a new message is sent by the OSCdevice. Was that what you were saying?

Wouldn’t it create some additional complexities if you are sending two automations to two different parameters ?

OK, thanks for explaining, @gsenna I think I see what you mean, now

OK, so probably we should make sure that the previously proposed syntax allows to do that, because I think that what you’re asking for could be done by something like adding two “alias” nodes

  • param1 $1
  • param2 $2

so then, two children would be created, in the way you requested (right ?)

anyway, what you could do, for now, would be to use the @[n] syntax in the automations address field in the inspector :

  • set the value of the int ie @[0] with a state
  • create an automation for the float with @[1]

Here’s a link to a score demonstrating this (open the messages window and look at the output), and also showing the limits of it: just overlay both boxes, and you will see that only the lowest messages are sent.

I won’t go into details on the why of this, but, in short, it allows to combine components of a complex dataspace across concurrent processes (like using one automation to set the luminance of a color in the hsl colorspace, while an other, parallel and independent automation, sets the red value)

Well, as I demonstrated it in the score above, with this logic, it’s very hard (at least with score’s current design) to have automations to different parameters (described by different int values) of your VST player or whatever.
Which is, I guess, what @jcelerier was saying:

While creating several “alias” nodes, one for each of the int values would allow to have concurrent and simultaneous automations to several parameters of the remote VST plugin.

But, anyway, as I said before, I think it’s good that we give a way to give the possibility to users to create the kind of things that you asked for, while also giving the possibility for other cases.

Is that any clearer ?

Yes, I think we are starting to understand each other!

Yes, but not right now because Carla will still complain about receiving two floats instead of an int and a float.

I don’t know about the internals, but from the UI perspective I think this syntax could be a solution to the problem. Still you would need to use a tabs system in the device node editor or the alias nodes you mentioned in order to control the type of each parameter. If you go for the tabs system, states would need to directly allow writing them an address (i.e., like the automation does) in order to add the @[n]. With the alias nodes you could just drag-and-drop the alias node inside a state.

That sounds reasonable!
BTW how would you imagine those tabs to be working ?

Internals-wise this is doable with the ‘list’ type, although the node editor doesn’t allow for a very advanced management of the list members yet.

Please feel free to create an issue for that on github, and to propose ui ideas to deal with types, ranges, etc of list members : collectively and individually

I haven’t done much with Qt, but after selecting “list”, I imagine you could see a QTabWidget and a “+” sign at the end in the node editor. Maybe with a single default one (a float?).