nodescore/nodescore.old

376 lines
11 KiB
Plaintext
Executable File

/*
////////////////////////////////////////////
nodescore server
nodescore.kiben.net
nodescore@kiben.net
////////////////////////////////////////////
*/
var sio = require('socket.io')
, http = require('http')
, ch = require('./chronometer')
, fs = require('fs')
, static = require('node-static');
// run webserver serving static html
////////////////////////////////////////////
var clientFiles = new static.Server('./www');
var httpServer = http.createServer(
function(request, response) {
request.addListener('end', function () {
clientFiles.serve(request, response);
process.setMaxListeners(0);
});
});
httpServer.listen(8889);
var pinging=0
console.log("ping set to 0")
////////////////////////////////////////////
// connect to websockets
////////////////////////////////////////////
var io = sio.listen(httpServer)
, nicknames = {};
io.set('log level', 3); // reduce logging
io.sockets.on('connection', function (socket) {
socket.on('nickname', function (nick, fn) {
if (nicknames[nick]) {
fn(true);
} else {
fn(false);
nicknames[nick] = socket.nickname = nick;
socket.broadcast.emit('announcement', nick + ' connected');
io.sockets.emit('nicknames', nicknames);
}
});
/// chat user messages to screens and to log file
// date format for filename
var da = new Date(); var dtstring = da.getFullYear()+ '-' + da.getMonth()+ '-' + da.getDate();
////////////////////////
/// log messages to file
socket.on('user message', function (msg) {
fs.open('logs/chatlog-'+dtstring+'.txt', 'a', 666, function( e, id ) {
//time format for message stamp
var dt = new Date();var timestring = dt.getHours() + ':' + dt.getMinutes() + ':' + dt.getSeconds();
socket.broadcast.emit('user message', socket.nickname, msg);
var fs = require('fs'), str = msg;
fs.write( id, timestring+" " + socket.nickname + ": "+ msg+"\n", null, 'utf8', function(){});
});
});
////////////////////////////////////////////
// metronome
////////////////////////////////////////////
socket.on('metroStop', stopMetro)
function stopMetro () {
metroState=0;
};
////////////////////////////////////////////
// Chronometer
////////////////////////////////////////////
/*
// number padding: 0 to 00
function pad(number) { return (number < 10 ? '0' : '') + number }
// the chronometer initial states
var chronstate = 0; var zecsec = 0; var seconds = 0;
var mins = 0; var hours = 0;
dt = setInterval( function () {
socket.broadcast.emit("dateTime", ch.dateTime());
socket.emit("dateTime", ch.dateTime());
console.log("boooooooooooo")
},1000)
function chronometer() {
if (chronstate==1){
zecsec += 1; // set tenths of a second
if(zecsec > 9) { zecsec = 0; seconds += 1;}
if(seconds > 59) { seconds = 0;mins += 1;}
if(mins > 59) { mins = 0; hours += 1; }
var chron = pad(hours) +":"+pad(mins)+ ':'+ pad(seconds)+ ":"+ zecsec
setTimeout(function(){chronometer()}, 100);
socket.broadcast.emit('chronFromServer', chron)
socket.emit('chronFromServer', chron)
}
}
*/
var chronstate=0;
function startChron (){
if (chronstate==1){
stopwatch = setInterval(function () {
c = ch.chronometer(1)
socket.broadcast.emit('chronFromServer', c)
socket.emit('chronFromServer', c)
}, 100)};
}
datetime = setInterval(function () {
d = ch.dateTime()
socket.broadcast.emit('dateTime', d)
socket.emit('dateTime', d)
}, 1000)
socket.on('startChr', function () { startChr();});
// if not already started start the chronometer
function startChr() { if (chronstate !== 1) {
chronstate = 1;
startChron();
}
}
socket.on('stopChr', function () { stopChr();} );
function stopChr() { chronstate = 0; }
// stop the chronometer
socket.on('resetChr', function () { resetChr();});
function resetChr() {//clearInterval();
chronstate = 0;
zecsec = 0; seconds = 0;
mins = 0; hours = 0;
chronstate = 0;
var chron = pad(hours) +":"+pad(mins)+ ':'+ pad(seconds)+ ":"+ zecsec
// send 0.0.0 values to display
socket.broadcast.emit('chronFromServer', chron)
socket.emit('chronFromServer', chron)
}
////////////////////////////////////////////
// magic square sequencer
////////////////////////////////////////////
// var score = require('./score');
// var c = require('./chronometer');
// var mm = score.mm
var sequencerState = 0;
// var srcsqr = score.srcsqr
var srcsqr = []
srcsqr[0] = [22,21,24,25,06,07];
srcsqr[1] = [20,23,27,26,05,04];
srcsqr[2] = [03,00,17,16,35,34];
srcsqr[3] = [01,02,19,18,33,32];
// var seqA = score.seqA
// var seqB = score.seqB
// var seqC = score.seqC
// var seqD = score.seqD
var seqA = { metrobeat:0, voice:1, name: "A", counter: 0, mm: 60, beatsinbar: 4, durations: srcsqr[0], units: [1,2,3,1,2,4]};
var seqB = { metrobeat:0, voice:2, name: "B", counter: 0, mm: 120, beatsinbar: 4, durations: srcsqr[1], units: [3,2,1,1,2,3]};
var seqC = { metrobeat:0, voice:3, name: "C", counter: 0, mm: 90, beatsinbar: 4, durations: srcsqr[2], units: [4,5,6,5,4,2]};
var seqD = { metrobeat:0, voice:4, name: "D", counter: 0, mm: 105, beatsinbar: 4, durations: srcsqr[3], units: [2,3,4,2,3,1]};
var countdowntick = function(seq){
// var tempoms = Math.floor(60000/seq.mm)
var tempoms = Math.floor(60000/seq.mm)
//console.log(tempoms)
var timemultiplier=1
var outcount = 4; var incount=4;
var time = ((seq.durations[seq.counter]+1) *timemultiplier) + 30000 + (outcount*tempoms);
var time = Math.floor(time)
var ztime = time;
var totaltime = Math.floor(time/tempoms)
var unit = seq.units[seq.counter];
// initiate first page here
socket.broadcast.emit("pageFlipfromserver", seq.voice, unit, time, seq.mm,seq.counter);
socket.emit("pageFlipfromserver", seq.voice, unit, time, seq.mm,seq.counter);
function sequenCer() {
// console.log(ztime)
if (ztime >= 0 ){
// basic unit is still the second/1000ms - change this to tempoms? no i dont think so
// count in and count out
////////////////////////////////////////////
var counter = Math.floor(ztime/tempoms)
//console.log(counter)
if (counter >= 0 ){
socket.broadcast.emit('counterText', seq.voice, seq.counter, counter);
socket.emit('counterText', seq.voice, seq.counter, counter);
if (counter <= outcount ) {
socket.broadcast.emit('countinFromServer', seq.voice, counter, "","stop in: ", "red", "transparent");
}
if (counter > (totaltime)-incount && counter <= totaltime ) {
socket.broadcast.emit('countinFromServer', seq.voice, counter-(totaltime-incount), "","play in: ", "green","transparent");
socket.emit('countinFromServer', seq.voice, counter-(totaltime-incount), "","play in: ", "green","transparent");
}
if (counter == (totaltime)-incount ) {
socket.broadcast.emit('countinFromServer', seq.voice, "+", "","playing.. ", "green","transparent");
socket.emit('countinFromServer', seq.voice, "+", "","playing.. ", "green","transparent");
}
// remove displayed number with " " at end of both countin/out
if (counter == 0 ) {
socket.broadcast.emit('countinFromServer', seq.voice, "", "","", "green","transparent");
socket.broadcast.emit('counterText', seq.voice, seq.counter, "");
socket.emit('counterText', seq.voice, seq.counter, "");
}
}
// on each beat do:
// push out the pulse to metronome
seq.metrobeat = (seq.metrobeat+1)%seq.beatsinbar ;
socket.broadcast.emit('metroPulse', tempoms, seq.voice,seq.metrobeat);
socket.emit('metroPulse', tempoms, seq.voice,seq.metrobeat);
}
// flip the page
if (counter == 0){
seq.counter = (seq.counter + 1) % seq.durations.length
socket.broadcast.emit("pageFlipfromserver", seq.voice, unit, time, seq.mm,seq.counter);
//delete tockTock;
step(seq);
}
// decrement the time
ztime -= tempoms
}
var pulse = setInterval(sequenCer, tempoms);
socket.on('stopSeq', function () {
//donaldduck = mickeymouse + 7
sequenCer.clearInterval
console.log("sequencer stopping...")
// grrr why wont this clearInterval work
sequencerState = 0
clearInterval(pulse)
stopChr();
});
};
////////////////
socket.on('startSeq', function () {
if (sequencerState == 0) {
console.log("sequencer starting...")
startChr();
//////////////////////////////////////////////////////////////////
step(seqA);step(seqB); step(seqC); step(seqD);
ztime =-1;
}
else console.log("sequencer already started...")
});
step = function (seq) {
//clearInterval(seq.boo);
//clearInterval(countdowntick);
countdowntick(seq)
sequencerState=1;
};
socket.on('resetSeq', function () {
console.log("reset")
resetChr();
});
////////////////////////////////////////////
// some latency calculations
///////////////////////////////////////////
/*
a ping is periodically broadcast to all connected clients each
connected returns a pong to the server via an "emit" and in turn
the server returns each unique client a report of the latency
via another emit - the emit only sends to the source of the
request, whereas the broadcast.emit.. broadcasts.. ie to all
connected clients
TODO: smooth range and average out results to remove erratic ping
times.
TODO:
The result then needs to be used to stagger outgoing messages to
compensate for latency - how much compensation is more connected
to the time that any audio/video feed needs to encode/decode as
the latency of the route from node A to node B is inavoidable?!
so maybe latency is irrelevant in this context - we just need to
stagger signals according to encoding decoding times.. hmmm
*/
// periodically broadcast a ping
function serverTime(freq) {
if (pinging==0){ st = setInterval(function() {
var pinging=1;
var d = new Date(); var n = d.getTime();
socket.emit("timeFromServer", n);
}, 1000); } else console.log("already pinging")
}
// receive the pong calculate the latency and
// return the response to the client
socket.on("clientTimeResponse", function(x) {
var d = new Date(); var n = d.getTime();
var latency = (n-x)/2;
//console.log("SERVERTIME:"+x + " LATENCY:" + latency);
socket.emit("latencyFromServer", latency);
});
// this is the trigger from the control client to start the process
// maybe remove this and have latency connections constantly running
/*
socket.on("getLatencies", function(x){
serverTime(x);
});
*/
serverTime(1000);
socket.on('disconnect', function(client) {
console.log(socket.nickname + " is gone..." )
clearInterval(st);
if (!socket.nickname) return;
delete nicknames[socket.nickname];
socket.broadcast.emit('announcement', socket.nickname + ' disconnected');
socket.broadcast.emit('nicknames', nicknames);
});
});