Open Sound Control

Hi,

I am encountering some speed problem with OSCBundle sent through SLIPserial. It seems to be quite slow and I would like to know if I am doing something wrong with my code?

Here's a simple speedtest I have made to measure the time taken to build and send OSCBundles.

Code:
#include <OSCBundle.h>
#include <OSCTiming.h>


#ifdef BOARD_HAS_USB_SERIAL
	#include <SLIPEncodedUSBSerial.h>
	SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
#else
	#include <SLIPEncodedSerial.h>
	SLIPEncodedSerial SLIPSerial(Serial);
#endif

// Global variables
uint16_t timetagSent;
long timestamp;

void setup()
{
                
  //begin SLIPSerial just like Serial
  SLIPSerial.begin(38400);   // set this as high as you can reliably run on your platform
  Serial.begin(38400);
  #if ARDUINO >= 100
    while(!Serial)
    ;   // Leonardo bug
  #endif
}

void loop()                     
{
    OSCBundle bndl;
    // Prepare the OSC Bundle
    timestamp = micros();
    bndl.add("/i").add((int16_t) 1).add((int16_t)1).add((int16_t)1).add((int16_t)1);
    timetagSent = micros() - timestamp;
    Serial.print("Add a long OSC Message: ");
    Serial.println(timetagSent);
    timestamp = micros();
    bndl.add("/f").add((int16_t) 1);
    timetagSent = micros() - timestamp;
    Serial.print("Add a simple OSC Message: ");
    Serial.println(timetagSent);
    Serial.println("");
    Serial.println("");
    timestamp = micros();
    
    // Send the OSC Bundle through the Serial Port
    SLIPSerial.beginPacket();
    bndl.send(SLIPSerial); // send the bytes to the SLIP stream
    SLIPSerial.endPacket(); // mark the end of the OSC Packet
    bndl.empty(); // empty the bundle to free room for a new one
    timetagSent = micros() - timestamp;
    Serial.println("");
    Serial.println("");
    Serial.print("Send the bundle through SLIPserial: ");
    Serial.println(timetagSent);
}

Here's the timing measured:

  • Sending an OSC Bundle with 5 items : 216 µs
  • Adding 4 items in the same OSC Message : 41 µs
  • Adding 1 OSC Message : 18 µs

As you can see, building an OSCBundle takes time, but sending through SLIPserial is very long too.

Thank you for your help !
 
Opening SLIPSerial and Serial at the same time does not work for me.

However, I have been curious as to what the Ethernet performance would be using a WIZ820io. I have not broken it out to creating a bundle, sending a bundle etc. but one complete loop takes 860micro seconds so it is about three times slower than using the USBSerial with the numbers you are reporting (275us).
 
I picked up a WiFly RN XV a few weeks ago and got it working with a Teensy 3.1. I modded some code for the RNXV that I first came across at http://jamesgregson.blogspot.com/2013/03/setting-up-wifly-rn-xv-with-teensy-30.html. My version is here: https://gist.github.com/Neurogami/dcc819b64c88f22b008d

I first copied that initial example and hand-rolled the OSC. and that worked well enough as to demonstrate sending OSC over the WiFly.

I then grabbed the CNMAT OSC library to handle parsing, routing, constructing, and sending OSC messages.

The only OSC library file i pulled in was OSCMessage.h

Code:
#include <OSCMessage.h>

and I was able to accept, processes, and send back OSC. Pretty sweet.


You can see how I'm connecting to the WiFLy using the TX3 and RX3 , and using parts of the OSC library, here:

https://gist.github.com/Neurogami/08d7c876e35cc3359b42#file-oscteensylibexample-ino


My next step was to also have the Teensy emit MIDI over USB. This is where I ran into a problem.

In the Arduino IDE I need to set the USB type to "MIDI" instead of "serial" in order to get usbMIDI to behave. But the OSC library defines a set of SLIPEncoded* files and these conflict with using the USB port for MIDI.

My workaround has been to just remove all the SLIPEncoded* files from the library. So far that breaks nothing for me.

However, that seems a bit too hackish; one day I may want to actually send OSC over the USB serial port.

Is there some way to block the inclusion of the SLIPEncoded* stuff in a sketch, or otherwise prevent this collision? For example, can I add a #define or something?

