RPC


Remote Procedure Call via OSC


Creates an SC object whose method calls are converted to OSC commands and sent to a remote application (Processing, Ardour, MaxMSP etc) and returns the results from the other application.  RPC allows you to work with remote applications as though they were native and local.


RPC(name,netAddr,sendAPI,receiveAPI)


name a unique name for the other app


netAddr a NetAddr object with IP and port

sendAPI   (optional)

the paths that the other app responds to

a list of OSC paths

If nil then actually all methods on your rpc object will be sent to the remote

without any safety checks.


receiveAPI (optional) 

these are the commands the other app responds back to,

either as fixed by the manufacturer or as programmed by you in the other environment. 

Can be:

a string/symbol: which looks up a registered API

that API will be OSC mounted at /appname

an API object

that API will be OSC mounted at /appname

or a dict

which is used to make an 

and will be mounted on OSC at the root:

/command

/funcName



mountOSC(baseCmd)

will mount the receive API at baseCmd, overriding the defaults as stated above.

Actually only needed if you need to receive commands and do two way communication.


METHOD CALLS


method calls on this object are converted to OSC messages and sent

UNLESS the RPC class or its superclass Object implements a method by the same name.


In this case use the explicit call(selector, ... args)

method selectors with an underscore _ are converted to / 

a = RPC("ardour",NetAddr("127.0.0.1",3819));

so

a.ardour_ffwd

calls:

/ardour/ffwd

if there is an underscore already in the name then you can't do this:

/ardour/transport_play

instead use:

a.call('/ardour/transport_play')

a.call('/ardour/transport_stop')


call(oscPath, ... args)


call the path with the given args on the remote application



Processing Example



(

a = API('osctest');


// define

a.add('wiggle',{ arg x,y;

("wiggling" + x + y).postln;

"wiggled" + Main.elapsedTime // return value

});


a.add('click',{ arg x,y;

[x,y].postln;

"".postln;

p.setcolor(x,y,1);

p.response( Color(x,y,1).asString );

"You clicked" + x + y // return value

});



)


You need the http://www.sojamo.de/oscP5 library.


Open Help/osctest.pde and run it in Processing


(

p = RPC("osctest",NetAddr("127.0.0.1",12000),['/setcolor','/response'],'osctest');


p.mountOSC;


p.setcolor(255.rand,255.rand,255.rand);

)


p.response("your message here")




Ardour Example


http://ardour.org/osc_control


a = RPC("ardour",NetAddr("127.0.0.1",3819));


Note: due to all the underscores the niceties of RPC are a bit broken here.

You have to use call for these:


a.call("/ardour/transport_play")

a.call("/ardour/transport_stop")


a.ardour_ffwd


a.ardour_rewind


I could use aliases in the sendAPI :

\stop -> "/ardour/transport_stop",


/ardour/set_transport_speed [transport_speed]

where [transport_speed] is a float rangin from -8 to 8.

/ardour/goto_start

/ardour/goto_end

/ardour/add_marker

(adds marker to the current transport position)

/ardour/next_marker

/ardour/prev_marker

/ardour/locate [sample_pos] [with_roll]

where [sample_pos] is the target position and [with_roll] is a bool/integer (whether you want transport to be kept rolling or not).

/ardour/loop_toggle



Ardour's OSC is quite complete and could be used to record directly from SC via jack and edit files while you sleep.