Use Zynthian as an OSC controller (to send OSC messages)

Hello,

I know that Zynthian can receive OSC messages (example from topic)

but I’m wondering if Zynthian is able to send OSC messages by itself?

The idea would be to send OSC messages when I control faders/buttons on a midi surface (for example S*, F*, K* controls on an MPK249)

Bonus ideas (if possible and still compatible within Zyn area of usage)

  • maybe use the touchscreen as a surface for OSC (like an embedded OpenStageControl, you put components and setup messages sent when touching them)
  • have a OSC sequencer (like ZynSeq, but instead of playing instruments, they send a list of OSC messages in time when the pad is pressed)

I have no problem to setup myself OSC components / messages / addresses (like I do in OpenStageControl)

Explanations about the final usecase : I am considering doing VJ shows, and the program Vimix is able to be controlled by OSC. The idea that came in my mind is “Use zynseq + keyboard for the audio part and control surface faders via OSC for the visual part“

By the generic nature of OSC, I’m sure it can be beneficial for others use cases

Or maybe its a (very?) niche usecase (I know that I can simply use OpenStageControl on a touchscreen + “Midi To OSC converter”)

But I wanted to know if there is a possibility to have this embedded in Zynthian (maybe by adding an “OSC chain“ like Midi chains)?


Note:

In my message, OSC always mean “Open Sound Control” (the protocol)

When talking about OpenStageControl, I always write the complete name

so silly to OpenStageControl to have chosen a name that have the same abbreviation :sweat_smile:

Hello,

good question – and you’re not alone, this comes up regularly when people start mixing audio + visual workflows :slightly_smiling_face:

Short answer:
:backhand_index_pointing_right: Zynthian does NOT currently provide a generic way to send arbitrary OSC messages based on MIDI controller actions.

Now the details.


What Zynthian can do today (OSC-wise)

Zynthian can send OSC, but only in very specific, hard-coded cases:

These are engine-specific implementations, not a general-purpose OSC output layer.

:right_arrow: There is no generic “OSC chain” equivalent to MIDI chains where:

  • MIDI CC → arbitrary OSC address/value mapping
  • MIDI surface → OSC target (like VJ software)

What Zynthian cannot do (yet)

  • :cross_mark: No generic MIDI → OSC mapper
  • :cross_mark: No OSC sequencer equivalent to ZynSeq
  • :cross_mark: No embedded OSC surface editor
  • :cross_mark: No user-configurable OSC output per controller / fader / button

So your idea of:

“use MIDI surface faders to directly send OSC to Vimix”

is not natively supported inside Zynthian at the moment.


Existing workaround (what does work)

What does work well is using OpenStageControl as a translation layer.

I’ve personally done this:

  • MIDI controller → Zynthian (or directly to OpenStageControl)

  • OpenStageControl:

    • receives MIDI
    • converts it to OSC
    • sends OSC to the target application (e.g. visuals)

I published a few OpenStageControl templates here:
:backhand_index_pointing_right: https://github.com/ToFFmashines/Zynthian-OSC

In particular:

  • the source/All templates include MIDI to Zynthian tables
  • some JS files need adaptation (Zynthian hostnames / ports are not centralized)

In my setups:

  • OpenStageControl usually runs on a separate computer
  • It could theoretically run on the Zynthian itself, but I haven’t tested that

So yes:
:backhand_index_pointing_right: OpenStageControl can be used as a middleware to translate MIDI → OSC, while Zynthian focuses on audio.


About your “bonus ideas”

Conceptually, they make sense:

  • OSC surface on touchscreen → :+1:
  • OSC sequencer → :+1:
  • OSC chains like MIDI chains → :+1:

But all of these would require:

  • new core features
  • UI work
  • routing logic
  • and long-term maintenance

So at the moment they remain feature requests, not hidden capabilities.


Final note

Your use case (audio on Zynthian + visuals via OSC) is valid, but currently the cleanest solution is still:

Zynthian for audio + OpenStageControl (or similar) for OSC routing

rather than an all-in-one embedded solution.

Hope this clarifies the current state :+1:

P.S: I’m not a programmer and I don’t belong to the Zynthian development core. I’m just an enthusiastic Zynthian user and I try to contribute more with practical things.

2 Likes

Hi, I’ve been experimenting with running Open Stage Control directly on Zynthian (not externally on a laptop). Surprisingly, it’s quite doable, but you need to pay attention to a few details (PATH / ports / MIDI backend).

1) Installing Node.js (arm64 tarball) into /opt/nodejs

I downloaded an ARM64 build of Node.js and installed it “manually” into /opt/nodejs:

cd /zynthian/zynthian-my-data/tmp
tar -xJf node-v22.11.0-linux-arm64.tar.xz
sudo mkdir -p /opt/nodejs
sudo mv node-v22.11.0-linux-arm64/* /opt/nodejs/

# (for interactive shell) add PATH to .bashrc
echo 'export PATH=/opt/nodejs/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

node --version

After that, Node works normally from the command line.


2) Putting Open Stage Control into zynthian-my-data

I put everything here:

/zynthian/zynthian-my-data/openstagecontrol/
  app/        # O-S-C (node build)
  sessions/   # my sessions + scripts

Specifically these session files:

  • /zynthian/zynthian-my-data/openstagecontrol/sessions/zynthian.json
  • /zynthian/zynthian-my-data/openstagecontrol/sessions/main.js

3) Running it (example command)

I’m using headless mode (-n) and sending OSC to Zynthian CUIA on localhost.

/opt/nodejs/bin/node /zynthian/zynthian-my-data/openstagecontrol/app/ \
  -s 127.0.0.1:1370 \
  -l /zynthian/zynthian-my-data/openstagecontrol/sessions/zynthian.json \
  -c /zynthian/zynthian-my-data/openstagecontrol/sessions/main.js \
  --port 8088 \
  -m sysex oscmidi:virtual \
  -n

4) systemd service (so it starts automatically)

I created this unit:

/etc/systemd/system/openstagecontrol.service

[Unit]
Description=Open Stage Control (headless) for Zynthian
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=zynthian
Group=audio
WorkingDirectory=/zynthian/zynthian-my-data/openstagecontrol

# systemd doesn't read .bashrc, so set PATH explicitly:
Environment="PATH=/opt/nodejs/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

ExecStart=/opt/nodejs/bin/node /zynthian/zynthian-my-data/openstagecontrol/app/ \
  -s 127.0.0.1:1370 \
  -l /zynthian/zynthian-my-data/openstagecontrol/sessions/zynthian.json \
  -c /zynthian/zynthian-my-data/openstagecontrol/sessions/main.js \
  --port 8088 \
  -m sysex oscmidi:virtual \
  -n

Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target

Enable / start it:

sudo systemctl daemon-reload
sudo systemctl enable --now openstagecontrol.service
sudo systemctl status openstagecontrol.service
journalctl -u openstagecontrol.service -n 200 --no-pager

In my template, I removed the mixer table because it caused a loop and massively slowed down the whole Zynthian.

CUIA commands to Zynthian worked for me.

I did not test MIDI commands yet. Zynthian (in Patchage) shows that it can see the newly created MIDI ports, and that’s basically as far as I got. Zynthian is definitely not ready for having Open Stage Control bolted onto it this “raw” way.

I’ll leave further experiments to people with stronger software skills.

3 Likes