The error I get if I have those SLIPEncoded* files in place looks like this:

Code:
In file included from /home/james/data/vendor/arduino-1.0.5/libraries/OSC/SLIPEncodedUSBSerial.cpp:1:0:
/home/james/data/vendor/arduino-1.0.5/libraries/OSC/SLIPEncodedUSBSerial.h:44:5: error: 'usb_serial_class' does not name a type


Thanks much for any pointers.
 
I got the same error trying to compile our OSC library on 86Duino. I am still tracking it down.
It is on the issue queue for the next release of the library.
 
Neurogami,
I checked the fixes to the usb_serial_class problem into the OSC github code base. It will be tested thoroughly in the coming week.

It is good to hear that the OSC library was useful to you. OSC is an encoding designed to be protocol independent and the library reflects that.

Incidentally, just pulling the OSC Message library function means you are not supporting OSC bundles which are a key part of OSC. They allow you to frame values that should be processed concurrently. This results in greater efficiency in many situations because most protocols have an especially efficient packet size, (e.g. 64bytes for USB, around 1000bytes for UDP etc).
 
Neurogami,
I checked the fixes to the usb_serial_class problem into the OSC github code base. It will be tested thoroughly in the coming week.

Sweet, thanks.

It is good to hear that the OSC library was useful to you. OSC is an encoding designed to be protocol independent and the library reflects that.

Yeah, I'm a big fan of OSC and once I sorted out the serial conflict it was pretty easy to get rolling over the WiFly. Thanks for that.


Incidentally, just pulling the OSC Message library function means you are not supporting OSC bundles which are a key part of OSC. They allow you to frame values that should be processed concurrently. This results in greater efficiency in many situations because most protocols have an especially efficient packet size, (e.g. 64bytes for USB, around 1000bytes for UDP etc).

For this particular case I don't yet have a need for bundles. This started out as a simple piezo-dirven MIDI thing, and as time went by and I thought about how to manage/config the settings the OSC library popped up on my radar.

I had thought about using assorted dials and switches, then considered using SysEx messages to send config details, and settled on making it configurable over UDP OSC.

Of course, now that I have basic OSC handling in place the device can send OSC as well as MIDI in response the piezo pads. I'm trying to reign in the options so I can just get something completed. :)

But I'm excited at the prospect of quirky, hand-held, battery-powered OSC controllers. I'm sure sending/receiving bundles will come into play.
 
But I'm excited at the prospect of quirky, hand-held, battery-powered OSC controllers.

Me too. I use x-OSC for these though.
Why? Because they don't have the complex problems the RN-XV has that people are "solving" with various timeouts and delays.
I have looked at the RN-XV command manual carefully and the many threads on this subject (from around 2012) and I don't feel there is a reliable way to use the serial byte stream to do UDP.
 
Me too. I use x-OSC for these though.

Are you referring to this: http://www.x-io.co.uk/products/x-osc/

£160 (~ $215) is a whole lot of money for wireless. If that price is correct, it seems a bit crazy.

Does it allow for sending arbitrary OSC address patterns and arguments? Does it accept arbitrary OSC address patterns and arguments? (That is, it will send and receive whatever I decide to program for.) The user manual seems to indicate you're stuck with a set of predefined address patterns.


Why? Because they don't have the complex problems the RN-XV has that people are "solving" with various timeouts and delays.

The only issue I have run into is that a straight-up "while(read more UDP bytes)" loop exits after the first byte; I had to add a delay(3) in there.

It's a hack but it works well for me so far and a plugable, multipurpose WiFly for $35 is a easier part for me to manage.
 
It has a good IMU, a fast DSP micro controller in it, a web server for configuration and yes, you work with their namespace. x-OSC saves thousands of dollars worth of my time for my employer. The last e-textile project I did took 3 minutes to get from the finished fabric sensor to sound synthesis control. x-OSC can support ad hoc mode so it takes a few seconds to find it on your wifi menu and then it is streaming OSC sensor data. I built an autonomous vehicle with OSC remote control in it in a few hours with IMU, optical sensors, motor speed control etc.
If you want to use Teensy 3.x with it, you can configure up to 4 serial interfaces that it streams over the wifi. I believe the new x-OSC will have the lipo charger too. It is quite hard to engineer all these things well from stacked Arduino thingies.
 
