logical AND. It certainly does shave quite some time in the loops, will
> hello Lorien,
> i don't know this device, but after a quick glance at your code, i
> spot one possible optimisation...
> {var byte= 0xFF; 1000000.do{if((byte>=0xF8).and(byte<=0xFF), {11},
> {22})}}.bench;""
> {var byte= 0xFF; 1000000.do{if((byte>=0xF8) and:{byte<=0xFF}, {11},
> {22})}}.bench;""
> ie replace all .and() with and:{} and it'll save a few cpu cycles.
>
> also did you consider closing the serial port at command period?
> something like CmdPeriod.doOnce{this.stop}. your task will be killed
> anyway so there's no way - as it looks to me now - to recover a
> cmdperiod without manually closing the port and reinstantiating. so
> why not also stop+close at cmdperiod i mean. just a suggestion.
>
> _f
>
> 15 apr 2009 kl. 10.02 skrev Lorien Dunn:
>
>> Hi all,
>> this code allows me to use my infusionsystems usbmicrodig in
>> standalone mode without having the icubex editor running (the
>> usbmicrodig is a usb serial device rather than usb midi device). It
>> works very well indeed on my macbook, and should work on Linux (and
>> Windows if SerialPort works). But I'm still a comparative newbie to
>> supercollider and would appreciate some constructive criticism.
>> Advice for optimisation would be nice too- under heavy sensor load
>> with a 1ms sampling rate it's taken 20% of one core of a 2gHz core2,
>> though under normal usage it's between 2 and 4%.
>> the midi parser is loosely based on libmidi++ by Paul Davis.
>>
>> thanks,
>> Lorien
>>
>> LowLevelMidiParser
>> {
>> classvar noteOffStat=0x80, noteOnStat=0x90, polytouchStat=0xA0,
>> controlStat=0xB0;
>> classvar programStat=0xC0, touchStat=0xD0, bendStat=0xE0;
>> classvar sysexStat=0xF0, qFrameStat=0xF1, songPositionStat=0xF2,
>> songSelectStat=0xF3;
>> classvar tuneRequestStat=0xF6, eoxStat=0xF7;
>> classvar bufferSize=16;
>> var parserState, runnable, msgType, msgBuffer;
>> var <noteOn, <noteOff;
>> var <polytouch, <control;
>> var <program, <touch;
>> var <bend;
>> var <>sysex;
>>
>> *new
>> {
>> var self = super.new;
>> self.initLLMP;
>> ^self;
>> }
>>
>> initLLMP
>> {
>> noteOn = Array.fill(16,{|i| nil});
>> noteOff = Array.fill(16,{|i| nil});
>> polytouch = Array.fill(16,{|i| nil});
>> control = Array.fill(16,{|i| Array.fill(128,{|j| nil})});
>> program = Array.fill(16,{|i| nil});
>> touch = Array.fill(16,{|i| nil});
>> bend = Array.fill(16,{|i| nil});
>> sysex = nil;
>> parserState = \needStatus;
>> runnable = true;
>> msgType = noteOnStat;
>> msgBuffer = Int16Array.new(bufferSize);
>> msgBuffer.add(noteOnStat);
>> }
>>
>> emit
>> {
>> var chan = msgBuffer[0] & 0xF;
>> switch(msgType,
>> controlStat, { //bandwidth hungry (i.e. lots of them)
>> msgs first
>> control[chan][msgBuffer[1]].value(msgBuffer[2]) },
>> bendStat, {
>> bend[chan].value(msgBuffer[2]<<7|msgBuffer[1]) },
>> polytouchStat, {
>> polytouch[chan].value(msgBuffer[1],msgBuffer[2]) },
>> touchStat, {
>> touch[chan].value(msgBuffer[1]) },
>> noteOnStat, {
>> noteOn[chan].value(msgBuffer[1],msgBuffer[2]) },
>> noteOffStat, {
>> noteOff[chan].value(msgBuffer[1],msgBuffer[2]) },
>> programStat, {
>> program[chan].value(msgBuffer[1]) }
>> );
>> }
>>
>> channelMessage
>> { arg byte;
>> switch((byte&0xF0),
>> controlStat, {
>> msgType = controlStat;
>> parserState = \needTwoBytes },
>> bendStat, {
>> msgType = bendStat;
>> parserState = \needTwoBytes },
>> polytouchStat, {
>> msgType = polytouchStat;
>> parserState = \needTwoBytes },
>> touchStat, {
>> msgType = touchStat;
>> parserState = \needOneByte },
>> noteOnStat, {
>> msgType = noteOnStat;
>> parserState = \needTwoBytes },
>> noteOffStat, {
>> msgType = noteOffStat;
>> parserState = \needTwoBytes },
>> programStat, {
>> msgType = programStat;
>> parserState = \needOneByte }
>>
>> );
>> }
>>
>> systemMessage
>> { arg byte;
>> msgType = byte;
>> switch(byte,
>> sysexStat, {
>> parserState = \variableLength; },
>> qFrameStat, {
>> parserState = \needOneByte; },
>> songPositionStat, {
>> parserState = \needTwoBytes; },
>> songSelectStat, {
>> parserState = \needOneByte; },
>> tuneRequestStat, {
>> parserState = \needStatus; },
>> eoxStat, {
>> parserState = \needStatus; }
>> );
>> }
>>
>> parseByte
>> { arg byte;
>> var statusBit;
>> var size;
>> if((byte >= 0xF8).and(byte <= 0xFF)) {^nil}; //it's a
>> realtime message, ignore it
>> statusBit = byte & noteOffStat;
>> if((statusBit != 0).and(parserState == \variableLength))
>> {
>> if(byte==eoxStat)
>> {
>> msgBuffer = msgBuffer.add(byte);
>> sysex.value(msgBuffer);
>> }
>> {
>> "Incorrectly terminated system exclusive
>> message".postln;
>> };
>> };
>> if(statusBit != 0)
>> {
>> msgBuffer = Int16Array.new(bufferSize);
>> msgBuffer.add(byte);
>> if((byte&sysexStat) == sysexStat)
>> {
>> runnable = false;
>> this.systemMessage(byte);
>> }
>> {
>> runnable = true;
>> this.channelMessage(byte);
>> };
>> ^nil;
>> };
>> //it's a data byte
>> msgBuffer = msgBuffer.add(byte);
>> if(parserState == \needTwoBytes)
>> {
>> if(msgBuffer.size<3) {^nil};
>> parserState = \needOneByte;
>> };
>> if(parserState == \needOneByte)
>> {
>> this.emit();
>> if(runnable)
>> {
>> if(msgBuffer.size==3)
>> {
>> msgBuffer.pop();
>> msgBuffer.pop();
>> }
>> {
>> msgBuffer.pop();
>> };
>> }
>> {
>> parserState = \needStatus;
>> };
>> };
>> }
>> }
>> UsbMicroDig : LowLevelMidiParser
>> {
>> var port;
>> var device;
>> var task;
>>
>> *new
>> { arg dev="/dev/tty.SLAB_USBtoUART";
>> var self = super.new;
>> self.initUsbMD(dev);
>> ^self;
>> }
>>
>> initUsbMD
>> { arg dev;
>> device = dev;
>> UI.registerForShutdown({this.stop()});
>> }
>>
>> play
>> {
>> if(port.isNil)
>> {
>> port = SerialPort.new(
>> port: device,
>> baudrate: 115200,
>> databits: 8,
>> stopbit: true,
>> parity: nil,
>> crtscts: true,
>> exclusive: true
>> );
>> task = fork { loop { this.parseByte(port.read()); } };
>> };
>> }
>>
>> stop
>> {
>> if(port.notNil)
>> {
>> task.stop;
>> task = nil;
>> port.close;
>> port = nil;
>> }
>> }
>>
>> }
>
>
> #|
> fredrikolofsson.com klippav.org musicalfieldsforever.com
> |#
>
>
> _______________________________________________
> sc-users mailing list
>
> info (subscription, etc.):
>
http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml> archive:
http://www.listarc.bham.ac.uk/marchives/sc-users/> search:
http://www.listarc.bham.ac.uk/lists/sc-users/search/>