= OSC In Field (beta8) = [http://opensoundcontrol.org/ Open Sound Control] (OSC for short) is a network protocol that's emerged as the dominant over-ethernet wire-random-things-together protocol. Originally developed as a modern successor to [http://en.wikipedia.org/wiki/Musical_Instrument_Digital_Interface MIDI] in the music software realm, today all manner of outward-looking applications and devices read and write OSC. Because of this popularity using OSC in Field is already extremely straightforward — just take your pick of Java-based or Pure-Python based OSC libraries, [PaletteOverview#ThePluginandExtensionmanager tell Field where they are located] and then start writing code that uses them. But because of its importance as the [http://glue69.ning.com/ glue that links interesting environments], and because Field is all about gluing things together, we've added a simple Field-ish OSC Plugin to the standard Field distribution. You are of course free to ignore the plugin and continue using your own OSC library. If you don't have something that you want to send OSC to or from this page is probably not for you yet. === Activate the plugin === The plugin is called {{{osc.mf}}} in the development tree (and will be {{{osc.jar}}} in beta8). Turn it on in [PaletteOverview#ThePluginandExtensionmanager plugin manager]. == Sending OSC messages == The OSC Plugin creates a couple of new properties that are available to your code. The first of interest is {{{OSCOut}}}. This lets you write: {{{ #!python _self.OSCOut.send("/banana/apple", (1, "peach", 3.2)) }}} That sends a message "to" {{{/banana/apple}}} containing an integer {{{1}}}, a string {{{"peach"}}} and a floating point number {{{3.2}}}. Pretty straightforward, no? This means that: {{{ #!python sheetSlider("banana", 0, update=lambda x : _self.OSCOut.send("/banana", (x, ))) }}} Gets you a slider that sends a floating point number between 0 and 1 to "/banana": [[Image(osc2.png, 430)]] Since OSC is (typically) an ethernet based protocol, OSC Plugin actually needs a port number and an address to send things to. '''Field defaults to an output port of 5501''' and an address of "255.255.255.255" — this is the broadcast address, everybody on your sub-net will get these messages. This is typically the kind of low configuration overhead that you want. To change the port and the address, use: {{{ #!python #changes the port to 11321 _self.OSCOut(11321).send("/banana/apple", (1, "peach", 3.2)) #changes the port to 11321 and the address to 18.85.9.1 _self.OSCOut(11321, "18.85.9.1").send("/banana/apple", (1, "peach", 3.2)) }}} To change the default port and address, use the "-defaultOutputPort" and "-defaultAddress" [StartupOptions command line options] == Receiving OSC Messages == Receiving OSC Messages in Field is, necessarily, a little more involved. It's one thing to tell some application or device what to do; it's quite another to be ''told'' what to do. Three vital lines of code get to receiving OSC messages in Field. ==== 1 — register a box of code ==== Firstly, tell Field that you want to receive an a box: {{{ #!python _self.OSCIn.dispatchOver(_self) }}} Whatever box you execute this in will be added to a list of visual elements that can respond to OSC events. Just as in the case of {{{OSCOut}}} you can make a custom input by appending a port number (for example {{{_self.OSCIn(10312).dispatchOver(_self)}}}) or by setting the [StartupOptions startup option -defaultInputPort]. Otherwise '''Field defaults to an input port of 5500'''. ==== 2 — add a callback ==== Next, you have to tell Field what code you actually want to run when the OSC event comes in. Following on from other event callbacks (for example [SimpleProcessingTutorial#Eventhooks mouse handling in the Processing Plugin]), we'll use [http://www.python.org/dev/peps/pep-0318/ Python Decorators]. {{{ #!python @_self.handleOSC_ def myCallback(address, *args): print address, args }}} ==== 3 — call update ==== Nothing happens — no callbacks are called — even though Field is receiving messages until you call {{{_self.OSCIn.update()}}} — this is to give you're code ultimate control over whether and when the callbacks happen. Typically, you'll want to call {{{_self.OSCIn.update()}}} a lot, so the simplest thing is to just write: {{{ #!python def doOSCUpdate(): _self.OSCIn.update() _r = doOSCUpdate }}} Start this code in a new box using [OptionClicking option click] or [[Image(InternalUtility:noodle.png)]]-!PgUp /[[Image(InternalUtility:noodle.png)]]-!PgDown (see VisualElementLifecycles). That's all you really need to know to receive OSC messages inside Field. == Advanced OSC usage — dispatching events == So far there's nothing here that isn't included in a standard OSC library (although we hope the way that callbacks get set and called is a little tighter than a typical Java-based OSC library). One extension to Field's OSC library is that the message hierarchy of OSC and the dispatch hierarchy of Field are integrated. Specifically, if you write {{{ #!python _self.OSCIn.dispatchOver(_self) }}} in some visual element that has a {{{subelement}}} called "banana" then all messages that start {{{/banana}}} get routed to ''that box'' instead — that is, only callbacks registered there will get called. [[Image(oscroot.png, 430)]] Matching proceeds as far down the [SelfAndProperties visual element graph as possible]. So if you have a box called "pear" that delegates to "banana" that delegates to the element that you designated as a message root with {{{.dispatchOver}}} then the address "/banana/pear" sends messages to only callbacks in that box. "/banana/*" sends messages to all callbacks in all children of "/banana" and so on. This marries OSC's idea of modular routing to Field's. = Status — where next ? = Field's OSC plugin is very new (although the underlying OSC code is very old, very tested and very straightforward) — expect bugs, but !OpenEnded are working on projects that use this code, so expect a fast response to [BugReports bug reports]. Functionality wise, it is currently lacking a complete set of OSC data-types — it handles integers, strings and floats and nothing more. We've never encountered much more than these things in real life, but it's easy to add more types. It's also lacking an idea of input message coalescing — if you take a long time between calls to {{{.update()}}} you'll always get all of the messages sent in the intervening interval. This is sometimes what you want, but not always.