Hi,

I am encountering some speed problem with OSCBundle sent through SLIPserial. It seems to be quite slow and I would like to know if I am doing something wrong with my code?

Thanks for the measurements Julien. I am concerned about the interleaved Serial.print's. They are quite slow too. When I measure
performance in these situations I prefer to flip bits on spare digital pins and time with a scope or logic analyzer.
 
amundsen: That's not possible... The CCK doesn't support normal Serial USB, you can only do MIDI when connecting to a Teensy.
 
To do what ?

To connect analog sensors to Lemur, without the 7-bits resolution associated with standard MIDI messages.

I understand only MIDI is possible with such a connection but it's not clear whether Lemur can decode incoming 14-bits ("high res") MIDI control change messages. I'll check on the dedicated forum.

Thank you.
 
The Lemur app can decode 14 bits midi messages, you can also send any data using sysex messages. This requires scripting on the lemur side however.
 
USB OSC - 6 years later?

I am considering someday (perhaps in the distant future) adding a Teensy 3.0 Tools > USB Type option for OSC. This thread is intended to discuss how USB-based OSC might (eventually) work. If you're interested in OSC on Teensy3, please subscribe to this thread. When/if a test version is ever made, preliminary info or invitations to beta test will be posted here. (...) My thoughts on OSC so far are implementing a limited USB Ethernet interface. Fortunately, OSC uses only UDP protocol, which makes this doable, since all the complexity of TCP isn't needed.

Dear Paul,
New forum member here, but old Teensy user (about a decade).

It looks like this problem is not solved yet, and after discussing with Adrian Freed, it seems that there is hope.
We're thus harvesting potential sources with a few hackerspace friends, it's documented in this wiki:
https://wiki.fuz.re/doku.php?id=projets:fuz:USB-OSC

Is there anything you started (code, documentation, etc), that you could share so we can contribute or finish it?

Thanks in advance,
Cedric ; )
honnet.eu
 
Dear Paul,
New forum member here, but old Teensy user (about a decade).

It looks like this problem is not solved yet, and after discussing with Adrian Freed, it seems that there is hope.
We're thus harvesting potential sources with a few hackerspace friends, it's documented in this wiki:
https://wiki.fuz.re/doku.php?id=projets:fuz:USB-OSC

Is there anything you started (code, documentation, etc), that you could share so we can contribute or finish it?

Thanks in advance,
Cedric ; )
honnet.eu

This would be a great achievement! I am looking forward to this development!
 
Is there anything you started (code, documentation, etc), that you could share so we can contribute or finish it?

Nope, this was only ever at the initial planning stage.

Ask me again in a couple months. Right now, all dev cycles are going into Teensy 4.0.
 
Hello everyone.
- sorry to reactivate this old post, but I have a related problem:

Trying to transmit OSC (from Max/MSP) via slip-encoded Serial using CNMAT´s OSC lib. My code runs without problem on Leonardo-based Arduino ProMicro as well as on Teensy2. But it doesn´t really work on Teency LC or 3.2 (don´t have any other Teensy to test): while Integers are received fine, floats don´t get through. Weird.

There are several other posts in these forums with similar issues, but i didn´t find the solution to my problem.
Does anyone have an idea to get this to work?



Code:
#include <OSCBoards.h>
#include <OSCBundle.h>

#ifdef BOARD_HAS_USB_SERIAL
#include <SLIPEncodedUSBSerial.h>
SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
#else
#include <SLIPEncodedSerial.h>
 SLIPEncodedSerial SLIPSerial(Serial1);
#endif


float value0 = 0;
int state = 0;

void setup()
{
  SLIPSerial.begin(9600);   // set this as high as you can reliably run on your platform
  pinMode(LED_BUILTIN, OUTPUT);
}


void CV1(OSCMessage &msg)
{
    if (msg.isFloat(0))
    {
         value0 = (msg.getFloat(0) * 2);
         state = !state;
         digitalWrite(LED_BUILTIN, state);
    }

     if (msg.isInt(0))
    {
         value0 = (msg.getInt(0) * 2);
         state = !state;
         digitalWrite(LED_BUILTIN, state);
    }
}


