Forum rss-feed

Forum

Developers: Prototype open-source OSC EigenD agent available

STICKY

written by: geert

Hi everyone,

Given the current developer interest and barnone's motivation to dig into the code, Jim has spent some time creating a prototype EigenD agent that is able to output EigenD data streams directly through OSC.

This implementation is just a start and was quickly written in two days to bootstrap the learning process of users that wish to participate in the development. Its serves both as a documented example for creating agents as well as an initial step towards the OSC plans that we've been making. As time progresses, our OSC support will mature and the EigenD OSC protocol will be formalized in more detail, but this should give you an idea of the direction we're heading into. We've discussed various approaches towards how to handle the OSC representation over the network and have hit limitations of the network stack in the past due to the massive amount of performance data that the Eigenharp generates. This performance data is essential to the expressiveness of the Eigenharp and we obviously want to allow it to be exposed in as much detail as possible. The document named "OSC" that comes with this example agent briefly explains what we consider the best approach, it will mature as we further work on the OSC support.

The document named 'Roadmap' explains how to use this OSC agent and gives a high-level developer-centric explanation of EigenD's internal architecture. The source code is heavily documented and should make it easy to adapt towards any other functionalities that you might want to implement with an agent.

The source code can be found on GitHub in the 1.4 branch of EigenD. Here is a direct link towards the source of just the plg_osc agent:
https://github.com/Eigenlabs/EigenD/tree/1.4/plg_osc

More information about getting involved in EigenD development can be found on this wiki page:
http://www.eigenlabs.com/wiki/Developers/

Please realize that we have very limited resources to provide direct support to external developers as we're hard at work wrapping up the initial release of EigenD 2.0 and Workbench. We hope that this example will give you enough information to make EigenD development more accessible.

Take care,

Geert

written by: steveelbows

Thu, 22 Mar 2012 17:19:42 +0000 GMT

Did the number of floats being output by key messages change with version 2.0.38 compared to version .36 ? There seem to be a few less to me, so I had to redo my OSC-receiving code, but perhaps it was something I did to my setup rather than a change you made?


written by: dhjdhj

Fri, 30 Mar 2012 14:03:15 +0100 BST

I don't actually understand the purpose of all the values that arrive in OSC messages for the keyboard.
I noted there are 10 values when a key is touched/moved (including some duplicates) and there are 22 values (all 0 except the event number) when a key is released
This actually makes my test easier as I can just use length to detect whether a key is up or down (I was using a regex in earlier code) but I'm curious as to the motivation for the current packets. I know it may change.


written by: steveelbows

Fri, 30 Mar 2012 15:57:50 +0100 BST

Its an interesting question, I've been meaning to look at the OSC source code to learn more about this.

For my initial application I've taken a really simple approach that seems to work just fine:

I completely ignore the event number.
I ignore the 0 0 0 0 0 etc key released messages, since just before I get that message I also seem to consistently receive one where the pressure value = 0, so I just use that to tell me that a key has been released.
I use the first OSC value to determine the key, and the last 3 for pressure, yaw & roll. I ignore all the others.

As for how many values are sent, need to be careful with how we talk about this stuff. Personally I don't count the event number as being a value, since it is part of the OSC message address rather than being part of the OSC value part of the message. I mean obviously its still a bit of real data, its just Im used to talking about OSC-related things strictly from the point of view of how OSC messages are structured, and the address part is quite different to the value parts.

So in my language there are 9 values for key pressed messages, and 20 for key released messages (not sure why I am counting 2 less than you for key released one rather than one less).


written by: dhjdhj

Fri, 30 Mar 2012 20:27:02 +0100 BST

Arggg, no.....(falling off a cliff)....I loved that they were different lengths (grin). Made it easy to detect on/off.

Is the length of the Key Off the same or can you (hopefully) just send a key event by itself as nothing else is needed.


More seriously, what is the purpose of having the four values row,col, course, and key? Cannot any of these can be calculated from either the key or the row/col pair. It may be that I don't understand "course" but I thought that was just vertical column, so wouldn't that be the same as "col"?


written by: geert

Fri, 30 Mar 2012 20:29:29 +0100 BST

The 22 values when the keys are released is a bug, I fixed it now, sorry about that. The format should be the same as for the others.

This is a breakdown of the values after the format specifier:

event id, row, column, course, key, hardness, pressure, roll, yaw

Take care,

Geert


written by: geert

Fri, 30 Mar 2012 20:31:02 +0100 BST

