colorchord/embedded8266/web/page/main.js
2017-04-05 12:32:22 -03:00

534 lines
11 KiB
JavaScript

//Copyright (C) 2015 <>< Charles Lohr, see LICENSE file for more info.
//
//This particular file may be licensed under the MIT/x11, New BSD or ColorChord Licenses.
var globalParams = {};
function mainticker()
{
KickOscilloscope();
KickDFT();
KickNotes();
KickLEDs();
QueueOperation( "CVR", ReceiveParameters );
setTimeout( mainticker, 1000 );
}
function maininit()
{
setTimeout( mainticker, 1000 );
}
window.addEventListener("load", maininit, false);
function ChangeParam( p )
{
var num = Number( p.value );
var elem = p.id.substr( 5 );
QueueOperation( "CVW\t" + elem + "\t" + num );
}
var hasCreateParams = false;
function ReceiveParameters(req,data) {
var elems = data.split( "\t" );
for( var v = 0; v < elems.length; v++ )
{
var pair = elems[v].split( "=" );
if( pair.length == 2 )
{
globalParams[pair[0]] = Number( pair[1] );
}
}
if( !hasCreateParams )
{
hasCreateParams = true;
var htv = "<table border=1><tr><th>Value</th><th width=100%>Parameter</th></tr>";
for( var v in globalParams )
{
var vp = globalParams[v];
htv += "<tr><td><INPUT TYPE=TEXT ID=param" + v + " VALUE=" + vp + " onchange=ChangeParam(this)></td><td>" + v + "</td></tr>";
}
$("#InnerParameters").html( htv + "</table>" );
for( var v in globalParams )
{
if( v.substr(0,1) == 'r' )
{
$("#param" + v).prop( "disabled", true );
}
}
}
for( var v in globalParams )
{
var vp = globalParams[v];
var p = $("#param"+v);
if( !p.is(":focus" ) )
p.val(vp);
}
}
var is_oscilloscope_running = false;
var pause_oscilloscope = false;
function KickOscilloscope()
{
$( "#OScopePauseButton" ).css( "background-color", (is_oscilloscope_running&&!pause_oscilloscope)?"green":"red" );
if( !pause_oscilloscope)
OScopeDataTicker();
}
function ToggleOScopePause()
{
pause_oscilloscope = !pause_oscilloscope;
KickOscilloscope();
}
function GotOScope(req,data)
{
var mult = Number(document.getElementById('OSCMultIn').value);
document.getElementById('OSCMultOut').innerHTML = mult;
var canvas = document.getElementById('OScopeCanvas');
var ctx = canvas.getContext('2d');
var h = canvas.height;
var w = canvas.width;
if( ctx.canvas.width != canvas.clientWidth ) ctx.canvas.width = canvas.clientWidth;
if( ctx.canvas.height != canvas.clientHeight ) ctx.canvas.height = canvas.clientHeight;
$( "#OScopePauseButton" ).css( "background-color", "green" );
var secs = data.split( "\t" );
var samps = Number( secs[1] );
var data = secs[2];
var lastsamp = parseInt( data.substr(0,2),16 );
ctx.clearRect( 0, 0, canvas.width, canvas.height );
ctx.beginPath();
for( var i = 0; i < samps; i++ )
{
var x2 = (i+1) * canvas.clientWidth / samps;
var samp = parseInt( data.substr(i*2+2,2),16 );
var y2 = ( 1.-mult*samp / 255 ) * canvas.clientHeight;
if( i == 0 )
{
var x1 = i * canvas.clientWidth / samps;
var y1 = ( 1.-mult*lastsamp / 255 ) * canvas.clientHeight;
ctx.moveTo( x1, y1 );
}
ctx.lineTo( x2, y2 );
lastsamp = samp;
}
ctx.stroke();
var samp = parseInt( data.substr(i*2,2),16 );
OScopeDataTicker();
}
function OScopeDataTicker()
{
if( IsTabOpen('OScope') && !pause_oscilloscope )
{
is_oscilloscope_running = true;
QueueOperation( "CM", GotOScope );
}
else
{
is_oscilloscope_running = false;
}
$( "#OScopePauseButton" ).css( "background-color", (is_oscilloscope_running&&!pause_oscilloscope)?"green":"red" );
}
var is_dft_running = false;
var pause_dft = false;
function KickDFT()
{
$( "#DFTPauseButton" ).css( "background-color", (is_dft_running&&!pause_dft)?"green":"red" );
if( !pause_dft )
DFTDataTicker();
}
function ToggleDFTPause()
{
pause_dft = !pause_dft;
KickDFT();
}
function GotDFT(req,data)
{
var mult = Number(document.getElementById('DFTMultIn').value);
document.getElementById('DFTMultOut').innerHTML = mult;
var canvas = document.getElementById('DFTCanvas');
var ctx = canvas.getContext('2d');
var h = canvas.height;
var w = canvas.width;
if( ctx.canvas.width != canvas.clientWidth ) ctx.canvas.width = canvas.clientWidth;
if( ctx.canvas.height != canvas.clientHeight ) ctx.canvas.height = canvas.clientHeight;
var secs = data.split( "\t" );
$( "#DFTPauseButton" ).css( "background-color", "green" );
var samps = Number( secs[1] );
var data = secs[2];
var lastsamp = parseInt( data.substr(0,4),16 );
ctx.clearRect( 0, 0, canvas.width, canvas.height );
ctx.beginPath();
for( var i = 0; i < samps; i++ )
{
var x2 = i * canvas.clientWidth / samps;
var samp = parseInt( data.substr(i*4,4),16 );
var y2 = ( 1.-mult*samp / 2047 ) * canvas.clientHeight;
ctx.fillStyle = CCColor( i % globalParams["rFIXBPERO"] );
ctx.fillRect( x2, y2, canvas.clientWidth / samps, canvas.clientHeight-y2 );
ctx.strokeStyle = "#000000";
ctx.strokeRect( x2, y2, canvas.clientWidth / samps, canvas.clientHeight-y2 );
}
ctx.stroke();
var samp = parseInt( data.substr(i*2,2),16 );
DFTDataTicker();
}
function DFTDataTicker()
{
if( IsTabOpen('DFT') && !pause_dft )
{
is_dft_running = true;
QueueOperation( "CB" + $("#WhichCanvas").val(), GotDFT );
}
else
{
is_dft_running = 0;
}
$( "#DFTPauseButton" ).css( "background-color", (is_dft_running&&!pause_dft)?"green":"red" );
}
var is_leds_running = false;
var pause_led = false;
function KickLEDs()
{
$( "#LEDPauseButton" ).css( "background-color", (is_leds_running&&!pause_led)?"green":"red" );
if( !pause_led )
LEDDataTicker();
}
function ToggleLEDPause()
{
pause_led = !pause_led;
KickLEDs();
}
function GotLED(req,data)
{
var ls = document.getElementById('LEDCanvasHolder');
var canvas = document.getElementById('LEDCanvas');
var ctx = canvas.getContext('2d');
var h = ls.height;
var w = ls.width;
if( canvas.width != ls.clientWidth-10 ) canvas.width = ls.clientWidth-10;
if( ctx.canvas.width != canvas.clientWidth ) ctx.canvas.width = canvas.clientWidth;
var secs = data.split( "\t" );
$( "#LEDPauseButton" ).css( "background-color", "green" );
var samps = Number( secs[1] );
var data = secs[2];
var lastsamp = parseInt( data.substr(0,4),16 );
ctx.clearRect( 0, 0, canvas.width, canvas.height );
for( var i = 0; i < samps; i++ )
{
var x2 = i * canvas.clientWidth / samps;
var samp = data.substr(i*6,6);
var y2 = ( 1.-samp / 2047 ) * canvas.clientHeight;
ctx.fillStyle = "#" + samp.substr( 2, 2 ) + samp.substr( 0, 2 ) + samp.substr( 4, 2 );
ctx.lineWidth = 0;
ctx.fillRect( x2, 0, canvas.clientWidth / samps+1, canvas.clientHeight );
}
var samp = parseInt( data.substr(i*2,2),16 );
LEDDataTicker();
}
function LEDDataTicker()
{
if( IsTabOpen('LEDs') && !pause_led )
{
is_leds_running = true;
QueueOperation( "CL", GotLED );
}
else
{
is_leds_running = 0;
}
$( "#LEDPauseButton" ).css( "background-color", (is_leds_running&&!pause_led)?"green":"red" );
}
var is_notes_running = false;
var pause_notes = false;
function KickNotes()
{
$( "#NotesPauseButton" ).css( "background-color", (is_notes_running&&!pause_notes)?"green":"red" );
if(!pause_notes )
NotesTicker();
}
function ToggleNotesPause()
{
pause_notes = !pause_notes;
KickNotes();
}
function GotNotes(req,data)
{
var canvas = document.getElementById('NotesCanvas');
var ctx = canvas.getContext('2d');
var secs = data.split( "\t" );
var elems = Number(secs[1] );
ctx.canvas.width = 400;
ctx.canvas.height = elems*25;
$( "#NotesPauseButton" ).css( "background-color", "green" );
var data = secs[2];
ctx.fillStyle = "#000000";
ctx.font = "18px serif"
ctx.fillRect( 0, 0, canvas.width, canvas.height );
for( var i = 0; i < elems; i++ )
{
var peak = parseInt( data.substr(i*12+0,2),16 );
var amped = parseInt( data.substr(i*12+2,4),16 );
var amped2 = parseInt( data.substr(i*12+6,4),16 );
var jump = parseInt( data.substr(i*12+10,2),16 );
if( peak == 255 )
{
ctx.fillStyle = "#ffffff";
ctx.fillText( jump, 10, i*25 + 20 );
continue;
}
ctx.fillStyle = CCColorDetail( peak );
ctx.lineWidth = 0;
ctx.fillRect( 0, i*25, 100,25);
ctx.fillRect( 101, i*25, amped/200,25);
ctx.fillRect( 229, i*25, amped2/200,25);
ctx.fillStyle = "#000000";
ctx.fillText( peak, 10, i*25 + 20 );
ctx.fillStyle = "#ffffff";
ctx.fillText( amped, 121, i*25 + 20 );
ctx.fillText( amped2, 240, i*25 + 20 );
}
var samp = parseInt( data.substr(i*2,2),16 );
NotesTicker();
}
function NotesTicker()
{
if( IsTabOpen('Notes')&& !pause_notes )
{
is_notes_running = true;
QueueOperation( "CN", GotNotes );
}
else
{
is_notes_running = 0;
}
$( "#NotesPauseButton" ).css( "background-color", (is_notes_running&&!pause_notes)?"green":"red" );
}
function CCColor( note )
{
return ECCtoHEX( (note * globalParams["rNOTERANGE"] / globalParams["rFIXBPERO"] + globalParams["gROOT_NOTE_OFFSET"] + globalParams["rNOTERANGE"] )%globalParams["rNOTERANGE"], 255, 255 );
}
function CCColorDetail( note )
{
return ECCtoHEX( (note + globalParams["gROOT_NOTE_OFFSET"] + globalParams["rNOTERANGE"] )%globalParams["rNOTERANGE"], 255, 255 );
}
function ECCtoHEX( note, sat, val )
{
var hue = 0;
var third = 65535/3;
var scalednote = note;
var renote = note * 65536 / globalParams["rNOTERANGE"];
//Note is expected to be a vale from 0..(NOTERANGE-1)
//renote goes from 0 to the next one under 65536.
if( renote < third )
{
//Yellow to Red.
hue = (third - renote) >> 1;
}
else if( renote < (third<<1) )
{
//Red to Blue
hue = (third-renote);
}
else
{
//hue = ((((65535-renote)>>8) * (uint32_t)(third>>8)) >> 1) + (third<<1);
hue = (((65536-renote)<<16) / (third<<1)) + (third>>1); // ((((65535-renote)>>8) * (uint32_t)(third>>8)) >> 1) + (third<<1);
}
hue >>= 8;
return EHSVtoHEX( hue, sat, val );
}
function EHSVtoHEX( hue, sat, val ) //0..255 for all
{
var SIXTH1 = 43;
var SIXTH2 = 85;
var SIXTH3 = 128;
var SIXTH4 = 171;
var SIXTH5 = 213;
var or = 0, og = 0, ob = 0;
hue -= SIXTH1; //Off by 60 degrees.
hue = (hue+256)%256;
//TODO: There are colors that overlap here, consider
//tweaking this to make the best use of the colorspace.
if( hue < SIXTH1 ) //Ok: Yellow->Red.
{
or = 255;
og = 255 - (hue * 255) / (SIXTH1);
}
else if( hue < SIXTH2 ) //Ok: Red->Purple
{
or = 255;
ob = hue*255 / SIXTH1 - 255;
}
else if( hue < SIXTH3 ) //Ok: Purple->Blue
{
ob = 255;
or = ((SIXTH3-hue) * 255) / (SIXTH1);
}
else if( hue < SIXTH4 ) //Ok: Blue->Cyan
{
ob = 255;
og = (hue - SIXTH3)*255 / SIXTH1;
}
else if( hue < SIXTH5 ) //Ok: Cyan->Green.
{
og = 255;
ob = ((SIXTH5-hue)*255) / SIXTH1;
}
else //Green->Yellow
{
og = 255;
or = (hue - SIXTH5) * 255 / SIXTH1;
}
var rv = val;
if( rv > 128 ) rv++;
var rs = sat;
if( rs > 128 ) rs++;
//or, og, ob range from 0...255 now.
//Need to apply saturation and value.
or = (or * val)>>8;
og = (og * val)>>8;
ob = (ob * val)>>8;
//OR..OB == 0..65025
or = or * rs + 255 * (256-rs);
og = og * rs + 255 * (256-rs);
ob = ob * rs + 255 * (256-rs);
//printf( "__%d %d %d =-> %d\n", or, og, ob, rs );
or >>= 8;
og >>= 8;
ob >>= 8;
if( or > 255 ) or = 255;
if( og > 255 ) og = 255;
if( ob > 255 ) ob = 255;
return "#" + tohex8(og) + tohex8(or) + tohex8(ob);
}
function tohex8( c )
{
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}