Hey folks,
So, using a combination of suggestions, I have arrived at a much
simpler version of the code that seems to work great. I haven't
scaled it up to grab all 14 OSC message types, but I think that I'm in
a much better place to do so at this point. I might have too many
me.yield() calls now, actually, but it works tons better.
thanks again!
mike
---
8000 => int oscport;
// the messages for the osc objects
"/leftraw, i" => string leftraw;
"/leftavg, i" => string leftavg;
spork ~ oscListener( oscport, leftraw );
me.yield();
spork ~ oscListener( oscport, leftavg );
me.yield();
SinOsc raw => dac;
SinOsc avg => dac;
// a generic osc listener shred
fun void oscListener( int port, string osctype ) {
// create our OSC receiver
OscRecv recv;
port => recv.port;
recv.listen();
int val;
string type;
// create an address in the receiver, store in new variable
recv.event( osctype ) @=> OscEvent oe;
while( true ) {
// wait for osc event to arrive
oe => now;
while( oe.nextMsg() ) {
oe.getInt() => val;
osctype => type;
if( type == leftraw ) {
val => raw.freq;
}
else if( type == leftavg ) {
val => avg.freq;
}
me.yield();
}
}
}
while( true ) {
1::second => now;
}
On Mon, Apr 28, 2008 at 2:43 PM, mike clemow
Wow, okay... Trying to make sense of this...
Actually, come to think of it, Mike, why have the Bang object at all? Why not just move the code (the if statements) from the main loop into the oscListener loops/shreds, and replace the broadcast with actual functionality instead? Maybe there is some more advanced stuff that you haven't included that prevents this?
No, the only thing that I left out were the spork lines for the other 12 OSC listeners I need. :)
I guess the answer to your question is that I never thought of doing that because I'm still trying to wrap my head around Chuck's notions of scope. What you're indirectly telling me is that it's possible to access my SinOsc objects (and indeed my whole patch) from the other shreds, which I imagined would not be possible because of scope limitations. However, considering how classes work, I'm clearly not fully grasping reality here. I thought that the only way I could share data between shreds was an event.
Kassen, I completely forgot about me.yield(), which makes me feel pretty dumb. But I guess concurrency is not as simple as Chuck leads me to believe!
Dan, thanks for pointing out the bug. Honestly, I seem to remember running into issues where if I had one OSC message with a signature of "/test, i" and another with a signature of "/mike, i" and both were coming in on the same port, that Chuck couldn't tell the difference between them for some reason. I remember fixing this with multiple listeners on multiple ports. Perhaps I was doing something else wrong.
I'm going to mess around with these excellent suggestions and get back to you all. (sadly, this is all due today. oh well.)
Thanks! Mike
On Mon, Apr 28, 2008 at 12:10 PM, Stefan Blixt
wrote: Actually, come to think of it, Mike, why have the Bang object at all? Why not just move the code (the if statements) from the main loop into the oscListener loops/shreds, and replace the broadcast with actual functionality instead? Maybe there is some more advanced stuff that you haven't included that prevents this?
/Stefan
Yeah, but note that there are two shreds running this loop in parallell. So if one event on each port arrive at the same time, chances are that the first yield will hand over execution to the second shred, that in turn overwrites b.value and b.message. I think you need at least two Bang instances to be sure that this doesn't happen.
/Stefan
On Mon, Apr 28, 2008 at 5:10 PM, Kassen
wrote: 2008/4/28 Stefan Blixt
: I don't know about the segv signal, but it seems to me that there is
only one Bang instance that is shared by all iterations/shreds. This means
On Mon, Apr 28, 2008 at 6:00 PM, Stefan Blixt
wrote: that if two events arrive at this loop: while( oe.nextMsg() ) { oe.getInt() => b.value; osctype => b.message; b.broadcast(); }
the second's values will overwrite those of the first (value and
message from the first event will be lost).
I think that's right and I think the way around this would be
while( oe.nextMsg() ) { oe.getInt() => b.value; osctype => b.message; b.broadcast(); //yield to receiving shreds, //then continue processing the message cue me.yield(); }
This is the exact same principle I talked about earlier in this topic; if you don't yield you don't give the waiting shreds a chance to run. Advancing time here would probably not be a good idea.
Yours, Kas.
_______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users
-- Release me, insect, or I will destroy the Cosmos!
-- Release me, insect, or I will destroy the Cosmos! _______________________________________________ chuck-users mailing list chuck-users@lists.cs.princeton.edu https://lists.cs.princeton.edu/mailman/listinfo/chuck-users