You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
2.9 KiB
166 lines
2.9 KiB
9 years ago
|
var page_spectrogram = (function () {
|
||
|
var sg = {};
|
||
|
|
||
|
var ctx;
|
||
|
|
||
|
// drawing area
|
||
|
var plot = {
|
||
|
x:0,
|
||
|
y:0,
|
||
|
w:860,
|
||
|
h:512,
|
||
|
dx: 1, // bin
|
||
|
dy: 1
|
||
|
};
|
||
|
|
||
|
var interval = 1000;
|
||
|
var running = false;
|
||
|
var readTimeout; // timer
|
||
|
var readoutPending;
|
||
|
var readXhr;
|
||
|
|
||
|
var sampCount = 1024;
|
||
|
var binCount = sampCount/2;
|
||
|
|
||
|
var colormap = {
|
||
|
r: [
|
||
|
{x: 0, b: 0},
|
||
|
{x: .7, b: 0},
|
||
|
{x: 1, b: 1},
|
||
|
],
|
||
|
g: [
|
||
|
{x: 0, b: 0},
|
||
|
{x: .3, b: 0},
|
||
|
{x: .7, b: 1},
|
||
|
{x: 1, b: 1},
|
||
|
],
|
||
|
b: [
|
||
|
{x: 0, b: 0},
|
||
|
{x: .02, b: .3},
|
||
|
{x: .3, b: 1},
|
||
|
{x: 1, b: 1},
|
||
|
]
|
||
|
};
|
||
|
|
||
|
function cmResolv(db, tab) {
|
||
|
var startX,endX,startC,endC;
|
||
|
|
||
|
db /=6;
|
||
|
if (db > 1) db = 1;
|
||
|
if (db < 0) db = 0;
|
||
|
|
||
|
for (var i = 0; i < tab.length; i++) {
|
||
|
var p = tab[i];
|
||
|
if (db >= p.x) {
|
||
|
startX = p.x;
|
||
|
startC = p.b;
|
||
|
}
|
||
|
|
||
|
if (db <= p.x) {
|
||
|
endX = p.x;
|
||
|
endC = p.b;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return Math.round((startC + (endC - startC)*((db - startX)/(endX - startX)))*255);
|
||
|
}
|
||
|
|
||
|
function val2color(x) {
|
||
|
var xx = x;//20 * Math.log(x);
|
||
|
|
||
|
var r = cmResolv(xx, colormap.r);
|
||
|
var g = cmResolv(xx, colormap.g);
|
||
|
var b = cmResolv(xx, colormap.b);
|
||
|
|
||
|
return 'rgb('+r+','+g+','+b+')';
|
||
|
}
|
||
|
|
||
|
function shiftSg() {
|
||
|
var imageData = ctx.getImageData(plot.x+plot.dx, plot.y, plot.w-plot.dx, plot.h);
|
||
|
ctx.putImageData(imageData, plot.x, plot.y);
|
||
|
}
|
||
|
|
||
|
function drawSg(col) {
|
||
|
shiftSg();
|
||
|
|
||
|
for (var i = 0; i < binCount; i++) {
|
||
|
// resolve color from the value
|
||
|
var y = binCount - i;
|
||
|
var clr;
|
||
|
|
||
|
if (i > col.length) {
|
||
|
clr = '#000';
|
||
|
} else {
|
||
|
clr = val2color(col[i]);
|
||
|
}
|
||
|
ctx.fillStyle = clr;
|
||
|
|
||
|
ctx.fillRect(plot.x+plot.w-plot.dx, plot.y+y*plot.dy, plot.dx, plot.dy);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
function onRxData(resp, status) {
|
||
|
readoutPending = false;
|
||
|
if (status == 200) {
|
||
|
try {
|
||
|
var j = JSON.parse(resp);
|
||
|
if (j.success) {
|
||
|
// display
|
||
|
drawSg(j.samples);
|
||
|
} else {
|
||
|
errorMsg("Sampling failed.");
|
||
|
}
|
||
|
} catch(e) {
|
||
|
errorMsg(e);
|
||
|
}
|
||
|
} else {
|
||
|
errorMsg("Request failed.");
|
||
|
}
|
||
|
|
||
|
if (running)
|
||
|
readTimeout = setTimeout(requestData, interval); // TODO should actually compute time remaining, this adds interval to the request time.
|
||
|
}
|
||
|
|
||
|
function requestData() {
|
||
|
if (readoutPending) {
|
||
|
errorMsg("Request already pending - aborting.");
|
||
|
readXhr.abort();
|
||
|
}
|
||
|
readoutPending = true;
|
||
|
|
||
|
var fs = $('#freq').val();
|
||
|
var url = _root+'/measure/fft?n='+sampCount+'&fs='+fs;
|
||
|
|
||
|
readXhr = $().get(url, onRxData, estimateLoadTime(fs,sampCount));
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
sg.init = function () {
|
||
|
var canvas = $('#sg')[0];
|
||
|
ctx = canvas.getContext('2d');
|
||
|
|
||
|
ctx.fillStyle = '#000';
|
||
|
ctx.fillRect(plot.x, plot.y, plot.w, plot.h);
|
||
|
|
||
|
$('#go-btn').on('click', function() {
|
||
|
interval = +$('#interval').val(); // ms
|
||
|
|
||
|
running = !running;
|
||
|
if (running) {
|
||
|
requestData();
|
||
|
} else {
|
||
|
clearTimeout(readTimeout);
|
||
|
}
|
||
|
|
||
|
$('#go-btn')
|
||
|
.toggleClass('btn-green')
|
||
|
.toggleClass('btn-red')
|
||
|
.html(running ? 'Stop' : 'Start');
|
||
|
});
|
||
|
};
|
||
|
|
||
|
return sg;
|
||
|
})();
|