-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial commit. Basic use cases work.
- Loading branch information
0 parents
commit 1e7420d
Showing
49 changed files
with
32,136 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
tmp | ||
*.pyc | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Python package for various streaming tasks with OpenBCI data. | ||
|
||
The default config serves a webpage which graphs the data coming from the OpenBCI. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head lang="en"> | ||
<meta charset="UTF-8"> | ||
<title>BCI Streamer</title> | ||
|
||
<link rel="stylesheet" type="text/css" href="static/vendor/css/bootstrap.css"> | ||
<link rel="stylesheet" type="text/css" href="static/vendor/css/bootstrap-theme.css"> | ||
<link rel="stylesheet" type="text/css" href="static/css/main.css"> | ||
|
||
</head> | ||
<body> | ||
|
||
|
||
<div class="container"> | ||
|
||
<header></header> | ||
|
||
<div class="well">well hello</div> | ||
|
||
<canvas id="display" width="1275" height="400" style="border: 1px solid; background-color: #333;"></canvas> | ||
|
||
<footer></footer> | ||
|
||
</div> | ||
|
||
<script type="text/javascript" src="static/vendor/js/lodash.min.js"></script> | ||
<script type="text/javascript" src="static/vendor/js/jquery.min.js"></script> | ||
<script type="text/javascript" src="static/vendor/js/bootstrap.min.js"></script> | ||
<script type="text/javascript" src="static/js/ws.js"></script> | ||
<script type="text/javascript" src="static/js/plotter.js"></script> | ||
<script type="text/javascript" src="static/js/main.js"></script> | ||
|
||
</body> | ||
</html> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
|
||
window.Bci = (window.Bci || {}); | ||
|
||
|
||
window.Bci.Ws.connect(); | ||
var unlisten = window.Bci.Ws.listen(function (packet) { | ||
Bci.Plotter.plotSamples(packet.channel_data.map(function (x) { return parseInt(x / -900, 10); })); | ||
// verifySampleOrder(packet); | ||
}); | ||
|
||
// TODO: | ||
// - server and/or client side, verify sample rate and packet fidelity | ||
|
||
|
||
var latestOrdinal; | ||
function verifySampleOrder(sample) { | ||
if (latestOrdinal == 255) { | ||
latestOrdinal = -1; | ||
} | ||
var newOrdinal = sample.ordernal_or_whatever; | ||
if (newOrdinal != latestOrdinal + 1) { | ||
console.log(Date.now(), latestOrdinal, newOrdinal); | ||
} | ||
latestOrdinal = newOrdinal; | ||
}; | ||
|
||
// -- * == * -- * == * -- * == * -- * == * -- * == * -- * == * -- * == * -- * == | ||
|
||
|
||
// setTimeout(function() { window.Bci.Plotter.plotSamples([-101,-10,1]);}, 0); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([-101,-10,10]);}, 100); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([-101,-10,11]);}, 200); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([-101,-10,12]);}, 300); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([-101,-10,19]);}, 400); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([-101,-10,10]);}, 500); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([-101,-10,-1]);}, 600); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([101,-10,1]);}, 700); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([105,-10,1]);}, 800); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([111,-10,1]);}, 900); | ||
// setTimeout(function() { window.Bci.Plotter.plotSamples([11,-10,1]);}, 1000); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
|
||
window.Bci = (window.Bci || {}); | ||
|
||
|
||
// TODO: make scrollspeed depend on time (pixels per second) rather than plot speed | ||
|
||
|
||
window.Bci.Plotter = (function () { | ||
'use strict'; | ||
|
||
var displayCnvs = document.getElementById('display'); | ||
var displayCtx = displayCnvs.getContext('2d'); | ||
|
||
var displayWidth = displayCnvs.width; | ||
var displayHeight = displayCnvs.height; | ||
|
||
var tapeWidth = displayWidth * 2; | ||
var tapeHeight = displayHeight; | ||
var tapeScratchWidth = displayWidth * 2; | ||
var tapeScratchHeight = displayHeight; | ||
|
||
// var tapeCnvs = document.getElementById('tapeCnvs'); | ||
var tapeCnvs = document.createElement('canvas'); | ||
tapeCnvs.width = tapeWidth; | ||
tapeCnvs.height = tapeHeight; | ||
var tapeCtx = tapeCnvs.getContext('2d'); | ||
|
||
// var tapeScratchCnvs = document.getElementById('tapeScratchCnvs'); | ||
var tapeScratchCnvs = document.createElement('canvas'); | ||
tapeScratchCnvs.width = tapeScratchWidth; | ||
tapeScratchCnvs.height = tapeScratchHeight; | ||
var tapeScratchCtx = tapeScratchCnvs.getContext('2d'); | ||
|
||
var animationOn = true; | ||
var tapeUpdated = false; | ||
var tapeOffset = 0; | ||
|
||
var pallete = [ | ||
[222, 222, 222], | ||
[255, 0, 0], | ||
[255, 255, 0], | ||
[0, 255, 0], | ||
[0, 255, 255], | ||
[0, 0, 255], | ||
[255, 0, 255], | ||
[200, 200, 200] | ||
]; | ||
|
||
var previousSamples = [0, 0, 0, 0, 0, 0, 0, 0]; | ||
|
||
function traceFromPrevious(y1, y2, color, pixels) { | ||
// y1 is the previous point, y2 is the present | ||
var y, i; | ||
if (y1 < y2) { | ||
y1 += 1; | ||
} else if (y1 > y2) { | ||
y1 -= 1; | ||
y = y1; | ||
y1 = y2; | ||
y2 = y; | ||
} | ||
for (y = y1; y <= y2; y++) { | ||
i = (displayHeight / 2 - y) * 4; | ||
pixels.data[i] = color[0]; | ||
pixels.data[i+1] = color[1]; | ||
pixels.data[i+2] = color[2]; | ||
pixels.data[i+3] = 255; | ||
} | ||
} | ||
|
||
function plotSamples(samples) { | ||
var pixels = new ImageData(1, displayHeight); | ||
for (var ch = 0; ch < samples.length; ch++) { | ||
traceFromPrevious(previousSamples[ch], samples[ch], pallete[ch], pixels); | ||
previousSamples[ch] = samples[ch]; | ||
} | ||
tapeCtx.putImageData(pixels, tapeOffset, 0); | ||
tapeUpdated = true; | ||
|
||
tapeOffset += 1; | ||
scrollTape(); | ||
} | ||
|
||
function updateDisplay() { | ||
if (!animationOn) return; | ||
if (tapeUpdated) { | ||
displayCtx.clearRect(0, 0, displayWidth, displayHeight); | ||
var copyOffset = Math.max(0, tapeOffset - displayWidth); | ||
displayCtx.drawImage(tapeCnvs, -copyOffset, 0); | ||
tapeUpdated = false; | ||
} | ||
requestAnimationFrame(updateDisplay); | ||
} | ||
|
||
function scrollTape() { | ||
var scrollDelta; | ||
if (tapeOffset > displayWidth * 1.5) { | ||
scrollDelta = tapeOffset - displayWidth; | ||
tapeScratchCtx.clearRect(0, 0, tapeScratchWidth, tapeScratchHeight); | ||
tapeScratchCtx.drawImage(tapeCnvs, -scrollDelta, 0); | ||
tapeCtx.clearRect(0, 0, tapeWidth, tapeHeight); | ||
tapeCtx.drawImage(tapeScratchCnvs, 0, 0); | ||
tapeOffset = displayWidth; | ||
} | ||
} | ||
|
||
function setAnimationOn(on) { | ||
animationOn = !!on; | ||
if (animationOn) { | ||
requestAnimationFrame(updateDisplay); | ||
} | ||
} | ||
|
||
setAnimationOn(true); | ||
|
||
return Object.freeze({ | ||
plotSamples: plotSamples, | ||
setAnimationOn: setAnimationOn | ||
}); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
window.Bci = (window.Bci || {}); | ||
|
||
window.Bci.Ws = (function () { | ||
'use strict'; | ||
|
||
var wsEndpoint = 'ws://' + location.host + '/channels'; | ||
var listeners = []; | ||
var ws; | ||
|
||
function connect() { | ||
if (ws && (ws.readyState == ws.CONNECTING || ws.readyState == ws.OPEN)) { | ||
return ws; | ||
} | ||
ws = new WebSocket(wsEndpoint); | ||
function init() { | ||
ws.onmessage = function(msg){ | ||
var content = JSON.parse(msg.data); | ||
listeners.forEach(function (listener) { listener(content); }); | ||
}; | ||
ws.send('{"hello": 1}'); | ||
} | ||
var waitingForConnection = setInterval(function () { | ||
if (ws.readyState === WebSocket.OPEN) { | ||
init(); | ||
clearInterval(waitingForConnection); | ||
} | ||
}, 10); | ||
return ws; | ||
} | ||
|
||
function status() { | ||
switch (ws.readyState) { | ||
case ws.CLOSED: | ||
return "closed"; | ||
case ws.CLOSING: | ||
return "closing"; | ||
case ws.CONNECTING: | ||
return "connecting"; | ||
case ws.OPEN: | ||
return "open"; | ||
} | ||
} | ||
|
||
function listen(cb) { | ||
var n = listeners.length; | ||
listeners.push(cb); | ||
function unlisten() { | ||
if (n >= 0) { | ||
listeners.splice(n, 1); | ||
n = -1; | ||
} | ||
}; | ||
return unlisten; | ||
} | ||
|
||
return Object.freeze({ | ||
connect: connect, | ||
status: status, | ||
listen: listen | ||
}); | ||
})(); |
Oops, something went wrong.