sonic-pi icon indicating copy to clipboard operation
sonic-pi copied to clipboard

how to send $[ $] flag for multiple array on erlang osc ?

Open rexmalebka opened this issue 4 years ago • 5 comments

Hi I was using osc.erl file to send OSC via udp, trying to imitate NetAddr("127.0.0.1",57110).sendMsg(\n_set, 1010,\freq, $[,200,400,$]); native function that sets an array as an argument of a synth, but couln't make it work for $[,$] flags on supercollider

  • sending msg like Msg = osc:encode(["/n_set",1004, "freq", [300,800]]) fails
  • sending msg like Msg = osc:encode(["/n_set",1004, "freq", $[,300,800,$]]) sends it like isiiii :
"/n_set", 1004, "freq", 91, 300, 800, 93 ]
size 44
   0   2f 6e 5f 73  65 74 00 00  2c 69 73 69  69 69 69 00   |/n_set..,isiiii.|
  16   00 00 03 ec  66 72 65 71  00 00 00 00  00 00 00 5b   |....freq.......[|
  32   00 00 01 2c  00 00 03 20  00 00 00 5d                |...,... ...]|

when it should look like this:

[ "/n_set", 1003, "freq", [ 400, 400 ]
size 36
   0   2f 6e 5f 73  65 74 00 00  2c 69 73 5b  69 69 5d 00   |/n_set..,is[ii].|
  16   00 00 03 eb  66 72 65 71  00 00 00 00  00 00 01 90   |....freq........|
  32   00 00 01 90                                          |....|

I tried creating {'['} {']'} clauses for encode_flags like:

encode_flag({'['})             -> $[;
encode_flag({']'})             -> $];

but could not make it work for encode_string,

encode_arg({'['})                -> encode_arg("");
encode_arg({']'})                -> encode_arg("");

that resulted on:

[ "/n_set", 1004, "freq", [ 0, 300, ], !unknown tag '?' 0x00 ! ]
size 44
   0   2f 6e 5f 73  65 74 00 00  2c 69 73 5b  69 69 5d 00   |/n_set..,is[ii].|
  16   00 00 03 ec  66 72 65 71  00 00 00 00  00 00 00 00   |....freq........|
  32   00 00 01 2c  00 00 03 20  00 00 00 00                |...,... ....|

I'm not familiar with OSC format, but could be possible to have some way of sending flags? I know that maybe {'['} could be a hacky way and should be a better way to do it so

thanks in advance

rexmalebka avatar Dec 07 '20 23:12 rexmalebka

I think I solved it adding to osc.erl

encode_flag({int64,_})            -> $h;
encode_flag({time,_})             -> $t;
encode_flag('[')             -> $[;
encode_flag(']')             -> $];
encode_flag(I) when is_integer(I) -> $i;
encode_flag(X) when is_list(X)    -> $s;
encode_flag(X) when is_atom(X)    -> $s;
encode_flag(X) when is_float(X)   -> $f;
encode_flag(X) when is_binary(X)  -> $b.

encode_arg(X) when is_list(X)    -> encode_string(X);
encode_arg('[')                  -> <<>>; %<<X:64/unsigned-little-integer>>;
encode_arg(']')                  -> <<>>; %<<X:64/unsigned-little-integer>>;
encode_arg(X) when is_atom(X)    -> encode_string(atom_to_list(X));
encode_arg(X) when is_integer(X) -> <<X:32>>;
encode_arg(X) when is_float(X)   -> <<X:32/float>>; %
encode_arg({int64,X})            -> <<X:64/unsigned-little-integer>>;
encode_arg(X) when is_binary(X)  -> encode_binary(X).

so I got the correct flags and encoded data,

Msg = osc:encode(["/n_set",1006, "freq", '[',500,501,']']),
gen_udp:send(Socket, "127.0.0.1", 57110,Msg),

on SC:

[ "/n_set", 1006, "freq", [ 500, 501 ]
size 36
   0   2f 6e 5f 73  65 74 00 00  2c 69 73 5b  69 69 5d 00   |/n_set..,is[ii].|
  16   00 00 03 ee  66 72 65 71  00 00 00 00  00 00 01 f4   |....freq........|
  32   00 00 01 f5      

That does work on my synthdef:

(
(SynthDef(\hola,{|freq=#[440,400]|
	freq.poll;
	Out.ar(0,SinOsc.ar(freq))
}).add);
NetAddr("127.0.0.1",57110).sendMsg(\dumpOSC, 3);
NetAddr("127.0.0.1",57110).sendMsg(\s_new, \hola, 1006,0,0,1);
)

rexmalebka avatar Dec 08 '20 00:12 rexmalebka

Interesting! cc/@xavriley - any thoughts on this and whether it affects the plans for fast_osc?

ethancrawford avatar Dec 08 '20 03:12 ethancrawford

Thanks for looking into this - I need to refresh my memory but this looks pretty good.

I think it's backwards compatible with the rest of osc.erl so we could merge this into the erlang code and then take a look at the Ruby side separately.

That being said, I thought that SC didn't support the [ and ] syntax based on this

"r" (RGBA color), "S" (symbol), and "[" and "]" (array start and end) are not supported. https://doc.sccode.org/Guides/OSC_communication.html

The array arguments I'd been looking at were based on SC interpreting a blob type in an OSC message as an Int8 array. It may be that the page I'm referencing is out of date though.

xavriley avatar Dec 18 '20 13:12 xavriley

yee, some docs say it's possible, others no, I got Supercollider 3.11.2.

I even don't know if this file it's still being used nowadays, I'm using it in a personal project as it's the most complete implementation of OSC for erlang, would be nice to make it into a lib in http://hex.pm/

Do you want me to make it into a pull request with remaining symbols ?

rexmalebka avatar Dec 18 '20 18:12 rexmalebka

I'd be happy to see this added to our osc.erl which we're still using. For a PR it would also be great to see some tests added here: https://github.com/sonic-pi-net/sonic-pi/blob/dev/app/server/beam/tau/test/erlang_tau_osc_test.exs

samaaron avatar Jul 20 '22 09:07 samaaron