Osc Query?

OSC Query?

Been messing around with OSC in other threads…

So, how do I query BPM? :)

Right now, GlobalOscActions.lua is all about “setting”, but what if I just want to get the current BPM?

Can we can some built-in boilerplate code for this? I don’t see any, yet.

I don’t know if this would work but do you see any way of using:

print(renoise.song().transport.bpm)  
``` ?  
  
Internally this this would maybe? work to then get a value to a notifier but sending it out one would probably need to use /evaluate I think.  
  
the lua code was taken from Renoise.Song.API.lua

You need a loopback connection to the client, attach notifiers to what you want to loopback in Renoise, and then send Osc messages to the client.
GlobalOscActions can not really do this cause we don’t know what the clients are interested in. We can not send loopbacks for “everything”.

See Osc Discussion (How Where What To Use Osc) for an example using Max and the track volume (from samBiotic)

You could also invent a message which sends a loopback on request only, like “/renoise/loopback_bpm”. All up to you. Nothing is standardized here…

Welcome to the fuzzy world of Osc. Everything’s possible, but nothing works (by default).

Ok, I see the samBiotic code.

Not really a “get” in the sense that I was looking for, more like two streams of data fighting each other.

But yeah, makes sense.

Thanks, but this won’t work.

Print will not send the value into the network stream.

Reading the OSC Specification, it’s clear that OSC Messages send, but don’t receive. They don’t behave like functions() which I had hoped, rather streams of data, which makes sense.

The metaphor is that you have to “open holes” on both sides and send info bidirectionally.

Taken from: http://cnmat.berkeley.edu/system/files/attachments/Nime09OSCfinal.pdf

So yeah, I was specifically looking for “command-response patterns” and they are specifically omitted.

OSC Sucks! /joke

i’ve started work on a renoise query API for OSC.

when i get home tonight to my main machine i’ll stick my code into a public repo so anyone who’s interested can collaborate on it.

so far i’ve only got one ‘request’ working, which is for note/instrument data on a single track in a single pattern, due to the 4k buffer limit with the renoise Osc.Message its impractical to send more data for one request.

in fact i think there might be a point where i’ll have to build a message factory which can keep track of message sizes and if necessary split them up and pack them into a bundle, or something like that. Ideally you dont want either side (the lua code or the other app) to care about buffer sizes, you just want to request your data and get it back. :)

I think what would be most useful at this point is to start to detail what the API looks like, i.e. what are the addresses and arguments (commands) and how is the response data formatted.

e.g.

[xml]
/renoise/pattern/track/get (int:pattern_index, int:track_index) {pattern data}
/renoise/instrument/get (int:instrument_number) {instrument data}
[/xml]

then define the response formats :

[xml]
{instrument data}
int index
string name
int number of samples
[int] (30) splitmap (list of 120 sample ids, 4 ids per int, so 30 ints)
[/xml]

that kind of thing :)

http://opensoundcontrol.org/publication/query-system-open-sound-control
A query system is proposed for inter-application control scenarios. The features consist of namespace exploration, documentation, type-signature, return-type-signature and parameter constraint specification, current-value polling, identification of common interpretation maps via osc-schema, as well as a general error reporting and reply mechanism.

interesting, thanks.

some good ideas there. might be worth seeing how well it would work in this environment.

i’ve read it a few times and thought about what they propose but im not going to use the main idea (/request/some/#thing -> #reply (s) etc…) because I think it makes the coupling between client and server too strong. Personally I think its better to maintain consistent use of the OSC addressing scheme at both ends, that way the client can receive data with or without requesting it. I can think of a couple of situations where this could be useful.

  1. bootstrapping. i.e. during the initial connection the client might just send /init and the server can respond with a series of messages which allow the client to create its initial state. e.g. instrument info, song info etc… So rather than explicitly requesting /renoise/instrument/#info and waiting for a #reply the server can just send /instrument messages which the client can parse as it does any other OSC message.

  2. change monitoring. Because changes will occur within the server which aren’t instigated by the client but which it will want to know about I think its worth implementing change monitoring requests, e.g. /track/dspchain/monitorchanges (int:trackindex) then at any point when the dsp chain is altered the server can send notifications to the client without an explicit request for that chain. Basically an implementation of the observer pattern across a network. Again it makes sense for the server to send normal OSC messages because its not really replying to anything.

What I would like to add is all the other stuff, node discovery, error reporting, doc requests and type info for messages. So that part is definitely useful. :)

I just converted my script into a tool and put it up here (its a mercurial repository)

At the moment you cant really do anything with it unless you use the terminal, and its mostly an adaptation of the built-in GlobalOsc script, with some minor changes and an implementation of a track data request. The major difference with this is that the return value of a registered handler is expected to be some form of OSC message which is sent back to the client.

I’ve also got an Actionscript client which i’ll commit to a repo later today, at the moment that just connects to the server, requests the note data from the first track and displays it in a grid editor (like the cubase drum editor, grid with red diamonds in it).

I think the first thing to do now is to make it work with UDP (just try to send data back to where the packet came from) and then design and implement the rest of the request API. :)

I’m not sure how to use it yet, but I got it to print FlashServer is Loaded. :)

Keep up the good work mdk

On a side note. Mercurial eh? I switched from CVS to SVN, like, last year (although I have worked with Perforce, too). I’m a luddite when it comes to SCMs…

this implies that you plan to build a stateful system.
for example: messages received after the /init request & reply process are dependent on the success of the init process itself.
care must be taken to ensure that this happens correctly.
perhaps separating them like so would provide an error checking process.

this feels a little strange having the client request which information it requires rather than filtering this client side.
you may run into problems down the line as again care needs to be taken in the init process of the monitoring system.

there is no real harm in sending everything a client could possibly need then having it discard what it doesn’t is there?

a stateless system, which avoids an init process and requires no previous data stream could be built by having the server send everything that’s monitored, when only one thing changes.
such a system may be preferential when using a non-assured transport such as UDP/IP.

this can already be done in the renoise api by attaching all notifiers to just one osc sending function.
see my monome tool for an example. you can watch the notifiers updating without the need for an actual device.

reference: Best Practices For Open Sound Control - CNMAT White Paper

This whitepaper is a bit outdated due to the OSC 1.1 specifications. Specially regarding the time-stamp descriptions:

Though the wildcard feature in 1.1 looks pretty interesting… It looks like it allows you to change several sub-addresses at the same time, if they all share the same name.
Haven’t tried if Renoise sneaky supports this anyway, you have to create your own OSC entries and then add identical subentries in all these entries to see if it wrks out.

I do. :)

I guess not, i’ll consider it for sure.

right, but my main target is to build an app in flash for controlling renoise. Flash only has HTTP sockets so im not going to be dropping packets.

That being said, I would like to include UDP as an option because it is more commonly used with OSC so I think it would be wise to heed your advice about not relying on the transmission of state. I guess it comes down to one of the common axes of development, building something specific for my needs and building something generic for everyone. :)

thanks, i’ll be sure to checkout your code.

surprisingly timetags have only been briefly discussed so far on the board in the Osc Sync: Tool request thread
they certainly aren’t needed for any proposed osc query system.

I haven’t tested the wild card pattern matching in renoise either.

flash also supports the sending and receiving of whole xml files in real time via sockets.

a java gateway for udp>osc>xmlsockets has been written called flosc

yeah, im aware of that, it was built when flash only had ‘xml’ sockets (which are actually HTTP sockets where a null byte is considered to be the 'end of message). Once flash got real HTTP sockets I wrote my own java OSC library based on Apache Mina so that I could talk OSC between java and flash. :)

https://www.assembla.com/wiki/show/osclib

(n.b. my flash OSC lib is also there as well as an mxj (java for max/msp) object)

if anyone notices the SuperCollider stuff, dont get excited its barely started and wont go anywhere, in fact i’ll probably delete it.

Also, I committed some edits to the code which I need to test (i.e. there are bugs and it probably doesnt work yet). The main changes are re-structuring the pieces into separate files as well as changing the system which maps OSC addresses to lua handlers. The original renoise code just uses a flat table, but i’ve changed it to use a tree to make bulk queries easier to implement, i.e. using regular expressions as part of the address : /renoise/song/* which would run all the zero-param handlers under /renoise/song like bpm, lpb, tpb etc…

I think i better test it tomorrow. :D

Its a shame that OSC Test App I saw in another thread is OSX only. Would be nice to have a cross-platform version.

what platform are you on?

if windows, this might work for you:
http://www.frieder-weiss.de/OSC

I’ve read other people have figured out how to get these to work,
but I have no idea how they got them to or proof they actually do.

linux mainly, but windows on my laptop when not at home.