Is there any Zynthian API?

We could implement our OSC API over RxPy :wink:

RxPy and OSC share the same design principles, but at a different level. RxPy is a Python library for implementing asynchronous protocols/APIs. OSC is a data-level specification for creating asynchronous protocols/APIs, completely independent of the platform or the transport-layer.

Implementing an OSC API on RxPy could be a good thing, but there are other libraries that can do the task. For instance, liblo is currently used in the zynthian core and it works quite well :wink:

Anyway, Zynthian’s core OSC API server could use liblo while the Zynthian’s Web UI could use tornado and RxPy for implementing its client-side part of the zynthian’s OSC API. No problem at all with it :wink:

Regards,

Do we want to use the latter example as starting point?

http://das.nasophon.de/pyliblo/examples.html

Hi guys, did this get progressed? I wanted to add some OSC control to the Zynth but couldn’t figure out how to / whether it is implemented. If it is still at the (pre) planning stage then count me in. If you like then I could work up a framework for this. OSC is cool but frustratingly under used.

1 Like

There is an incipient OSC API based in the CUIA but it’s not explicitly documented. Basically you can call any CUIA using OSC in the port 1370 (UDP).

You can get a list of the currently implemented CUIA actions in the source code:

It’s pending to document in the Wiki the CUIA API using MIDI and OSC, but it’s quite new and still changing too fast, so better to wait a little bit :wink:

Kind Regards,

Note: Omit the leading slash path character, e.g.

import liblo
liblo.send(('localhost',1370), 'ALL_NOTES_OFF')

not

liblo.send(('localhost',1370), '/ALL_NOTES_OFF')

We may wish to consider adding path to the OSC implementation, e.g.

/cuia/ALL_NOTES_OFF

Next step is to create a set of tests that may benefit from automation and map / add OSC actions to test steps.

OK to add the “/cuia/” base path. Please, create a task in our wonderful issue tracking system :wink:

I am happy to get more involved in the OSC rationalisation / implementation. I would suggest that we define a schema something like:

/cuia
/midi
... etc.

(Obviously in much more detail!)

We would probably wish to retain TouchOSC compatibility but maybe that could be ported into a generic OSC layer rather than run a separate implementation just for TouchOSC. It would seem appropriate to have a single daemon servicing all OSC traffic. This should reduce overheads (CPU, memory, maintenance, etc.) We may need / want different IP ports for different integrations, e.g. TouchOSC may need to work on a different port to standard OSC - I don’t remember but this could be accommodated if required.

I have seen discussion in other threads. Let’s get as much input from developers and users as we can. We should probably create ticket to track this development.

Let me know if you want me to take the lead on this and I will work up a prototype to demonstrate.

1 Like

What we need is the pushing side. How would you do that?
How would webconf register to osc and get status changes without polling?

I see that as separate to OSC. Webconf is a tool to configure Zynthian and as such has connection and control. I believe it already uses websockets for comms. What traffic do you envisage passing to web conf that is not covered by existing websocket? If required we could build an OSC <-> websocket.

For any webbased site, a websocket connection helps.
I want to show the currently loaded snapshot in webconf f.e.
A snapshot changed event needs to be sent to a websocket.

Loading snapshots could be done using an OSC REST call.
But the other direction needs to be done differently.
OSC itself offers something like that as well. But liblo doesn’t support it yet?
And yes, it will be a different module. But liblo needs to send something to a websocket on certain events.

I don’t think OSC / liblo needs to be involved in that. liblo provides OSC protocol to the application so we can interface Zynthian to devices that support OSC. This should allow OSC enabled devices to control and monitor Zynthian similar to how MIDI device may do so (but with more control and monitoring available). Such control should affect the core modules which will retain these states. Any other interfaces should control and monitor those core modules.

Compare this with a server / client model. Zynthian core modules (sound engines, configuration, etc.) could be considered the server whilst connecting devices (MIDI controllers, OSC apps, web conf, etc.) could be considered clients. Each client may connect to the server via its own method / protocol and access the same data as other clients connecting via a different method / protocol.

So I don’t (yet) see the advantage of using OSC for webconf.

I think, the question is, how we get OSCresponderNode and SendTrig to work.
That’s how SuperCollider does it.

I want something like

Sorry - I am still confused :frowning:. What is the workflow and data flow that would required OSC interfacing with WebSocket. Implementing it does not worry me but I can’t figure out why we need it. Will you describe a user workflow which demonstrates this so that I can get my head around it?

We want an API that offers a complete rewrite of ZynthianUI in a browser.
When I use a rotary knob, I want to see it change in webconf et.al. webapp.

Cheers! I understand that now. I don’t think it would necessarily be worth using OSC for that. I would suggest we put the API layer in then add interface layers above it. That way we have a consistent API which may be accessed via different protocols. It feels awkward and inefficient to cascade websockets and OSC. Having an API which can have OSC and websockets connect in parallel feels the more resilient solution. We have full access to the guts of this beast so don’t need to use awkward bolt-ons.

OSC does not explicitly provide a mechanism for registering for unsolicited data. It is a unidirectional, asymmetric protocol without handshaking. Such bidirectional communication must be implemented at application layer, e.g. Ardour will send change of value to a device that has previously requested the data, i.e. it implicitly sets up a persistent reverse comms channel when a device asks for an element of data. A problem with this is that UDP is connectionless so there is no indication of the client disconnecting, e.g. OSC controller depowers but application continues to send data, an undesirable overhead and undesirable / unexpected data targeted at client when it repowers. I have worked on similar distrbuted data systems so have insight into how to implement such an application layer avoiding such pitfalls. Maybe the client registers and deregisters for data and maintains a heartbeat to retain the link.

Regarding creating a remote display, if you want to mirror the UI then consider rendering the display within an HTML window. Some ideas here. If you want to create a different display then Zynthian needs to expose its core functionality to the API layer which may then be interfaces via whatever protocols we decide to implement.

So we should create an API layer which allows monitoring and control of (all) Zynthian functions with a method to register and unregister for data changes then add interfaces to this API layer to expose the API to the outside world.

Maybe we extend the current CUIA to provide full control and monitoring of the user interface, e.g. add ability to find out what screen is showing and what is on that screen, similar to a screen reader. Then we also add a full API which gives control and monitoring of the full application without consideration of the user interface. Any changes made in the API would be reflected in all user interfaces including the attached screen if relevant, e.g. if an API client added a layer whilst the main screen was showing the layer’s page then the screen would update to show the new layer.

We may then wish to move some functions from CUIA to API, e.g. reboot (with all associated control of that function, e.g. MIDI control of CUIA reboot would become MIDI control of API reboot). This would be because reboot is not a GUI function. (To reboot from the GUI you navigate to the admin menu then select the reboot option, you don’t have a dedicated reboot button.)

I think the best would be, if the OSC server provides a websocket channel. If the webclient requests any OSC request through this channel, all changes of this value will be delivered until the socket is closed.
one issue is how we handle multiple values.
Hence we need control messages like “add /cuia/foobar” and the osc server returns those multiple value

And btw…this center API was discussed two years ago already.