void loop()
{
  OSCBundle bundleIN;
  int size;

  while(!SLIPSerial.endofPacket()) {

    if( (size =SLIPSerial.available()) > 0)
    {
       while(size--)
          bundleIN.fill(SLIPSerial.read());
     }
  }
    if(!bundleIN.hasError()) {

      bundleIN.dispatch("/CV/1", CV1);


      bundleIN.add("/CVout/1").add(value0);           //echo *2
      bundleIN.add("/state").add(state);

        SLIPSerial.beginPacket();
            bundleIN.send(SLIPSerial);
        SLIPSerial.endPacket();
        bundleIN.empty();
     }

}




/*   **maxpatch**
 * <pre><code>
----------begin_max5_patcher----------
789.3ocwWs0aaBCF8YxuBjeNKEyc1qUZutIsp8xTUjC3jRGXiLltzU0+6yWH
ozVfPR8XODh70iOe2N1OsvBrgtGWCr+r8OssrdZgkkpKYGVsss.kn8oEnZ0z
.D7uoatGrTODGumq5tfhxJw001vCCQZJoM7BLWsNXau5t3OVg0fB.121NTEh
mdWNY2ZFNkqGMLbkyR6jD42HG4WW2UNGWQdlBaw44StcfMmbDUYeOuXg7yxI
RPIKP6vuigUrbB2jjyyOVxHXTj7OO2wnWPuzy8BnmXC1fY8yC2A4wRavFDY2
37wQ4sfNJGUvntKOm98WG2cFpDywr0XBZSg5X3bAjktJkVVQqwlzu45ocX9d
qBDzMDpHpeGhtkR3aQo5icOwpwfNSrN+OpIBkA.84ja6rF8.Na8lFRVAdcAl
rieW28+UCmg3H8g091KIFo+b75h7pu98q62V5MVri7mXk2jWhuA0IJpl+n14
BxvaQMEGyu5yrG3qLzQp+B7FsZPjwxW3zc6JN23GYkhwBghzY9AwGBcdS.TW
p.mkLkAb4hslQEozmI+OYshVCPhtTQ3X9RXhw7kh.3rgp8cY0BfwJsoXcwN0
2H3.73XM7sBwRt.mpFdWjOVHn+5.l1iOnNGkwsSMpPWPj17DnpalLp212Xd6
QIHxnJBIwSmftFifh3Hwd7hVBqDoNPg+CD2aE8lj3Nz4+YIK5pJT5uru55eb
04dWzuzTT7Mwhw7IYK7UZP5quMjsH1X2Kc1DkGgw5x1iq8ZtD3gXLlkiJrSs
SBcbNyKxptB+oxlaungm+ocuvS5dUqBTjSd6yrTHK6+0VfZZCK8vws8kM1uf
cFtlmSP7bJo6bf5I0qQdx.Am.RR03OLRG1jwQxD.ELEfbL.RdNS.oXC.T7Dv
w2Dlt4hPxCKbFhEBloXN4aONcBarl0eLWj+bkF4NW.MESWz6.RWiEUU8.lU2
NaEFB8j6oLYy3kpl4DcS0U..L7C4GluRpDfXB0.tPJngoeW59PsdFnjJd5.o
Ius9tfcBHUZUDwsYpqZetuRRawyK9KPahLG3
-----------end_max5_patcher-----------
</code></pre>
 */


thanks!
 
Hello everyone.
- sorry to reactivate this old post, but I have a related problem:

Trying to transmit OSC (from Max/MSP) via slip-encoded Serial using CNMAT´s OSC lib. My code runs without problem on Leonardo-based Arduino ProMicro as well as on Teensy2. But it doesn´t really work on Teency LC or 3.2 (don´t have any other Teensy to test): while Integers are received fine, floats don´t get through. Weird.

There are several other posts in these forums with similar issues, but i didn´t find the solution to my problem.
Does anyone have an idea to get this to work?



Code:
#include <OSCBoards.h>
#include <OSCBundle.h>

#ifdef BOARD_HAS_USB_SERIAL
#include <SLIPEncodedUSBSerial.h>
SLIPEncodedUSBSerial SLIPSerial( thisBoardsSerialUSB );
#else
#include <SLIPEncodedSerial.h>
 SLIPEncodedSerial SLIPSerial(Serial1);
