Gideros LOSC

From GiderosMobile

OSC

OpenSoundControl: https://ccrma.stanford.edu/groups/osc/index.html

From Wikipedia, the free encyclopedia
Open Sound Control (OSC) is a protocol for networking sound synthesizers, computers, and other multimedia devices for purposes such as musical performance or show control. OSC's advantages include interoperability, accuracy, flexibility and enhanced organization and documentation. Its disadvantages include inefficient coding of information, increased load on embedded processors, and lack of standardized messages/interoperability. The first specification was released in March 2002.

LOSC

OSC 1.0 implementation for lua. Github: https://github.com/davidgranstrom/losc

License:

  • MIT License

Features:

  • implements the complete OSC 1.0 specification
  • pure lua implementation, no platform dependent libraries
  • support for extended OSC types
  • plugin system for transport layers
  • address pattern matching
  • scheduled bundle evaluation (plugin dependent)

Gideros LOSC

You can download the Gideros LOSC bundle here: Media:Losc.zip (tip: right click and Save Link As).

To use LOSC in your project, copy the Gideros LOSC bundle in your project assets folder.

For documentation regarding LOSC you can refer to this link: https://davidgranstrom.github.io/losc/index.html

@keszegh initiated LOSC thread on Gideros forum here: https://forum.gideros.rocks/discussion/4975/how-can-i-communicate-with-other-apps-using-osc/p1

There is also plenty of comments in each LOSC files, feel free to read them.

Example 1

A simple example of a server and a client.

example="client"
--example="server"

local losc = require"losc"
local plugin = require"losc.plugins.udp-socket"
local Packet = require"losc.packet"

if example=="client" then
	-----------------
	-- Simple client.
	-- Uses the udp-socket plugin.
	local udp = plugin.new {sendAddr = "localhost", sendPort = 9000}
	local osc = losc.new {plugin = udp}

	local message = losc.new_message {
		address = "/foo/bar",
		types = "ifsb",
		123, 1.2345, "hi", "blobdata",
	}

	osc:send(message)

	stage:addEventListener(Event.KEY_DOWN, function(e)
		if e.keyCode == KeyCode.M then
			osc:send(message)
		end
	end)
end


if example=="server" then
	-----------------
	-- Simple server.
	-- Uses the udp-socket plugin.
	local udp = plugin.new {
		recvAddr = "localhost",
		recvPort = 9000,
		ignore_late = true, -- ignore late bundles
		non_blocking = true, -- do not block on :open(), :poll() handles processing
	}
	local osc = losc.new {plugin = udp}

	local function print_data(data)
		local msg = data.message
		print("address: " .. msg.address, "timestamp: " .. data.timestamp)
		for index, argument in ipairs(msg) do
			print("index: " .. index, "arg: " .. argument)
		end
	end
	local function print_message(msg)
		local text = TextField.new(nil, msg.address)
		stage:addChild(text)
		text:setPosition(math.random(400), math.random(400))
		print("address: " .. msg.address, "time: "..plugin:now():timestamp(plugin.precision))
		for index, argument in ipairs(msg) do
			print("index: " .. index, "arg: " .. argument)
		end
	end

	osc:add_handler("/foo/bar", function(data)
		print_data(data)
	end)
	osc:add_handler("/foo/bar2", function(data)
		print_data(data)
	end)

	osc:open() -- non blocking call :)
	isopened=true

	function onEnterFrame()
		local status, data = osc:poll()
		if status and data then
			local message = Packet.unpack(data)
			print_message(message)
		end
	end
	stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)

	stage:addEventListener(Event.KEY_DOWN, function(e)
		if e.keyCode == KeyCode.S then
			if not isopened then
				print("server opened")
				osc:open()
				isopened = true
			end
		elseif e.keyCode == KeyCode.P then
			if isopened then
				print("server closed")
				isopened = false
				osc:close()
			end
		end
	end)
end

This as a Gideros project: Media:Loscdemo.zip (tip: right click and Save Link As).

To test the LOSC protocol:

  • uncomment example="server"
  • and comment example="client"
  • compile the server as an executable then launch it
  • in Gideros:
  • uncomment example="client"
  • and comment example="server"
  • run the client in Gideros Player
  • the communication should be established between the server and the client

Example 2

Drag your mouse on the clients to draw Pixels on the server.

Losc demo4 ss.png

client.lua

print("----")
print("LOSC GIDEROS DEMO")
print("LOSC CLIENT")
print("")

local losc = require "losc"
local plugin = require "losc.plugins.udp-socket"

-- simple client, uses the udp-socket plugin
local udp = plugin.new { sendAddr="localhost", sendPort=9000, }
local osc = losc.new { plugin=udp, }

-- send message
local message
local mousex, mousey = 0, 0
stage:addEventListener(Event.MOUSE_MOVE, function(e)
	mousex, mousey = e.x, e.y
	message = losc.new_message {
		address="/foo/bar2", -- "/foo/bar"
		types="ii", -- "ifsb"
		mousex, mousey, -- 123, 1.2345, "hi", "blobdata"
	}
	osc:send(message)
end)

server.lua

print("----")
print("LOSC GIDEROS DEMO")
print("LOSC SERVER")
print("")

local losc = require "losc"
local plugin = require "losc.plugins.udp-socket"
local packet = require "losc.packet"

-- simple server, uses the udp-socket plugin
local udp = plugin.new {
	recvAddr="localhost",
	recvPort=9000,
	ignore_late=true, -- true, false, ignore late bundles
	non_blocking=true, -- true, false, do not block on :open(), :poll() handles processing
}
local osc = losc.new { plugin=udp }

-- a pixel list
local pixels = {}

-- open server
osc:open() -- non blocking call :)
print("server opened")
local isopened = true

-- listeners
local function process_message(msg)
	local pixel = Pixel.new(math.random(0xffff00), 1, 32, 32)
	pixel:setAnchorPoint(0.5, 0.5)
	pixel:setPosition(msg[1] or 0, msg[2] or 0)
	pixels[#pixels+1] = pixel
	stage:addChild(pixel)
end
stage:addEventListener(Event.ENTER_FRAME, function(e)
	local status, data = osc:poll()
	if status and data then
		local message = packet.unpack(data)
		process_message(message)
	end
	for i = #pixels, 1, -1 do
		local pposx, pposy = pixels[i]:getPosition()
		pposy += 2
		pixels[i]:setPosition(pposx, pposy)
		if pposy > 200 then
			stage:removeChild(pixels[i])
			pixels[i] = nil
			table.remove(pixels, i)
		end
	end
end)
stage:addEventListener(Event.KEY_DOWN, function(e)
	isopened = not isopened
	if isopened then
		osc:open() -- non blocking call :)
		print("server opened")
	else
		osc:close()
		print("server closed")
	end
end)

This as a Gideros project: Media:Loscdemo4.zip (tip: right click and Save Link As).


Multiplayer