DATA[size] is only the way that the server’s dumpOSC mode prints embedded OSC messages blobs. It is not an accurate representation of the packet’s complete contents.
Going back to the origin – /d_recv
documentation:
/d_recv
Receive a synth definition file.
bytes buffer of data.
bytes an OSC message to execute upon completion. (optional)
In the SC client, bytes
should be supplied as an Int8Array.
The first “bytes” refers to the binary representation of a SynthDef – this is produced by the message asBytes
. When you add
a SynthDef, it includes these steps (but folds them into one operation, so you don’t normally think about them). We can unpack them, though, for explanatory purposes.
// create a synthdef object
(
d = SynthDef(\demo, { |out = 0, freq = 440, amp = 0.1, gate = 1|
var eg = EnvGen.kr(Env.asr, gate, doneAction: 2);
Out.ar(out, (SinOsc.ar(freq) * amp * eg).dup);
});
)
d.asBytes;
-> Int8Array[ 83, 67, 103, 102, 0, 0, 0, 2, 0, 1, 4, 100, 101, 109, 111, 0, 0, 0, 7, 63, -128, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, ... ]
d.asBytes.size;
-> 445
SynthDef bytes
can get rather large – it would be wasteful for dumpOSC to print the entire contents.
In SC, you pack an OSC message by writing an array with the command path as the first item, and arguments beginning with the second item. Normally we just sendMsg
but you can also generate binary OSC:
['/d_recv', d.asBytes].asRawOSC
-> Int8Array[ 47, 100, 95, 114, 101, 99, 118, 0, 44, 98, 0, 0, 0, 0, 1, -67, 83, 67, 103, 102, 0, 0, 0, 2, 0, 1, 4, 100, 101, 109, 111, 0, 0, 0, 7, 63, -128, 0, 0, 0, 0, 0, 0 ... ]
The other bytes
is a second message (written also as an array), to run after the new SynthDef is ready. Normally this will be /s_new, because, what do you want to do after adding a new SynthDef? Probably hear it.
e = Synth.basicNew(\demo, s).newMsg(args: [freq: 220, amp: 0.15]);
-> [ 9, demo, 1000, 0, 1, freq, 220, amp, 0.15 ]
['/d_recv', d.asBytes, e].asRawOSC;
If you sendRaw
this message to a running server, then it should play.
s.sendRaw(['/d_recv', d.asBytes, e].asRawOSC);
… which normally we elide with a sendMsg
or just SynthDef().play
, but it gets down to this under the hood.
So this is what your client needs to do – basically everywhere that there is a “completionMessage” (you’ll see this a lot with Buffer methods), it should be handled like e
here.
TBH I haven’t looked at the C primitive for asRawOSC, so I’m not sure exactly how it’s converting the embedded sub-message array (e
in the example). But it’s all there in the source code, and it should be straightforward to translate to Pharo’s OSC library.
hjh