dhjdhj, course, key, row, column is part of the new physical and musical key positioning in EigenD 2.0. It's fully explained from the 'Physical and musical mapping' section onwards on http://www.eigenlabs.com/wiki/2.0/Keygroups/

There's not really a key off, but rather an event end where all the values for the different values are basically set to 0, this is part of the EigenD architecture. It's not a collection of messages but streams of data for distinct signals.


written by: geert

Fri, 30 Mar 2012 21:42:19 +0100 BST

@steve, I think you're misreading them, those are the course and key numbers. Each instrument is set up as one long course, but several rows, keygroups are able to change these mappings.


written by: dhjdhj

Fri, 30 Mar 2012 21:42:29 +0100 BST

Thanks for the ref, I'll take a look.

I understand (now) that since the data that comes in through OSC might be different depending on how the connected agent is configured.

In my system, things like scaling and offsets between columns are done further downstream since, for me, the OSC is the "raw" info.


written by: steveelbows

Fri, 30 Mar 2012 21:43:05 +0100 BST

Interesting stuff, thanks for the explanation.

As someone with a Pico I sense an anomaly between the way rows are described in the document you linked to, and what comes through OSC. What you are saying is the row value part of the OSC message actually gives me values of 1 to 18 for the playing keys, and 19-22 for the other buttons on the Pico. Is this just because Im going straight from the Pico keyboard to the OSC agent, and not using a keygroup, or is it some kind of ambiguity about the way terms like row are used?


written by: dhjdhj

Sat, 7 Apr 2012 18:58:12 +0100 BST

Is there any chance the OSC output string could be changed slightly when it's sending out the event that a key is NOT pressed. Given that spaces are used to separate the different arguments, using a space to represent "no key" makes parsing much more awkard and more expensive than it needs to be.
Since key numbers start at 1, how about sending out a 0 ?


written by: steveelbows

Sat, 7 Apr 2012 20:31:24 +0100 BST

Im a bit confused by your description, it doesn't match my prior understanding of OSC. OSC itself is not a format where all value data is sent separated by spaces, its a lot more formal/optimised/supportinve of different data types than that.

So Im guessing that your view of OSC as having message values separated by spaces is to do with how that data is being given over to you inside your dev environment (e.g. MAX). Even with this in mind Im a bit confused by exactly which EigenD OSC messages you are referring to them and what data is actually being sent, can you give an example of the output you are talking about?


written by: steveelbows

Sat, 7 Apr 2012 20:52:25 +0100 BST

The OSC plugin meets my current needs just fine, but before it gets more set in stone I feel the need to talk about whether its output is really in keeping with the spirit of OSC.

The most important issue I can see in this regard is the way you are making the event ID part of the OSC Address String, compounded by the fact that when discussing this stuff, some of you are talking as if this event number is the first of the OSC values. Its not, its part of the address. And thats important and raises issues because OSC message addresses are supposed to be analogous to methods/procedure calls. So by making the event ID part of the OSC message address, you are sending this data in a manner that makes it equivalent to part of the name of a function, not simply one of the arguments that is being passed to that function.

In practice this matters because of how some environments, especially node-based graphical programming ones, are setup to enable people to easily process stuff based on receiving different OSC message address patterns. Sometimes it is relatively trivial to workaround the EigenD OSC Message Address format, as it is in the programming environment Im using (Unity 3D), but I still think the point is worthy of at least some consideration.

To be clear, Im talking mostly about the fast stream of data for key presses, as I haven't really looked at the other OSC data from EigenD much yet. There are several possibilities, but firstly move the event id data to be an additional OSC value instead of being the last part of the address. Otherwise you are either asking people to perform additional parsing of the OSC address to treat this last part of the address as a value rather than part of the method name, or people will have to have a method to deal with every possible event id.

I hope this makes sense. In practice this issue can be trivial to overcome, especially if your environment supports wildcards in OSC Addresses, but I still think its worth thinking about given the desirability of consistency between EigenD and existing standards. If this post fails to make sense then please take a look at the later sections of the OSC 1.0 spec document, where the sections on OSC semantics will hopefully clarify what Im on about.

http://opensoundcontrol.org/spec-1_0


written by: steveelbows

Sat, 7 Apr 2012 21:07:14 +0100 BST

I should also say that although I have just argued against event IDs being part of the OSC Address, there are actually some circumstances where having the key number as part of the address would aid simple programming in certain environments. For example you can call different methods depending on which key has been pressed without first having to look at any of the OSC values. This sort of thing is quite commonly seen with the Lemur or TouchOSC, where the name of the interface component is part of the message address (e.g. /1/fader1 or 1/fader/1 etc).

