Some fixes, formatting
parent
fc469e0fa3
commit
5a764293fc
265
SLIPDecoder.sc
265
SLIPDecoder.sc
|
@ -23,12 +23,10 @@ SLIPDecoder {
|
||||||
// Buffer for OSC bundles/messages
|
// Buffer for OSC bundles/messages
|
||||||
const bufferSize = 4096;
|
const bufferSize = 4096;
|
||||||
|
|
||||||
var <>deviceName, <>rate, <>prepend, <port, decode, trace, stop, <reader;
|
var <>deviceName, <>rate, <>prepend, <port, <>trace = false, <running = false, <reader;
|
||||||
|
|
||||||
*new { |deviceName="/dev/ttyUSB0", rate=115200, prepend=""|
|
*new { |deviceName="/dev/ttyUSB0", rate=115200, prepend=""|
|
||||||
deviceName.postln;
|
^super.newCopyArgs(deviceName, rate, prepend);
|
||||||
//^super.newCopyArgs(deviceName, rate, prepend).init;
|
|
||||||
^super.newCopyArgs(deviceName, rate, prepend);//.init;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
readInt32 { |byteArr|
|
readInt32 { |byteArr|
|
||||||
|
@ -43,22 +41,19 @@ SLIPDecoder {
|
||||||
// Return array [string, strlen (bytes)]
|
// Return array [string, strlen (bytes)]
|
||||||
readNextString { |byteArr|
|
readNextString { |byteArr|
|
||||||
var str = "", idx = 0;
|
var str = "", idx = 0;
|
||||||
while({ (idx + 4) <= byteArr.size },
|
while({ (idx + 4) <= byteArr.size }, {
|
||||||
{
|
str = str ++ String.newFrom(
|
||||||
str = str ++ String.newFrom(
|
byteArr[(idx..(idx + 3))]
|
||||||
byteArr[(idx..(idx + 3))]
|
.removeEvery([0, nil])
|
||||||
.removeEvery([0])
|
.collect({|x| x.asAscii})
|
||||||
.collect({|x| x.asAscii})
|
);
|
||||||
);
|
|
||||||
|
|
||||||
// If last byte is null, return
|
// If last byte is null, return
|
||||||
if ( isNil(byteArr[idx + 3]) || (byteArr[idx + 3] == 0), {
|
if ( isNil(byteArr[idx + 3]) || (byteArr[idx + 3] == 0), {
|
||||||
^[str, idx + 4]
|
^[str, idx + 4]
|
||||||
});
|
});
|
||||||
|
idx = idx + 4;
|
||||||
idx = idx + 4;
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// If end of byteArr, return
|
// If end of byteArr, return
|
||||||
^[str, idx];
|
^[str, idx];
|
||||||
|
@ -68,175 +63,151 @@ SLIPDecoder {
|
||||||
// ce je stevilo, v razponu crk, stevk in znakov, vrni char, sicer kar cifro
|
// ce je stevilo, v razponu crk, stevk in znakov, vrni char, sicer kar cifro
|
||||||
if (x.isInteger && (x >= 0x20) && (x <= 0x7E),
|
if (x.isInteger && (x >= 0x20) && (x <= 0x7E),
|
||||||
{ ^x.asAscii },
|
{ ^x.asAscii },
|
||||||
{ ^x })
|
{ ^x }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
"init".postln;
|
|
||||||
dump(this);
|
|
||||||
deviceName.postln;
|
|
||||||
rate.postln;
|
|
||||||
port = SerialPort(deviceName, rate);
|
port = SerialPort(deviceName, rate);
|
||||||
trace = false;
|
|
||||||
stop = false;
|
|
||||||
"init done".postln;
|
|
||||||
}
|
|
||||||
|
|
||||||
trace { |val|
|
|
||||||
trace = val;
|
|
||||||
val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
traceMsg { |...msg|
|
traceMsg { |...msg|
|
||||||
if (trace, { "> ".post; msg.join(' ').postln; });
|
if ((trace), { "> ".post; msg.join(' ').postln; });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function for decoding the properly-SLIP-decoded message.
|
// Function for decoding the properly-SLIP-decoded message.
|
||||||
decode { |data|
|
decode { |data|
|
||||||
// Is it a bundle? (read header from first 8 bytes)
|
|
||||||
var header = data.at((0..7));
|
var header = data.at((0..7));
|
||||||
|
|
||||||
if (header == oscBundleHeader,
|
// Is it a bundle? (read header from first 8 bytes)
|
||||||
|
if ((header == oscBundleHeader), {
|
||||||
// OSC bundle
|
// OSC bundle
|
||||||
{
|
var nextMsgLen, nextMsgStart, nextMsgEnd, bundlePart;
|
||||||
var timetag, nextMsgLen, nextMsgStart, nextMsgEnd, bundlePart;
|
this.traceMsg("BUNDLE");
|
||||||
|
|
||||||
this.traceMsg("BUNDLE");
|
// Next 8 bytes are a time tag (or null)
|
||||||
|
/* @TODO handle timetags!
|
||||||
|
var timetag = data.at((8..15));
|
||||||
|
*/
|
||||||
|
|
||||||
// Next 8 bytes are a time tag (or null)
|
// First message starts after the time tag
|
||||||
/* @TODO handle timetags!
|
nextMsgStart = 16;
|
||||||
timetag = data.at((8..15));
|
|
||||||
*/
|
|
||||||
|
|
||||||
// First message starts after the time tag
|
// Loop for each message
|
||||||
nextMsgStart = 16;
|
while({ nextMsgStart < data.size }, {
|
||||||
|
// Further 4 bytes hold the next message length
|
||||||
|
nextMsgLen = this.readInt32(data.at((nextMsgStart..(nextMsgStart + 3))));
|
||||||
|
nextMsgStart = nextMsgStart + 4;
|
||||||
|
nextMsgEnd = min(nextMsgStart + nextMsgLen - 1, data.size - 1);
|
||||||
|
bundlePart = data.at((nextMsgStart..nextMsgEnd));
|
||||||
|
|
||||||
// Loop for each message
|
// Recursively decode; each bundle part can be another bundle
|
||||||
while({ nextMsgStart < data.size },
|
this.decode(bundlePart);
|
||||||
{
|
|
||||||
// Further 4 bytes hold the next message length
|
|
||||||
nextMsgLen = this.readInt32(data.at((nextMsgStart..(nextMsgStart + 3))));
|
|
||||||
nextMsgStart = nextMsgStart + 4;
|
|
||||||
nextMsgEnd = nextMsgStart + nextMsgLen - 1;
|
|
||||||
bundlePart = data.at((nextMsgStart..nextMsgEnd));
|
|
||||||
|
|
||||||
// Recursively decode; each bundle part can be another bundle
|
nextMsgStart = nextMsgEnd + 1;
|
||||||
this.decode(bundlePart);
|
});
|
||||||
|
}, {
|
||||||
nextMsgStart = nextMsgEnd + 1;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
// OSC message
|
// OSC message
|
||||||
{
|
var nextString, index, address, type, args = [];
|
||||||
var nextString, index, address, type, args = [];
|
|
||||||
|
|
||||||
// Message Address
|
// Message Address
|
||||||
nextString = this.readNextString(data);
|
nextString = this.readNextString(data);
|
||||||
address = nextString[0];
|
address = nextString[0];
|
||||||
data = data[(nextString[1]..(data.size - 1))];
|
data = data[(nextString[1]..(data.size - 1))];
|
||||||
|
|
||||||
nextString = this.readNextString(data);
|
nextString = this.readNextString(data);
|
||||||
type = nextString[0];
|
type = nextString[0];
|
||||||
data = data[(nextString[1]..(data.size - 1))];
|
data = data[(nextString[1]..(data.size - 1))];
|
||||||
|
|
||||||
type.do({ |t|
|
type.do({ |t|
|
||||||
t.switch (
|
t.switch (
|
||||||
$i, {
|
$i, {
|
||||||
args = args.add(this.readInt32(data));
|
args = args.add(this.readInt32(data));
|
||||||
data = data[(4..(data.size - 1))];
|
data = data[(4..(data.size - 1))];
|
||||||
},
|
},
|
||||||
$f, {
|
$f, {
|
||||||
args = args.add(this.readFloat32(data));
|
args = args.add(this.readFloat32(data));
|
||||||
data = data[(4..(data.size - 1))];
|
data = data[(4..(data.size - 1))];
|
||||||
},
|
},
|
||||||
$s, {
|
$s, {
|
||||||
nextString = this.readNextString(data);
|
nextString = this.readNextString(data);
|
||||||
args = args.add(nextString[0]);
|
args = args.add(nextString[0]);
|
||||||
data = data[(nextString[1]..(data.size - 1))];
|
data = data[(nextString[1]..(data.size - 1))];
|
||||||
}
|
}
|
||||||
/* @TODO implement strings, bytearrays */
|
/* @TODO implement strings, bytearrays */
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
this.traceMsg("OSC", prepend ++ address, args);
|
this.traceMsg("OSC", prepend ++ address, args);
|
||||||
|
|
||||||
// Send OSC message to the engine
|
// Send OSC message to the engine
|
||||||
NetAddr.localAddr.sendMsg(prepend ++ address, *args);
|
NetAddr.localAddr.sendMsg(prepend ++ address, *args);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
start {
|
start {
|
||||||
this.traceMsg("Starting...");
|
this.traceMsg("Starting...");
|
||||||
dump(this);
|
if ((port == nil), {this.init;});
|
||||||
// TODO fix restart
|
if (port.isOpen.not, {this.init;});
|
||||||
if ((port == nil), {this.init;});
|
|
||||||
if (port.isOpen.not, {this.init;});
|
|
||||||
|
|
||||||
this.traceMsg("opened");
|
this.traceMsg("opened");
|
||||||
|
running = true;
|
||||||
|
|
||||||
reader = fork {
|
reader = fork {
|
||||||
var serialByte, buffer, firstRead;
|
var serialByte, buffer, firstRead;
|
||||||
firstRead = true;
|
firstRead = true;
|
||||||
|
|
||||||
// Skip data before the first END character
|
// Skip data before the first END character
|
||||||
while({stop.not && firstRead}, {
|
while({running && firstRead}, {
|
||||||
serialByte = port.read;
|
serialByte = port.read;
|
||||||
|
|
||||||
//this.traceMsg("Read byte");
|
//this.traceMsg("Read byte");
|
||||||
//this.traceMsg(serialByte.asAscii);
|
//this.traceMsg(serialByte.asAscii);
|
||||||
|
|
||||||
if (serialByte == slipEND, {
|
if (serialByte == slipEND, {
|
||||||
buffer = Int8Array(maxSize: bufferSize);
|
buffer = Int8Array(maxSize: bufferSize);
|
||||||
firstRead = false;
|
firstRead = false;
|
||||||
}, {
|
}, {
|
||||||
//this.traceMsg("Skip...")
|
this.traceMsg("Skip...")
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start reading data
|
// Start reading data
|
||||||
this.traceMsg("First read!");
|
this.traceMsg("First read!");
|
||||||
while({stop.not}, {
|
while({running}, {
|
||||||
serialByte = port.read;
|
serialByte = port.read;
|
||||||
//this.traceMsg("Checking", serialByte.asInteger, serialByte.asAscii);
|
//this.traceMsg("Checking", serialByte.asInteger, serialByte.asAscii);
|
||||||
serialByte.switch(
|
serialByte.switch(
|
||||||
// on END, decode buffer
|
// on END, decode buffer
|
||||||
slipEND, {
|
slipEND, {
|
||||||
//this.traceMsg("SLIP END, decoding ");
|
//this.traceMsg("SLIP END, decoding ");
|
||||||
//this.traceMsg(buffer);
|
//this.traceMsg(buffer);
|
||||||
//3.wait;
|
//3.wait;
|
||||||
if (buffer.isEmpty.not, {
|
if (buffer.isEmpty.not, {
|
||||||
this.traceMsg("decode!", buffer);
|
this.traceMsg("decode!", buffer);
|
||||||
this.decode(buffer);
|
this.decode(buffer);
|
||||||
buffer = Int8Array(maxSize: bufferSize);
|
buffer = Int8Array(maxSize: bufferSize);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
slipESC, {
|
slipESC, {
|
||||||
serialByte = port.read;
|
serialByte = port.read;
|
||||||
serialByte.switch(
|
serialByte.switch(
|
||||||
slipESC_END, {
|
slipESC_END, { buffer.add(slipEND) },
|
||||||
//this.traceMsg("SLIP ESC and ESC_END");
|
slipESC_ESC, { buffer.add(slipESC) },
|
||||||
buffer.add(slipEND)
|
{"SLIP encoding error.".error }
|
||||||
},
|
);
|
||||||
slipESC_ESC, {
|
}, {
|
||||||
//this.traceMsg("SLIP ESC and ESC_ESC");
|
// Otherwise just add the byte
|
||||||
buffer.add(slipESC)
|
//this.traceMsg(buffer);
|
||||||
},
|
buffer.add(serialByte);
|
||||||
{"SLIP encoding error.".error }
|
});
|
||||||
);
|
});
|
||||||
},
|
};
|
||||||
{
|
|
||||||
// Otherwise just add the byte
|
|
||||||
//this.traceMsg(buffer);
|
|
||||||
buffer.add(serialByte);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stop {
|
stop {
|
||||||
this.traceMsg("Stopping...");
|
this.traceMsg("Stopping...");
|
||||||
stop = true;
|
running = false;
|
||||||
port.close;
|
port.close;
|
||||||
|
this.reader.free;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue