OSC - Port troubleshooting / discussion of OSC alternatives for internal communication

Hi everybody. I’m using OSC inside scripts of a single GP instance to update widgets+plugin state.
There’s one thing that troubles me about OSC though.

From time to time, on startup GP will state it could not open the selected port and disables OSC.
Nothing to worry about in a non critical environment, but in production I really don’t want to fear my GP setup becomes broken because of it.

The actual problem – I cannot find a reason for GP stating it cannot use the port.
Right now it is set to use 54355.
netstat -ano | find “:54355” returned nothing, so the port seems unused.
What other reasons can there be that make it fail to connect?

P.S.:
Would be a nice feature to have an option “auto select a free port for OSC”.
Of course this can’t work when communicating with external software.
But for everyone using it just for internal communication, it could end all worries.

What is the reason you don’t use SetWidgetValue to update a widget and SetParameter to update a plugin parameter?

@dhj let’s please not discuss alternatives. I have good reasons for using OSC. It is no option for me not to use it.
OSC support is a stable feature right? So we should investigate what is wrong and see if something needs to be fixed.

Let me know if the forums are the wrong place to troubleshoot a possibly technical issue.

In addition to my initial post:
I experienced multiple crashes while CLOSING GP. This may have to do with the port issue. Bug capture already sent through error reporting.

How looks your OSC settings window when you face that the port is already in use?

What happens when you use a different port?
For example 9000

With respect, as one of the GP developers, it is very important for us to understand why people make particular choices. For example, it is not unheard of for users to create very complicated workarounds for some particular operation because they didn’t know there were alternatives that were much easier.

Or sometimes people do something very complicated because there is no easy way to do it and understanding what they’re trying to do may help us come up with a better and easier solution.

For example, I have no way to know whether your use of OSC is because you needed it or because you didn’t know about SetWidgetValue() and SetParameter()

1 Like

I run GP on four different computers, all with OSC enabled, have been doing so for several years, and I have never encountered that problem. I run Windows 11 and Windows 10. I also don’t recall hearing anyone else mention this problem.

This leads me to believe it’s something about your system. Could you tell us a bit more about your system and whether anything else on the system is using OSC?

1 Like

@dhj well explained, I got you wrong then initially. It seemed ike you didn’t really care about the issue and were suggesting to just change the implementation to non-OSC API.

A primary reason for using OSC instead of API is that latter one requires Widget/PluginBlock refs, so it can only work in Rackspace Scripts. I use scripting a lot, so throwing it all into the Rackspace script would create a huge and hard to understand+debug mess.
Further, I’m also using OSC for communication between Local+Global Rackspace Scripts and Scriptlets.

@Vindes
Good to know, then something must be off over here. Only GP is running OSC on my system. Right now a pretty regular, well equipped Win 10 Pro PC. However for production it will soon move to a WIn11 machine with the bare minimum of software running.

@pianopaul
I had changed the OSC port to a free one, 33333 which is working well so far. However the issue was always appearing quite irregularly so only time will tell.
I worked on the setup for quite a few hours without any problems. Then, when closing GP, it crashed again - I sent you the error report. I restarted GP and this time it had no problems to use the port.
Maybe the error report can give you some clues. Other than that, I can only think of keeping an eye on it and try to describe/reconstruct what happened as detailed as possible when it happens again.

So, can you tell me what you’re doing that needs scripting?

yeah, but give me some time. My strategies and approaches changed a lot over the past months… I’m now close to a production ready setup and will show some examples and scripts soon.

Summary:

  • preset selection via UI for global+local rackspace plugins
  • plugin wet/dry mix with auto-bypass
  • plugin parameter configuration abstracted as UI-selectable choices
  • multi-plugin preset selection/parameter configuration abstracted as UI-selectable presets

Dunno if such a list can be understood without practical examples :sweat_smile:

Alright, I did some rework of my scripts and I can now tell I am using OSC because the following functions cannot be used in scriptlets:

SetWidgetValue
SetParameter
“SetBypass” (think it is not supported by setParameter atm)
LoadGPPreset

we’ve already discussed that scriptlets must not access Widget + PluginBlock instances.
But an alternative came to my mind.
What if these functions were accepting the string-based plugin handle/id?
That way, scriptlets are not actively referencing Widgets/Plugins but can still send requests.
It is then up to GP to check if the passed ID is valid and process the request.

If there were

  • SetWidgetValueByHandle
  • SetParameterByHandle
  • SetBypassByHandle
  • LoadGPPresetByHandle

then there is a powerful, easy to use alternative to OSC for internal communication.
I could disable OSC then, and also delete my entire Rackspace script.
(which I’d prefer, cause one script for managing an entire Rackspace becomes messy very soon.)

What do you think about this approach?

For these three, would you not just use a parameter in the scriptlet and map it to a widget? That widget if grouped with another then gives the same functionality (this might not be what you are trying to use it for of course)

You could bind a widget to a scriptlet parameter and then create an additional Widget which is in the same widget group as the other widget.
This additional widget you can bind to a plugin parameter.
This way you can control plugin parameters via a scriptlet parameter.
At least - to save screen space - you can hide one of the widgets.

I don’t want to sound respectless here, but I’m kinda fed up with this response,
cause we discussed this multiple times over the past months,
Pretty sure you just won’t remember this as I’m just one of many users around here.
Instead of discussing benefits/weaknesses of adding proposed features,
the only response I get is “just map stuff to widgets, use groups etc”.

Here are all the issues that I have with this approach again.

It is fine for simple stuff where it comes down to 1, 2 widgets.
For racks with heavy scripting… my scripts automate 12 or 13 plugins (bypass, preset, sometimes individual params) + dry/wet gain control for each.
I had to add dozens, maybe over a hundred of hidden widget knobs

There are so many issues that come to my mind with this concept:

  • meticulous: its fiddly and error prone to map so many widgets as an intermediate layer
  • additional error sources: widget mappings can be unlinked by accident (a misclick, on plugin replacement, widget deleted by accident, wrong widget group)
  • hard to debug - if something fails, it will fail silently, and then one has to find and dig through all the widgets and hope to find the issue more sooner than later
  • when replacing the target plugin, widgets will forget their associations
  • chaotic: dozens of hidden knobs…
  • cannot replace OSC cause it can only handle SOME functionality.
  • limited: Widget groups are capped to 26

It is intransparent as hell. which knob is for what scriptlet, targets which plugin? which widget group is associated with what? Nope. Its ok for very simple things. But for serious scripting and large setups this is a messy workaround.

In practice this means

  • 1 line of code for sending an OSC message , with a logged error message if OSC address is invalid
  • or
  • add an extra scriptlet out parameter
  • mapping this to a widget
  • add a second widget
  • group them
  • associate second widget to target plugin
  • hope this will never break or need modification
  • be left without any error reporting in case something breaks

Don’t understand the mindset of praising this as a good solution.
The response I need, and why I’m writing all this, comes down to

  • A) “yeah, would be a great feature, let’s discuss how this could be implemented”
  • B) “we don’t see the need for the average project script to do such stuff”

If there is no interest in thinking about such a feature addition just say it.
I’ll save time and skip further discussion then, and live with OSC or look into possibilities of writing my own extension.
/Rant mode off
As said, from my POV I’m a bit fed up with this discussion, please don’t take it personally.

There is a way to bind widgets - but it has a significant downside in terms of speed.

Changing the value of a widget needs to be very efficient. The reason there is a Widget “type” is because the compiler can map the variable declaration directly to the underlying widget address so calls to change the value are essentially instant. You’re guaranteed that the widget exists because the script will be recompiled if you change anything.

When you use handles, you have to search for the widget every time you want to change its value (say). Even if you’re using a fast dictionary approach (associative array), that’s not something you want to be doing all the time.

I don’t think you’re understanding the point of these interactions. When people suggest other approaches and you point out why you don’t like them, that in itself helps to see what we could do better. For a trivial example, I’d like to get rid of that 26 maximum for widget links and allow arbitrary names.

It may also make sense to allow widgets to be mappable to more than one parameter although I’d rather have a mechanism where a widget can be a driver of a “widget list”, the latter of which wouldn’t actually have GUI parts, but would still have the semantics.

Many of your other concerns are items that will be addressed in future versions, it’s not like we’re finished developing the product!

So why do you need 100s of widgets — what exactly are you trying to accomplish? How does this approach benefit live performance? Surely you’re not going to manipulate hundreds of widgets during a performance.

One major disadvantage of a large number of widgets is that switching variations will be slower because so many widgets have to be updated.

I’m just trying to understand. For example, just using my own case, I play in three bands, and have had to create some pretty sophisticated setups to accomplish the needs of the music — but I still end up with many rackspaces that only have one or two widgets and I have only one rackspace right now that has about 15 widgets. A couple of scriptlets to do things like AutoSustain or communicate with my pedalboard and that’s it.

1 Like

thank you @dhj that’s valuable insight!

When people suggest other approaches and you point out why you don’t like them, that in itself helps to see what we could do better.

I understand, but if responses do not reply to the actual question but over and over state to use some alternative (yes, this happened every single time) it feels like there is no interest in discussing anything and there’s no fun in sharing thoughts if it’s being ignored.

So why do you need 100s of widgets

Let’s skip the “why” for the moment, lots of thought has gone into the setup over past months and I’ll soon showcase the project in another thread. Limited to the “what” here is the calculation:

scripts are currently managing 12 plugins x 4 params (bypass, preset, dry gain, wet gain) = 64
(plus some special case extras, I’ll skip these here)
For conventional mapping via widgets, each param needs one “receiving” and one “sending” widget, so that’s 128 then.

Scripts will abstract all these parameters into a simpler-to-use UI which can be controlled either by hand or, on stage, by preprogrammed MIDI automation. So, many if not all of these parameters will be actively used.

reason there is a Widget “type” is because the compiler can map the variable declaration directly to the underlying widget address

I both love and hate that logic, haha… smart solution, but also tacks view/UI and model so close together that it feels kinda dirty.
So widgets are a performant way to control state and they can act as an intermediate communication layer between scriptlets and plugins. (Technically it feels weird to have script and plugins communicate through an UI layer. Controller wants to change Model but has to ask View to do so. :sweat_smile:)

Then again a script referencing plugins directly is the most performant option, as it skips the “Widget” layer entirely, right?

So, about the performance concerns, how does OSC work performantly then?
After all it communicates by string-based addresses, so GP has to map/look up plugin addresses too.

The concept of “SetParameterByHandle” etc seems to be - in my thoughts - much more comparable to OSC. Just without requiring free port and using external UDP.
Thinking about it abstractly, it is a bit like a centralised task execution scheduler that can be accessed by scripts.
As an example, the script-callable SetParameterByHandle would just need to push a new task instruction to the scheduler, pseudo-coded as { taskType, targetName, value } and GP can then handle and execute the requested action on next tick.
Of course at least the lookup of plugin/widget referenced by targetName is a necessity, but still I’d imagine it to be much more performant than OSC - building, sending, recieve, parse, interprete should take considerably more time?

Who knows, just browsed the extension API and it doesn’t look impossible to implement the basic concept as an extension. May give it a try if I feel bored.

GP Script was not designed to be a C++ replacement to handle significant separation of models, views and controllers. It is a DSL designed explicitly to perform certain operations fast because that’s what is needed in a live performance situation.

That said, for what it’s worth, when you set a widget value in GP Script, you are not performing any UI at all - you’re simply setting the underlying value of the widget which consequently sets a plugin parameter value, all extremely fast, mostly native code.

The UI (i.e, updates to the view of the widgets) is in fact handled completely separately. GP Script isn’t making the knob “turn”, for example.

