diff -r 79ae42ad97d4 -r e0e514c5470f client/annotviz/app/js/doubleroll.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/client/annotviz/app/js/doubleroll.js Fri Jan 16 20:20:28 2015 +0100 @@ -0,0 +1,278 @@ +/** +* scripts/doubleroll.js +* +* This is the starting point for your application. +* Take a look at http://browserify.org/ for more info +*/ + +/* global window: false */ +/* global document: false */ +/* global WebSocket: false */ +/* global MozWebSocket: false */ + +'use strict'; + + +var PIXI = require('pixi'); +var _ = require('lodash'); +var PianoRoll = require('./pianoroll.js'); + +var NTP_EPOCH_DELTA = 2208988800; //c.f. RFC 868 + +var defaultConfig = { + logger: false, + sceneWidth: 1920, + pianorolls : [ + { + height: 435, + timeWidth: 10, + lineInterval: 5000, + noteHeight: undefined + }, + { + height: 645, + timeWidth: 60, + lineInterval: 5000, + noteHeight: undefined + }, + ], + framerate: 25, + offsetMusic: false, + sceneBgColor: 0xFFFFFF, + lineColor: 0x444444, + lineFillColor: 0xFFFF00, + noteColors: [0xB90000, 0x4BDD71, 0xAF931E, 0x1C28BA, 0x536991], + canvasContainer: 'canvasContainer', + logContainer: 'log', + timeContainer: 'timeStarted', + noteHeight: undefined, + zeroShift: 0.9, + timeWidth: 60, + lineInterval: 5000, + annotationChannel: 'PIANOROLL' +// wsUri: undefined, +// eventCode: undefined + +}; + +function DoubleRoll(options) { + + var _this = this; + var opts = _(options).defaults(defaultConfig).value(); + + this.logger = opts.logger; + this.lineColor = opts.lineColor; + this.lineFillColor = opts.lineFillColor; + this.framerate = opts.framerate; + this.offsetMusic = opts.offsetMusic; + this.noteColors = opts.noteColors; + + var noteHeight = opts.noteHeight; + var sceneBgColor = opts.sceneBgColor; + var sceneHeight = opts.sceneHeight || _(opts.pianorolls).reduce(function(s,p) { return s + p.height; }, 0); + var timeWidth = opts.timeWidth; + var lineInterval = opts.lineInterval; + var offsetMusic = opts.offsetMusic; + + var sceneWidth = opts.sceneWidth; + var canvasContainer = opts.canvasContainer; + var logContainer = opts.logContainer; + var timeContainer = opts.timeContainer; + + var zeroShift = opts.zeroShift; + + var eventCode = opts.eventCode; + var annotationChannel = opts.annotationChannel; + var wsUri = opts.wsUri; + if(!wsUri) { + if (window.location.protocol === 'file:') { + wsUri = 'ws://127.0.0.1:8090/broadcast'; + } + else { + wsUri = 'ws://' + window.location.hostname + ':8090/broadcast'; + } + wsUri += '?channel='+annotationChannel+'&event_code='+eventCode; + } + + + var colorsReg = {}; + + //create an new instance of a pixi stage + var stage = new PIXI.Stage(sceneBgColor); + //create a renderer instance. + var renderer = PIXI.autoDetectRenderer(sceneWidth, sceneHeight); + + var uberContainer = new PIXI.DisplayObjectContainer(); + uberContainer.x = Math.floor(sceneWidth*zeroShift); + uberContainer.y = 0; + stage.addChild(uberContainer); + + var pianorollList = []; + + var pianorollOptions = { + parentContainer: uberContainer, + xInit: 0, + width: sceneWidth, + noteColors: this.noteColors, + colorsReg: colorsReg, + lineColor: this.lineColor, + lineInterval: lineInterval, + offsetMusic: offsetMusic, + }; + + var yInit = 0; + var linesDown = true; + _(opts.pianorolls).forEach(function(prDef, i) { + var prNoteHeight = noteHeight || prDef.noteHeight || prDef.height / 128; + var prTimeWidth = prDef.timeWidth || timeWidth; + pianorollList.push(new PianoRoll(_({ + yInit: yInit, + height: prDef.height, + linesDown: linesDown, + pixelsPerSecond: Math.floor(sceneWidth / prTimeWidth), + noteHeight: prNoteHeight, + lineInterval: prDef.lineInterval + }).defaults(pianorollOptions).value())); + yInit += prDef.height; + linesDown = !linesDown; + + if(i<(opts.pianorolls.length-1)) { + var lineGraphics = new PIXI.Graphics() + .beginFill(_this.lineFillColor) + .lineStyle(1, _this.lineColor) + .moveTo(0, yInit) + .lineTo(sceneWidth, yInit) + .endFill(); + stage.addChild(lineGraphics); + } + }); + + this.init = function() { + + if(typeof(canvasContainer) === 'string') { + canvasContainer = document.getElementById(canvasContainer); + } + if(typeof(logContainer) === 'string') { + logContainer = document.getElementById(logContainer); + } + if(typeof(timeContainer) === 'string') { + timeContainer = document.getElementById(timeContainer); + } + + + if(!this.logger){ + document.body.removeChild(logContainer); + logContainer = undefined; + } + var sock; + + canvasContainer.appendChild(renderer.view); + + if ('WebSocket' in window) { + sock = new WebSocket(wsUri); + } else if ('MozWebSocket' in window) { + sock = new MozWebSocket(wsUri); + } else { + this.log('Browser does not support WebSocket!'); + window.location = 'http://autobahn.ws/unsupportedbrowser'; + } + + if (!sock) { + return; + } + sock.onopen = function(){ + if(_this.logger){ + _this.log('Connected to ' + _this.wsUri); + } + }; + + sock.onclose = function(e) { + if(_this.logger){ + _this.log('Connection closed (wasClean = ' + e.wasClean + ', code = ' + e.code + ', reason = \'' + e.reason + '\')'); + } + sock = null; + }; + + sock.onmessage = function(e) { + var dataJson = JSON.parse(e.data); + if(_this.logger){ + var dataDate = new Date((dataJson.content[0]-NTP_EPOCH_DELTA)*1000); + _this.log('Got message: ' + e.data + ' - ' + dataDate.toISOString()); + } + _this.addNotes(dataJson); + }; + + }; + + + this.addNotes = function(data) { + var note = data.content[3]; + var velocity = data.content[4]; + var ts = (data.content[0] - NTP_EPOCH_DELTA)*1000; + var channel = data.content[2]; + var sessionTs = data.content[1]; + + pianorollList.forEach(function(c) { + c.addNote(note, ts, sessionTs, velocity, channel, 0); + }); + }; + + this.refreshStage = function() { + pianorollList.forEach(function(c) { + c.move(); + }); + renderer.render(stage); + }; + + // Init page and intervals + var refreshInterval; + var refreshTimeInterval; + var startTs; + + this.updateTime = function(){ + var nbSec = (Date.now() - startTs) / 1000; + var hours = Math.floor( nbSec / 3600 ) % 24; + var minutes = Math.floor( nbSec / 60 ) % 60; + var seconds = Math.floor(nbSec % 60); + var timeStr = (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds); + timeContainer.innerHTML = timeStr; + }; + + this.start = function() { + + startTs = Date.now(); + refreshInterval = window.setInterval(function() {_this.refreshStage();}, 1000/this.framerate); + refreshTimeInterval = window.setInterval(function() {_this.updateTime();}, 1000); + pianorollList.forEach(function(c) { + c.start(); + }); + }; + + this.stop = function() { + window.clearInterval(refreshInterval); + window.clearInterval(refreshTimeInterval); + pianorollList.forEach(function(c) { + c.stop(); + }); + }; + + + this.log = function(m) { + if(this.logger){ + this.logContainer.innerHTML += m + '\n'; + this.logContainer.scrollTop = logContainer.scrollHeight; + } + }; + + + window.onload = function() { + _this.init(); + _this.start(); + }; + + return this; +} + +module.exports = { + DoubleRoll: DoubleRoll +};