#endif


float value0 = 0;
int state = 0;

void setup()
{
  SLIPSerial.begin(9600);   // set this as high as you can reliably run on your platform
  pinMode(LED_BUILTIN, OUTPUT);
}


void CV1(OSCMessage &msg)
{
    if (msg.isFloat(0))
    {
         value0 = (msg.getFloat(0) * 2);
         state = !state;
         digitalWrite(LED_BUILTIN, state);
    }

     if (msg.isInt(0))
    {
         value0 = (msg.getInt(0) * 2);
         state = !state;
         digitalWrite(LED_BUILTIN, state);
    }
}


void loop()
{
  OSCBundle bundleIN;
  int size;

  while(!SLIPSerial.endofPacket()) {

    if( (size =SLIPSerial.available()) > 0)
    {
       while(size--)
          bundleIN.fill(SLIPSerial.read());
     }
  }
    if(!bundleIN.hasError()) {

      bundleIN.dispatch("/CV/1", CV1);


      bundleIN.add("/CVout/1").add(value0);           //echo *2
      bundleIN.add("/state").add(state);

        SLIPSerial.beginPacket();
            bundleIN.send(SLIPSerial);
        SLIPSerial.endPacket();
        bundleIN.empty();
     }

}




/*   **maxpatch**
 * <pre><code>
----------begin_max5_patcher----------
789.3ocwWs0aaBCF8YxuBjeNKEyc1qUZutIsp8xTUjC3jRGXiLltzU0+6yWH
ozVfPR8XODh70iOe2N1OsvBrgtGWCr+r8OssrdZgkkpKYGVsss.kn8oEnZ0z
.D7uoatGrTODGumq5tfhxJw001vCCQZJoM7BLWsNXau5t3OVg0fB.121NTEh
mdWNY2ZFNkqGMLbkyR6jD42HG4WW2UNGWQdlBaw44StcfMmbDUYeOuXg7yxI
RPIKP6vuigUrbB2jjyyOVxHXTj7OO2wnWPuzy8BnmXC1fY8yC2A4wRavFDY2
37wQ4sfNJGUvntKOm98WG2cFpDywr0XBZSg5X3bAjktJkVVQqwlzu45ocX9d
qBDzMDpHpeGhtkR3aQo5icOwpwfNSrN+OpIBkA.84ja6rF8.Na8lFRVAdcAl
rieW28+UCmg3H8g091KIFo+b75h7pu98q62V5MVri7mXk2jWhuA0IJpl+n14
BxvaQMEGyu5yrG3qLzQp+B7FsZPjwxW3zc6JN23GYkhwBghzY9AwGBcdS.TW
p.mkLkAb4hslQEozmI+OYshVCPhtTQ3X9RXhw7kh.3rgp8cY0BfwJsoXcwN0
2H3.73XM7sBwRt.mpFdWjOVHn+5.l1iOnNGkwsSMpPWPj17DnpalLp212Xd6
QIHxnJBIwSmftFifh3Hwd7hVBqDoNPg+CD2aE8lj3Nz4+YIK5pJT5uru55eb
04dWzuzTT7Mwhw7IYK7UZP5quMjsH1X2Kc1DkGgw5x1iq8ZtD3gXLlkiJrSs
SBcbNyKxptB+oxlaungm+ocuvS5dUqBTjSd6yrTHK6+0VfZZCK8vws8kM1uf
cFtlmSP7bJo6bf5I0qQdx.Am.RR03OLRG1jwQxD.ELEfbL.RdNS.oXC.T7Dv
w2Dlt4hPxCKbFhEBloXN4aONcBarl0eLWj+bkF4NW.MESWz6.RWiEUU8.lU2
NaEFB8j6oLYy3kpl4DcS0U..L7C4GluRpDfXB0.tPJngoeW59PsdFnjJd5.o
Ius9tfcBHUZUDwsYpqZetuRRawyK9KPahLG3
-----------end_max5_patcher-----------
</code></pre>
 */


thanks!
 
ok, everything is working fine.
the issue was introduced by using CNMAT´s odot-lib in Max, where float type is double by default. pushing everything through o.downcast did the trick.
 
Back
Top