client/annotviz/app/js/doubleroll.js
changeset 98 72d767c5142d
parent 95 806739a26858
child 100 0d7dac03c1a0
equal deleted inserted replaced
97:545803e685e0 98:72d767c5142d
     3 *
     3 *
     4 * This is the starting point for your application.
     4 * This is the starting point for your application.
     5 * Take a look at http://browserify.org/ for more info
     5 * Take a look at http://browserify.org/ for more info
     6 */
     6 */
     7 
     7 
     8 /* global window: false */
       
     9 /* global document: false */
     8 /* global document: false */
    10 /* global WebSocket: false */
       
    11 /* global MozWebSocket: false */
       
    12 
     9 
    13 'use strict';
    10 'use strict';
    14 
    11 
    15 
    12 
    16 var PIXI = require('pixi');
    13 var PIXI = require('pixi');
    17 var _ = require('lodash');
    14 var _ = require('lodash');
    18 var PianoRoll = require('./pianoroll.js');
    15 var PianoRoll = require('./pianoroll.js');
    19 
    16 
    20 var NTP_EPOCH_DELTA = 2208988800; //c.f. RFC 868
       
    21 
       
    22 var defaultConfig = {
    17 var defaultConfig = {
    23     orientation: 'horizontal',
    18     orientation: 'horizontal',
    24     logger: false,
    19     externalRefresh: false,
       
    20     logger: undefined,
    25     sceneWidth: 1920,
    21     sceneWidth: 1920,
    26     pianorolls : [
    22     pianorolls : [
    27       {
    23       {
    28         height: 435,
    24         height: 435,
    29         timeWidth: 10,
    25         timeWidth: 10,
    42     sceneBgColor: 0xFFFFFF,
    38     sceneBgColor: 0xFFFFFF,
    43     lineColor: 0x444444,
    39     lineColor: 0x444444,
    44     lineFillColor: 0xFFFF00,
    40     lineFillColor: 0xFFFF00,
    45     noteColors: [0xB90000, 0x4BDD71, 0xAF931E, 0x1C28BA, 0x536991],
    41     noteColors: [0xB90000, 0x4BDD71, 0xAF931E, 0x1C28BA, 0x536991],
    46     canvasContainer: 'canvasContainer',
    42     canvasContainer: 'canvasContainer',
    47     logContainer: 'log',
       
    48     timeContainer: 'timeStarted',
    43     timeContainer: 'timeStarted',
    49     noteHeight: undefined,
    44     noteHeight: undefined,
    50     zeroShift: 0.9,
    45     zeroShift: 0.9,
    51     timeWidth: 60,
    46     timeWidth: 60,
    52     lineInterval: 5000,
    47     lineInterval: 5000,
    53     annotationChannel: 'PIANOROLL'
       
    54 //    wsUri: undefined,
    48 //    wsUri: undefined,
    55 //    eventCode: undefined
    49 //    eventCode: undefined
    56 
    50 
    57 };
    51 };
    58 
    52 
    61     var _this = this;
    55     var _this = this;
    62     var opts = _(options).defaults(defaultConfig).value();
    56     var opts = _(options).defaults(defaultConfig).value();
    63 
    57 
    64     var orientation = opts.orientation;
    58     var orientation = opts.orientation;
    65     var isHorizontal = (orientation !== 'vertical');
    59     var isHorizontal = (orientation !== 'vertical');
       
    60     var externalRefresh = opts.externalRefresh;
    66 
    61 
    67     this.logger = opts.logger;
    62     this.logger = opts.logger;
    68     this.lineColor = opts.lineColor;
    63     this.lineColor = opts.lineColor;
    69     this.lineFillColor = opts.lineFillColor;
    64     this.lineFillColor = opts.lineFillColor;
    70     this.framerate = opts.framerate;
    65     this.framerate = opts.framerate;
    78     var lineInterval = opts.lineInterval;
    73     var lineInterval = opts.lineInterval;
    79     var offsetMusic = opts.offsetMusic;
    74     var offsetMusic = opts.offsetMusic;
    80 
    75 
    81     var sceneWidth = opts.sceneWidth;
    76     var sceneWidth = opts.sceneWidth;
    82     var canvasContainer = opts.canvasContainer;
    77     var canvasContainer = opts.canvasContainer;
    83     var logContainer = opts.logContainer;
       
    84     var timeContainer = opts.timeContainer;
    78     var timeContainer = opts.timeContainer;
    85 
    79 
    86     var zeroShift = opts.zeroShift;
    80     var zeroShift = opts.zeroShift;
    87 
    81 
    88     var eventCode = opts.eventCode;
    82     var ws = opts.ws;
    89     var annotationChannel = opts.annotationChannel;
       
    90     var wsUri = opts.wsUri;
       
    91     if(!wsUri) {
       
    92         if (window.location.protocol === 'file:') {
       
    93             wsUri = 'ws://127.0.0.1:8090/broadcast';
       
    94         }
       
    95         else {
       
    96             wsUri = 'ws://' + window.location.hostname + ':8090/broadcast';
       
    97         }
       
    98         wsUri += '?channel='+annotationChannel+'&event_code='+eventCode;
       
    99     }
       
   100 
       
   101 
    83 
   102     var colorsReg = {};
    84     var colorsReg = {};
   103 
    85 
   104     //create an new instance of a pixi stage
    86     //create an new instance of a pixi stage
   105     var stage = new PIXI.Stage(sceneBgColor);
    87     this.stage = new PIXI.Stage(sceneBgColor);
   106     //create a renderer instance.
    88     //create a renderer instance.
   107     var renderer = PIXI.autoDetectRenderer(sceneWidth, sceneHeight);
    89     var renderer = PIXI.autoDetectRenderer(sceneWidth, sceneHeight);
   108 
    90 
   109     var uberContainer = new PIXI.DisplayObjectContainer();
    91     var uberContainer = new PIXI.DisplayObjectContainer();
   110     uberContainer.x = Math.floor(sceneWidth*zeroShift);
    92     uberContainer.x = Math.floor(sceneWidth*zeroShift);
   111     uberContainer.y = 0;
    93     uberContainer.y = 0;
   112     stage.addChild(uberContainer);
    94     this.stage.addChild(uberContainer);
   113 
    95 
   114     var pianorollList = [];
    96     var pianorollList = [];
   115 
    97 
   116     var pianorollOptions = {
    98     var pianorollOptions = {
   117         parentContainer: uberContainer,
    99         parentContainer: uberContainer,
   162     this.init = function() {
   144     this.init = function() {
   163 
   145 
   164         if(typeof(canvasContainer) === 'string') {
   146         if(typeof(canvasContainer) === 'string') {
   165             canvasContainer = document.getElementById(canvasContainer);
   147             canvasContainer = document.getElementById(canvasContainer);
   166         }
   148         }
   167         if(typeof(logContainer) === 'string') {
       
   168             logContainer = document.getElementById(logContainer);
       
   169         }
       
   170         if(typeof(timeContainer) === 'string') {
   149         if(typeof(timeContainer) === 'string') {
   171             timeContainer = document.getElementById(timeContainer);
   150             timeContainer = document.getElementById(timeContainer);
   172         }
   151         }
   173 
   152 
   174 
       
   175         if(!this.logger){
       
   176             document.body.removeChild(logContainer);
       
   177             logContainer = undefined;
       
   178         }
       
   179         var sock;
       
   180 
       
   181         canvasContainer.appendChild(renderer.view);
   153         canvasContainer.appendChild(renderer.view);
   182 
   154 
   183         if ('WebSocket' in window) {
   155         ws.message(function(data) {
   184             sock = new WebSocket(wsUri);
   156             _this.addNotes(data);
   185         } else if ('MozWebSocket' in window) {
   157         });
   186             sock = new MozWebSocket(wsUri);
       
   187         } else {
       
   188             this.log('Browser does not support WebSocket!');
       
   189             window.location = 'http://autobahn.ws/unsupportedbrowser';
       
   190         }
       
   191 
       
   192         if (!sock) {
       
   193             return;
       
   194         }
       
   195         sock.onopen = function(){
       
   196             if(_this.logger){
       
   197                 _this.log('Connected to ' + _this.wsUri);
       
   198             }
       
   199         };
       
   200 
       
   201         sock.onclose = function(e) {
       
   202             if(_this.logger){
       
   203                 _this.log('Connection closed (wasClean = ' + e.wasClean + ', code = ' + e.code + ', reason = \'' + e.reason + '\')');
       
   204             }
       
   205             sock = null;
       
   206         };
       
   207 
       
   208         sock.onmessage = function(e) {
       
   209             var dataJson = JSON.parse(e.data);
       
   210             if(_this.logger){
       
   211                 var dataDate = new Date((dataJson.content[0]-NTP_EPOCH_DELTA)*1000);
       
   212                 _this.log('Got message: ' + e.data + ' - ' + dataDate.toISOString());
       
   213             }
       
   214             _this.addNotes(dataJson);
       
   215         };
       
   216 
   158 
   217     };
   159     };
   218 
   160 
   219 
   161 
   220     this.addNotes = function(data) {
   162     this.addNotes = function(data) {
   221         var note = data.content[3];
   163 
   222         var velocity = data.content[4];
   164         pianorollList.forEach(function(c) {
   223         var ts = (data.content[0] - NTP_EPOCH_DELTA)*1000;
   165             c.addNoteRaw(data);
   224         var channel = data.content[2];
   166         });
   225         var sessionTs = data.content[1];
   167     };
   226 
   168 
   227         pianorollList.forEach(function(c) {
   169     this.refreshStage = this.refresh = function() {
   228             c.addNote(note, ts, sessionTs, velocity, channel, 0);
       
   229         });
       
   230     };
       
   231 
       
   232     this.refreshStage = function() {
       
   233         pianorollList.forEach(function(c) {
   170         pianorollList.forEach(function(c) {
   234             c.move();
   171             c.move();
   235         });
   172         });
   236         renderer.render(stage);
   173         renderer.render(this.stage);
   237     };
   174     };
   238 
   175 
   239     // Init page and intervals
   176     // Init page and intervals
   240     var refreshInterval;
   177     var refreshInterval;
   241     var refreshTimeInterval;
   178     var refreshTimeInterval;
   251     };
   188     };
   252 
   189 
   253     this.start = function() {
   190     this.start = function() {
   254 
   191 
   255         startTs = Date.now();
   192         startTs = Date.now();
   256         refreshInterval = window.setInterval(function() {_this.refreshStage();}, 1000/this.framerate);
   193         if(!externalRefresh) {
   257         refreshTimeInterval = window.setInterval(function() {_this.updateTime();}, 1000);
   194             refreshInterval = setInterval(function() {_this.refreshStage();}, 1000/this.framerate);
       
   195         }
       
   196         refreshTimeInterval = setInterval(function() {_this.updateTime();}, 1000);
   258         pianorollList.forEach(function(c) {
   197         pianorollList.forEach(function(c) {
   259             c.start();
   198             c.start();
   260         });
   199         });
   261     };
   200     };
   262 
   201 
   263     this.stop = function() {
   202     this.stop = function() {
   264         window.clearInterval(refreshInterval);
   203         if(!externalRefresh) {
   265         window.clearInterval(refreshTimeInterval);
   204             clearInterval(refreshInterval);
       
   205         }
       
   206         clearInterval(refreshTimeInterval);
   266         pianorollList.forEach(function(c) {
   207         pianorollList.forEach(function(c) {
   267             c.stop();
   208             c.stop();
   268         });
   209         });
   269     };
   210     };
   270 
   211 
   271 
   212 
   272     this.log = function(m) {
   213     this.log = function(m) {
   273         if(this.logger){
   214         if(this.logger) {
   274             this.logContainer.innerHTML += m + '\n';
   215             this.logger.log(m);
   275             this.logContainer.scrollTop = logContainer.scrollHeight;
   216         }
   276         }
   217     };
   277     };
   218 
   278 
   219 
   279 
       
   280     window.onload = function() {
       
   281         _this.init();
       
   282         _this.start();
       
   283     };
       
   284 
   220 
   285     return this;
   221     return this;
   286 }
   222 }
   287 
   223 
   288 module.exports = {
   224 module.exports = {