No! Scriptlets are plugins with parameters that can be accessed by widgets or even controlled directly from GP Script.

The purpose of a widget is to be an intermediary between plugin parameters and your hardware controllers so that you don’t have to be concerned about MIDI.

Plugins, by definition, should not “know” anything about their container (host) and in principle scriptlets, as I mentioned earlier should not know anything about widgets. You’re basically using OSC as a workaround to communicate with objects (widgets, plugins) that scriptlets shouldn’t know anything about. That is basically breaking the Gig Performer model and why we’re all trying to understand *why you are doing what you’re doing and wondering why you are not doing things the “GP way”.

Understanding that better may lead to improvements in our approach - so that’s the “why”

Nowhere do we claim that OSC is as efficient as direct access to a widget (or a plugin) in GP Script.

when you set a widget value in GP Script, you are not performing any UI

yes I thought so much. Still, from a user’s perspective, first of all it is a UI element.
It has to be created one by one from hand, and must be maintained by hand via editor UI.
That makes it - again from a user’s POV, not in technical terms - inefficient when your aim is to automate model changes that have nothing to do with UI and need no visual representation.

No! Scriptlets are plugins with parameters that can be accessed by widgets

I believe this is one core point here.
I read lots of old and new threads and blog posts and I’m getting a feeling for what scriptslets are and what not. If I am correct, their initial purpose was to script midi processing and then they’ve grown to support more and more functionality beyond their core purpose.

The next quesiton to ask is: Why do users want to use Scriptlets for things that they are not supposed to do?

  1. they don’t know about rackspace script
  2. they need scriptlet I/O parameters
  3. they have reasons for not wanting to use rackspace script

(Option 2 is a bit ambiguous, because a rackspace script could simply listen to widgets and execute value changes. Not relevant for now.)

And option 3 is where, IMO, things become interesting.

I think there’s a fight going on about what scriptlets are:

  • plugins with encapsulated scripting (intended use)
  • a node in editor which contains a script interacting with rack (idealized use)

But there already is a rackspace script if you need rack interaction, right?
Why would one use a scriptlet/script node?

  • visual UX: Rackspace script is not visual. A Scriptlet has a visual representation that can be positioned and can be visually associated with a certain section of your node setup.
  • accessibility: One rackspace script per rack for everything. With much scripting going on, one file becomes super difficult to understand because it is responsible for handling many functions for many features in parallel Finding the functions responsible for a certain plugin in a large rackspace script is tedious, a scriptlet can sit right next to the plugin node.
  • maintainability: Changes to a monolithic rackspace script are difficult, because they can affect many things. A scriptlet, responsible for certain functionality and limited number of blocks/widgets, is easier to modify and validate.
  • repeatability: A scriptlet can easily be copied and reused with few to no alterations, a rackspace script is monolithic.

My conclusion:
There is a trend to use scriptlets far beyond their intended use, to work around the cons of rackspace script.

So maybe instead of extending Scriptlet functionality further and further, it is time to improve rackspace scripts. Ideas that may be pretty simple but have a huge impact:

  • Support multiple rackspace scripts (maintainability over max performance)
  • Named rackspace scripts (users need to have a way to easily identify the script they are looking for)
  • maybe Rackspace script nodes (UX improvement for visual association)

did a fast mockup so that its easier to follow my thoughts. These changes could already greatly improve the usefulness of rackspace scripts. (in my case: Not perfect, but I’d think its enough benefits - no more OSC - to convert my scriptlets to rackspace scripts.)

What should happen when the same callback is in more than 1 rackspace script?

Genuinely not trying to do what it’s frustrating you a bit, but have you experienced with using includes in your script - it’s not as neat as your lockup (which, I do really like the idea of, I have to say), but functionally does the same thing. It allows you to store script in separate files and just include what you need in a. Given script. If you want to change that piece of script for a load of rackspace, you just have to do it in one place and recompile all (who h is a menu option) and allr ackspces including that’s cript are updated.

1 Like