OSC via TCP has no framing

Version string: Renoise 64Bit - V3.0.0 (Built: apr 8 2014)

OSC is a packet encoding and therefore needs some kind of framing when sent via streaming protocols (e.g. TCP).

Renoise expects OSC to arrive without any framing which is not correct and thus does not work with any other OSC-TCP implementation.

There are two framing schemes for OSC-TCP out there: size-prefix framing and SLIP encapsulation:


Right now it is not possible to send any OSC via TCP to renoise from any library/app I know of that supports OSC via TCP, as Resnoise does not

implement OSC via TCP correctly.



TCP stream {

raw OSC packet



SuperCollider uses size-prefix framing:

TCP stream {

int32 size prefix

raw OSC packet



PureData uses SLIP encapsulation

TCP stream {

SLIP packet {

raw OSC packet



The OSC 1.0 spec says

The underlying network that delivers an OSC packet is responsible for delivering both the contents and the size to the OSC application. An OSC packet can be naturally represented by a datagram by a network protocol such as UDP. In a stream-based protocol such as TCP, the stream should begin with an int32 giving the size of the first packet, followed by the contents of the first packet, followed by the size of the second packet, etc.


The 1.1 spec is here (sort of):http://opensoundcontrol.org/spec-1_1

But it seems that it was never finalized. That age links to a another page, which links to a PDF.

In that PDF it says:

  1. OSC Delivery Specification 1.1

OSC messages may be sent directly without the need for framing in message oriented protocols such as UDP or MPI. Stream-oriented protocols such as TCP and serial byte streams need a framing mechanism to establish message boundaries. These streams are now required to employ SLIP (RFC1055) with a double END character encoding. This choice has been used extensively for years on the Make Controller board and in our micro-OSC work and we have established its efficiency and superiority over the OSC 1.0 size-count-preamble recommendation when recovering from damaged stream data.


Thank you for the summary and the corresponding links.

That’s exactly how it is right now, some apps/libs are compliant to the spec-1.0 (e.g. SuperCollider), some are compliant to the spec-1.1 (e.g. PureData), and some can do both (e.g. liblo)

Renoise’s default TCP-OSC server seems not to be compliant with any spec at all, though, which makes it useless.







liblo (lightweight OSC library)


To summarize this thread here:


Best practices:

  • For datagram protocols (e.g. UDP), send the raw OSC packet.

  • For reliable stream protocols (e.g. TCP, USB), use spec-1.0 and send the OSC packet prefixed with its int32 size

  • For unreliable stream protocols (e.g. serial), use spec-1.1 and send a SLIP (double)encoded OSC packet

SuperCollider does it right, IMHO, by using spec-1.0 for TCP.

PureData provides only one function for streaming OSC packets, not discrimiation between the underlying transport channels (e.g. TCP vs serial).

As PureData is widely used to interface to sensors and microcontrollers via serial lines, they choose the spec-1.1, I guess. OSC via TCP is just not that common.

liblo supports both framing approaches as it is frequently used to interface to both :slight_smile:

Renoise in turn only processes raw OSC packets sent via TCP (I actually had to write a tiny TCP app to find out why none of my OSC packets were processed) which is neither compliant to spec-1.0 nor spec-1.1.

I thus would opt to use spec-1.0 (int32 size prefix) for Renoise, but I would be equally happy with spec-1.1.

Thanks for the detailed report. Pretty strange that the packet layout within the stream changes with the protocol. Wasn’t aware of this.

Will research and test this and fix/change this for an upcoming Renoise release. For now I can only recommend to use UDP then.