PDA

View Full Version : sending osc from c++



koleeko
04-26-2010, 05:18 AM
I am almost done building a custom controller. It sends serial data to a program I wrote in openFrameworks. I'm able to send OSC messages to Osculator pretty easily and then have them play on a vst synth in Ableton. My problem is that when I send the OSC messages to Osculator, a note stays on for a second and then goes off. If I change the code to continuously send messages, it just loops really fast. How do I get Osculator to behave the way it does with Touch OSC? For example with the keys template, the notes will stay on as long as you hold a key down, even though Osculator only registers the OSC message for a short time, not continuously.

camille
04-26-2010, 08:43 AM
Hey Koleeko,


I guess there is a problem with the messages you send to OSCulator.

You should send a message with a value over 0.5 to trigger a note ON, and under 0.5 to trigger it OFF.

There is no need to "sustain" the note and this has nothing to do with TouchOSC.


Cheers,

Cam

koleeko
04-26-2010, 08:30 PM
Thanks Camille. I'm honestly not sure what the message values are that I'm sending out. Right now the way I have it set up, I send a message and I designate an address that I want it sent to. In C++ (openFrameworks), my code looks like this:


ofxOscMessage m;

m.setAddress( "/keyz" );

m.addStringArg( "One" );

sender.sendMessage( m );


I do see the messages registering in Osculator, so It's definitely getting a note ON. The note just doesn't stay on. It plays and ends quickly. I'm trying to get it to play a note until it gets a note OFF message.

camille
04-26-2010, 08:49 PM
Alright, I see.

What you should do rather, is send a float argument as 1.0 when you want the note ON, and 0.0 when you want the note OFF. Thus, if you want to turn a note ON:



ofxOscMessage m;

m.setAddress( "/keyz" );

m.addFloatArg( 1.0 );

sender.sendMessage( m );




If you send a string argument to OSCulator and bind an event to that message, it will be interpreted as a "transient" event, meaning it will be ON for a short while and quickly come back to 0.0.

koleeko
04-26-2010, 09:09 PM
camille,


That doesn't seem to have changed much. My code now looks like you suggested:


if (myByte == 0){

ofxOscMessage m;

m.setAddress( "/keyz" );

m.addFloatArg( 0.0 );

sender.sendMessage( m );

}


else if (myByte == 1){

ofxOscMessage m;

m.setAddress( "/keyz" );

m.addFloatArg( 1.0 );

sender.sendMessage( m );

}


(I'm reading bytes coming in from the serial port to determine which notes to trigger. Only one byte is being read at a time, so I'm pretty sure it's not turning itself off. There's also definitely only one message at a time registering in OSCulator.)


It seems to respond exactly the same with the new code. On for a short time then off. The only difference is that in my list of messages, I now have 0 and 1 in addition to the One, Two, Three, etc underneath /keyz. Otherwise it seems to be exactly the same.

camille
04-26-2010, 10:10 PM
Are you sure you are not sending 1 and 0 at the same time for the same address?

I don't have much details about your device, but it seems it has several buttons, then you should use a different address for each of them. For example you could use "/keyz/one", "/keyz/two", and so forth, or "/keyz/1", "/keyz/2", etc.

koleeko
04-26-2010, 10:55 PM
Camille,

I'm pretty sure that I'm only sending one message at a time and not a 1 and 0 simultaneously. I'm only reading one byte at a time from my sensors which I print to Xcode's console when they are read. I only see one message printing to the console at a time and I only see one little box light up green in OSCulator. I had each button (there are 20 total) set up with a different string or float:


m.setAddress( "/keyz" );

m.addStringArg( "One" );


or


m.setAddress( "/keyz" );

m.addFloatArg( 1.0 );


I just tried giving each an entirely different address as you suggested:


if (myByte == 0){

ofxOscMessage m;

m.setAddress( "/keyz/zero" );

sender.sendMessage( m );

}


else if (myByte == 1){

ofxOscMessage m;

m.setAddress( "/keyz/one" );

sender.sendMessage( m );

}


still nothing. ( ; _ ; )

camille
04-26-2010, 11:16 PM
he he, the problem here is that you are sending different values to different addresses.

What I really suggested previously was to assign a different address to different buttons, and then if they are pushed, add the float argument 1 or 0 depending on if they are pressed or released.


Something along the lines of (pseudo code):



string address = GetButtonAddress (); // returns /keyz/one, /keyz/two, depending on the button being pressed

float state = GetButtonState (); // returns 1.0 or 0.0, depending on if the current button is being pressed or released


ofxOscMessage m;

m.setAddress( address );

m.addFloatArg( state );

sender.sendMessage( m );

koleeko
04-26-2010, 11:32 PM
AWESOME! That totally fixed it. My problem was because I have the same zero message regardless of what key is going off. I was thinking of zero as one of my 21 possible byte / OSC messages, instead of thinking of ON / OFF message pairs. Since I only have one zero message, I just need to have zero send OFF to all 20 of my addresses. Thanks so much. This was the last piece of code I needed to complete my project.