ROSC is intended to build and parse messages in the Open Sound Control (OSC) protocol in R.
Currently, only building messages is implemented. ROSC builds string representations of OSC Messages that can then be passed to an external function that encodes OSC for transport.
Open Sound Control (OSC) is a transport-independent, message-oriented communication protocol for communication among computers, devices. OSC is differentiated from the related encodings XML, JSON, YMAL, MIME and MIDI by use of regular expressions and pattern-matching for dispatching, and by temporal and atomicity semantics. This package partially implements the OSC 1.1 Encoding Specification http://cnmat.berkeley.edu/content/open-sound-control-11-encoding-specification.
Many applications, most programming environments, and numerous devices (including sensor/actuator interfaces such as Arduino) have OSC client and/or server implementations.
See: http://opensoundcontrol.org/implementations https://en.wikipedia.org/wiki/Open_Sound_Control#Applications
Python, Matlab, and many other computing languages have OSC implementations.
R does not (yet), so here is a first attempt to remedy that.
oscMessage
- Build OSC Message from user supplied data, address
pattern, and optional type tag string
oscType
- Helper function to calculate an OSC Type Tag String from
user supplied data
listFlatten
- Helper function to recursively flatten a list (and
vector list elements) into a single-level list of elements each of
length 1.
libo
extension of OSC.See http://www.cnmat.berkeley.edu/sites/default/files/attachments/2015_Dynamic_Message_Oriented_Middleware.pdf for a description. This should be a separate package.
Not yet implemented. This will require writing functions to dispatch OSC Address Patterns and convert OSC arguments to R data types.
ROSC
library(ROSC)
## Example OSC address patterns
address <- "/audio/1/foo"
address.with.wildcards <- "/{th,s}ing/n[2-4]/red*"
## Example data to pack into OSC messages
data1 <- "bird"
data2 <- 6:8
data3 <- list(list(3:4,"apple"), TRUE, list(list(5.1,"foo"),NULL))
## Example of a manual type string for data3
data3_typestring <- ",iiSidSN"
## Example OSC messages
OSC1 <- oscMessage(address = address, data = data1)
OSC2 <- oscMessage(address = address, data = data2, typecomma=FALSE) # remove comma from typstring
OSC3 <- oscMessage(address = address, data = data3) # now with a nested list of mixed data types
OSC4 <- oscMessage(address = address, data = data3, double = "f") # convert doubles to 32bit floats
OSC5 <- oscMessage(address = address, data = data3, logical = "integer") # convert logical to ints
OSC is transport-independant, but it typically sent over UDP, and less often over TCP. UDP is chosen for many applications because of the lower latency (at the expenses of a theoretical possibility of occasional lost packets), and because of the ability to broadcast without the need for first establishing a connection, simplifying communication.
Unlike TCP socket connections, UDP is not natively supported in R. UDP clients and servers can be written in RCPP, but none that implement OSC compliant packets have yet been built. This should be be on a to-do list for interested R developers.
oscchief
:Install with Homebrew: $ brew install pkg-config
or see
https://www.freedesktop.org/wiki/Software/pkg-config/
Install liblo from source (requires make):
$ cd liblo-x.xx
$ ./configure --prefix=/usr/local --enable-static
$ make
$ make install
compile and install oscchief (requires make):
$ git clone https://github.com/hypebeast/oscchief.git oscchief
$ cd oscchief
$ make
$ sudo make install
oscchief
Usage
oscchief Version 0.2.0
Copyright (C) 2013 Sebastian Ruml <sebastian.ruml@gmail.com>
usage: oscchief send HOST PORT OSCADDRESS TYPES ARGUMENTS
oscchief send FILENAME
oscchief listen PORT
positional arguments:
HOST: IP address of the host where you want to send your OSC message
PORT: Port number
OSCADDRESS: OSC address where you want to send your message
TYPES: OSC type tags. Supported types:
i - 32 Bit integer
h - 64 Bit integer
f - 32 Bit float
d - 64 Bit double
c - Char
s - String
T - True (no argument required)
F - False (no argument required)
N - Nil (no argument required)
optional arguments:
-h - Shows this help message
Examples:
oscchief send 192.168.0.10 7028 /osc/address ssiii some integers 10 12 786
oscchief send 192.168.0.10 7028 /osc/address TTiFi 643 98
oscchief send 192.168.0.10 7028 /osc/address
oscchief send 192.168.0.10 7028 /osc/address TF
oscchief listen 7028
oscchief
# Wrapper for system("oscchief send")
oscchief.send <- function (host="localhost", port=12345, osc="/") {
osc <- gsub(",","",osc) # strip type tag comma for compatibility with oscchief
command <- paste("oscchief send", host, port, osc)
system(command)
}
# Define host and port
HOST <- "255.255.255.255" # this ip address means "all ip addresses on the local subnet"
LOCALHOST <- "localhost" # equivalent to "127.0.0.1", i.e. your own machine
PORT <- 6789 # recipient must listen on this port number. Use any number in the thousands.
# Send OSC messages
oscchief.send(host=HOST, port=PORT, osc=OSC1)
oscchief.send(host=HOST, port=PORT, osc=OSC2)
oscchief.send(host=HOST, port=PORT, osc=OSC3)
oscchief.send(host=HOST, port=PORT, osc=OSC4)
oscchief.send(host=HOST, port=PORT, osc=OSC5)
osccheif
:Listen on port 6789
$ oscchief listen 6789
oscchief
?## You might think you could write a wrapper for system("oscchief listen") like this, but...
# DO NOT RUN THIS IN R:
# (DOES NOT RETURN MESSAGE TO R SESSION)
# (NO WAY TO GRACEFULLY KILL LISTENER ONCE STARTED)
#
# oscchief.listen <- function (port=12346) {
# command <- paste("oscchief listen", port)
# system(command)
# }
# PORT <- 12346
# oscchief.listen(PORT)
#
Note:
Max receives both doubles (int64) and 64-bit ints (int64) as 0.0, even
in Max7 running in 64 bit mode.
Max receives floats (float32) correctly. TODO: Check code for udpsend
.
KLUDGE: Send doubles to Max as float32 (OSC Type âfâ):
ADDRESS <- "/audio/1/foo"
DATA <- list(list(3:4,"apple"), TRUE, list(list(5.1,"foo"),NULL))
OSC <- oscMessage(address = address, data = data3, double = "f") # convert doubles to 32bit floats
HOST <- "localhost"
PORT <- 5678
oscchief.send(host=HOST, port=PORT, osc=OSC)
Copy entire code block into empty Max patcher:
----------begin_max5_patcher----------
282.3ocoQsraBCCD7ryWgkOmhRLDBzekppJSxpViB1V9QZPH92qe1RendgKq
zNd1clY8kJD4fbALD7i3mvHzkJDJBE.P4dD4DaYXhYhzHB3c4gij5zSVXwFg
UZtvVPM1ySPDtfHbm3hIvF2QaFTwrCuwEu9hFFrIOP6W0Ti62Epq2DpT5pF7
y4I3iws5MvCzaVszYK6tI.dspJTpuuH4FUdiA7Y.2sseW48jX1yJHYYB4S6c
u4l1Ep62+e4t8uyc6M4NNFYhK94OaT3.92OFFoSOTRSVC7WhOBFKWvrbo3FN
zDmeIKSolAsISNJg+ZeTpCs80wVtH0tN1pgYdgeWDgo82Gq+33zoy4x1Mjzn
xQPKb7bj8Jes5CvurQJU
-----------end_max5_patcher-----------
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.