OSC implementation for QSC Q-Sys - Via UDP
Created by programmedav.com.au
Given that there is little information on the topic, i decided to create a general/basic guide for interacting with OSC devices via udp.
Not all features are covered.
TLDR - just use the tool to create the code you need.
osc = require("osc")
udp = UdpSocket.New()
-- Bind to port (Sending and receiving on this port)
udp:Open(nil, 9000)
-- Ephemeral port (system chooses)
udp:Open()
Encodes an OSC message
msg = osc.encode({
"/address/pattern", -- OSC address
"i", -- Type tag // i = integer - More on this below
42 -- Integer value
})
Decodes OSC data into a lua table
decoded = osc.decode(packet.Data)
-- Result format: {"/address/pattern", "i", 42}
When encoding OSC messages (in Qsys), there are a few argument types:
| Type | Tag | Description | Example |
|---|---|---|---|
| Integer | "i" | 32-bit integer | {"i", 42} |
| Float | "f" | 32-bit float | {"f", 0.75} |
| String | "s" | Text string | {"s", "hello-this-is-sean"} |
osc = require("osc")
udp = UdpSocket.New()
-- Send a single float value
local msg = osc.encode({
"/device/fader", -- Address
"f", -- Type (float)
0.75 -- Value
})
udp:Send("192.168.1.100", 8000, msg)
local msg = osc.encode({
"/mixer/channel",
"i", 1, -- First argument (integer)
"f", 0.75, -- Second argument (float)
"s", "cmd_string" -- Third argument (string)
})
udp:Send("192.168.1.100", 8000, msg)
osc = require("osc")
udp = UdpSocket.New()
-- Open socket
udp:Open(nil, 9000)
-- Handle incoming packets
udp.EventHandler = function(_, packet)
-- Extract address and values
local address = osc.get_addr_from_data(packet.Data)
local values = osc.decode_message(packet.Data)
print("Received OSC address:", address)
for i, v in ipairs(values) do
print("Value " .. i .. ":", v)
end
end
udp.EventHandler = function(_, packet)
local address = osc.get_addr_from_data(packet.Data)
local values = osc.decode_message(packet.Data)
if address == "/fader/1" then
-- Handle fader 1 messages
local faderValue = values[1]
-- Do something with the fader value
elseif address == "/mute/1" then
-- Handle mute 1 messages
local muteState = (values[1] == 1)
-- Do something with the mute state
end
end
-- Create a function to refresh the socket
function refreshSocket(port)
udp:Close()
udp:Open(nil, port)
end
-- Call this whenever the port needs to change
refreshSocket(9000)
udp.EventHandler = function(_, packet)
-- Only handle messages from specific IP addresses
if packet.Address == "192.168.1.100" then
local address = osc.get_addr_from_data(packet.Data)
local values = osc.decode_message(packet.Data)
-- do the things you need to do
end
end
value:gsub('\x00','')udp:Open("192.168.1.100", 9000)-- Example: Basic OSC command sender for controlling thiings
-- Load the OSC library
osc = require("osc")
-- Create UDP socket
udp = UdpSocket.New()
-- Target device information
deviceIP = "192.168.1.100"
devicePort = 8000
-- Function to send a basic OSC command
function sendOscCommand(address, ...)
-- Build arguments array with address as first element
local args = {address}
-- Add remaining arguments (type tags and values)
for i = 1, select("#", ...) do
table.insert(args, select(i, ...))
end
-- Encode OSC message
local msg = osc.encode(args)
-- Send message to the device
udp:Send(deviceIP, devicePort, msg)
print("Sent OSC message:", address)
end
-- Make sure socket is open before sending
udp:Open()
-- Examples of sending various OSC commands:
-- Example 1: Turn on a device (using integer)
sendOscCommand("/device/power", "i", 1)
-- Example 2: Set volume level (using float)
sendOscCommand("/device/volume", "f", 0.75)
-- Example 3: Send a preset name (using string)
sendOscCommand("/device/preset", "s", "Theater Mode")
-- Example 4: Send multiple parameters to a lighting cue
sendOscCommand("/lighting/cue", "i", 5, "f", 3.5, "s", "Blue Wash")
Use this tool to generate generic OSC code for Q-Sys.
Paste this into a script
-- Generated code will appear here