However this wouldn't be suitable for all scenarios, e.g. its very unlikely you'd want to wire up all of a large Eigenharp instruments keys in this way, you wouldn't want a different method for every single key, you'd pass the key as an argument as happens presently. So the usefulness of this would likely be for certain keys that drive special functions. Or for the Eigenharp Pico.

On a related note I could make an even simpler case that perhaps the key off message should have its own OSC message Address.

Anyway Im not particularly arguing in favour of any of these, just throwing them out there to cover a range of OSC possibilities. Making it so that the Event ID is not part of the OSC Message Address is the one thing I am arguing strongly in favour of here.


written by: dhjdhj

Sat, 7 Apr 2012 21:11:16 +0100 BST

(By string, I mean the sequence of ASCII values that arrive in a UDP message)

I've had to do some unpleasant hacks to get the stuff through the OSC parser including some special detection when the second parameter is just a space (ascii 32 actually) because the max objects that process integers (converted from incoming ascii strings) just send nothing if the incoming string cannot be converted to a valid integer. Thus when a note is released, some objects will just stop. Originally I was using a regex and then when the last version had the bug where the "key off" produced 22 values, it was trivial to just check the length to control the flow. Now that we're back to the same length for both ON and OFF events, I'm back to using more complex hacks again.

That would be simplified significantly if the parameters could always be interpreted the same way. Normally the second parameter can be trivially converted from a string to an integer and we can do what we want. However, if a string is allowed to NOT have an integer value, then extra work has to be done to see if it is a number first.

While I'm able to deal with the event number using the wildcard trick, the processing still ends up more complicated than it should

I'd rather see something like
/keyboard_1/key eventNumber keynumber other parameters
and
/keyboard_1/off eventNumber

which can then be trivially routed with a single OSC object that recognizes /key and /off

In fact the keyboard_1 might also need to be parameterized if there can be multiple keyboards but like "steveelbows" said before, that doesn't matter to me since I will never have more than one keyboard at the input side.


written by: dhjdhj

Sat, 7 Apr 2012 21:19:02 +0100 BST

Yes, we're on the same wavelength --- I think we posted previous comments at the same moment....

On a related note I could make an even simpler case that perhaps the key off message should have its own OSC message Address.


written by: dhjdhj

Mon, 9 Apr 2012 14:15:20 +0100 BST

I'm adding support for the strips on the Alpha. I've noticed that there are spaces in the names --- I believe that's not allowed
E.g.
/keyboard_1/strip position 2/0 . 0.03125
/keyboard_1/absolute strip 2/0 . -0.246582
I can work around it but wondering if it might make sense to replace those spaces with underscores (say)

D


written by: geert

Tue, 17 Apr 2012 10:05:16 +0100 BST

I've replaced those spaces, thanks for noticing that.


written by: dhjdhj

Thu, 26 Apr 2012 11:19:45 +0100 BST

I'm just curious. Older versions of EigenD supported incoming OSC messages for setting the LEDs. Why was this replaced by an http server approach? UDP is several times faster, which counts when once wants to use up as little time as possible at the transmission end.

As an aside, I've been experimenting with Lemur as an extra controller and although I can send Lemur data to Max via OSC and then Max can send it on to EigenD as REST request, it would be nice to be able to send te commands directly from Lemur


written by: geert

Fri, 27 Apr 2012 08:10:53 +0100 BST

Hi dhj,

EigenD has never supported setting the leds from the outside in any fashion. There is an external MIDI Illuminator agent done by Ferninand that uses the Stage OSC protocol to set lights. This protocol isn't intended for this usage and its internal bookkeeping is quite expensive, magnitudes more than the difference between UDP and TCP.

We're still thinking about general support for OSC input into EigenD agents but there's no timeline for it. This will be a general solution and not just for lights. The reason why the Illuminator agent has a built in HTTP server is that it allows us to evolve it to provide a remote user interface for non technical users to control the lights.

Best regards,

Geert


written by: dhjdhj

Fri, 27 Apr 2012 13:02:39 +0100 BST

Thanks, Geert, it's helpful to know the thinking. I'm involved in a project that I'm not yet allowed to talk about but I'm doing all the keyboard parts with the Alpha. We wanted to leverage the LEDs to sync with some MIDI loops and volume peaks (purely for show) but the response times were noticeably aging so we gave up. Not sure how much of that was REST and how much was due to LEDs being processed on low priority thread.



Please log in to join the discussions