How best to slow down / queue outgoing OSC messages

My question is: is this a decent way to do this,

It depends on your application. If you can identify specific methods/functions that send many messages at once, you can instead send the messages in smaller batches and wait in between.

For example, if you want so send a large Array of messages, you can do something like the following:

someMethod { |array|
    var batchSize = 64; // some value
    var waitTime = 0.05; // some value
    forkIfNeeded {
        array.do { |msg, i|
            if ((i % batchSize == 0) and: { i > 0 }) { waitTime.wait };
            // send msg
        }
    }
}

For a practical example, check out Buffer.sendCollection in the Class Library.


Alternatively, is there a way to send OSC messages via TCP from SC?

There is:

n = NetAddr("localhost", 40000).connect({ "disconnected!".postln });
n.sendMsg('/foo', 1, 2, 3);

As you probably know, TCP is stream based and, unlike UDP, does not have a notion of packets. This means that applications must frame their messages so that the receiving end knows when a new message starts. NetAddr.sendMsg (in TCP mode) does this by prepending the OSC message with the message size (as a big-endian 32-bit integer). For example, the message ['/foo' 1 2 3] is actually send like this over TCP:

[ 0, 0, 0, 28, 47, 102, 111, 111, 0, 0, 0, 0, 44, 105, 105, 105, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3 ]

However, this only works if the receiving end uses the same framing mechanism! NetAddr.sendMsg (in TCP mode) is intended to be used to communicate with scsynth or other sclang clients.

Now, what do you do if your remote application uses another framing technique (e.g. SLIP)? Fortunately, you can also send raw bytes over TCP with NetAddr.sendRaw. In this case, you would first need to convert the OSC message itself to raw bytes with Array.asRawOSC and then do the appropriate framing yourself before passing it to NetAddr.sendRaw.