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 'use strict'; |
8 'use strict'; |
9 |
9 |
|
10 var doubleroll = require('./doubleroll'); |
|
11 var annotsroll = require('./annotsroll'); |
|
12 var annotstimeline = require('./annotstimeline'); |
|
13 var stageview = require('./stageview'); |
|
14 var wswrapper = require('./wswrapper'); |
|
15 var logger = require('./logger'); |
10 |
16 |
11 var PIXI = require('pixi'); |
17 var _ = require('lodash'); |
12 var rgb2hex = require('./utils'); |
|
13 |
18 |
14 // Config vars |
19 module.exports = _({}) |
15 var horizontalView = false; |
20 .extend(doubleroll) |
16 var logger = false; |
21 .extend(annotsroll) |
17 var sceneWidth = 1920; |
22 .extend(annotstimeline) |
18 var sceneHeight = 1080; |
23 .extend(stageview) |
19 var prSize1 = 435; |
24 .extend(wswrapper) |
20 var prSize2 = 435; |
25 .extend(logger) |
21 var prSize3 = 300; |
26 .value(); |
22 var sceneBgColor = 0xFFFFFF; |
|
23 var lineColor = 0x444444; |
|
24 if (horizontalView){ |
|
25 var pixelsPerSecond1 = Math.floor(sceneWidth / 10); // nb of pixels per second |
|
26 } else{ |
|
27 var pixelsPerSecond1 = Math.floor(sceneHeight / 10); // nb of pixels per second |
|
28 } |
|
29 var manualFramerate = pixelsPerSecond1 / 4; |
|
30 if (horizontalView){ |
|
31 var pixelsPerSecond2 = Math.floor(sceneWidth / 60); // nb of pixels per second |
|
32 } else { |
|
33 var pixelsPerSecond2 = Math.floor(sceneHeight / 60); // nb of pixels per second |
|
34 } |
|
35 var pixelsPerSecond3 = Math.floor(sceneHeight / 60); // nb of pixels per second |
|
36 var lineInterval = 5000; // means line every 5 seconds |
|
37 var nbLines = -1; |
|
38 var noteHeight = 110; |
|
39 var noteColors = [0xB90000, 0x4BDD71, 0xAF931E, 0x1C28BA, 0x536991]; |
|
40 var colorsReg = {}; |
|
41 // Vars |
|
42 var noteDict = []; |
|
43 // Timecode method |
|
44 var timePageLoaded = Date.now(); |
|
45 var offsetMusic = false; |
|
46 var categoriesColor = { |
|
47 "ntm" : rgb2hex(205,200,63), |
|
48 "iam" : rgb2hex(205,200,63), |
|
49 "hip" : rgb2hex(205,200,63), |
|
50 "hop" : rgb2hex(205,200,63), |
|
51 "rock" : rgb2hex(222,139,83), |
|
52 "rap" : rgb2hex(222,139,83), |
|
53 "classic" : rgb2hex(222,139,83), |
|
54 "drums" : rgb2hex(197,163,202), |
|
55 "guitar" : rgb2hex(197,163,202), |
|
56 "bass" : rgb2hex(121,187,146), |
|
57 "default": rgb2hex(128,128,128) |
|
58 }; |
|
59 |
|
60 //create an new instance of a pixi stage |
|
61 var stage = new PIXI.Stage(sceneBgColor); |
|
62 |
|
63 //create a renderer instance. |
|
64 var renderer = PIXI.autoDetectRenderer(sceneWidth, sceneHeight); |
|
65 |
|
66 //add the renderer view element to the DOM |
|
67 document.getElementById('canvasContainer').appendChild(renderer.view); |
|
68 |
|
69 var uberContainer = new PIXI.DisplayObjectContainer(); |
|
70 if (horizontalView){ |
|
71 uberContainer.position.x = Math.floor(sceneWidth*9/10); |
|
72 uberContainer.position.y = 0; |
|
73 } else { |
|
74 uberContainer.position.x = 0; |
|
75 uberContainer.position.y = Math.floor(sceneHeight*9/10); |
|
76 } |
|
77 stage.addChild(uberContainer); |
|
78 |
|
79 /* ---------------------------------------------------------------- */ |
|
80 /* ------------------- Init Pianoroll containers ------------------ */ |
|
81 /* ---------------------------------------------------------------- */ |
|
82 |
|
83 var PianoRoll = require('./pianoroll.js') |
|
84 |
|
85 var containerList = []; |
|
86 |
|
87 if (horizontalView){ |
|
88 containerList.push(new PianoRoll(uberContainer, 0, 0, prSize1, true, pixelsPerSecond1, sceneWidth, noteColors, colorsReg, lineColor, lineInterval, offsetMusic, prSize1 / 128, horizontalView)); |
|
89 containerList.push(new PianoRoll(uberContainer, 0, prSize1, prSize2, false, pixelsPerSecond2, sceneWidth, noteColors, colorsReg, lineColor, lineInterval, offsetMusic, prSize2 / 128, horizontalView)); |
|
90 } else { |
|
91 // containerList.push(new PianoRoll(uberContainer, sceneWidth - prSize1, 0, sceneHeight, true, pixelsPerSecond1, prSize1, noteColors, colorsReg, lineColor, lineInterval, offsetMusic, prSize1 / 128, horizontalView)); |
|
92 // containerList.push(new PianoRoll(uberContainer, sceneWidth - (prSize1 + prSize2), 0, sceneHeight, false, pixelsPerSecond2, prSize2, noteColors, colorsReg, lineColor, lineInterval, offsetMusic, prSize2 / 128, horizontalView)); |
|
93 containerList.push(new PianoRoll(uberContainer, sceneWidth - prSize1, 0, sceneHeight, false, pixelsPerSecond2, prSize2, noteColors, colorsReg, lineColor, lineInterval, offsetMusic, prSize2 / 128, horizontalView)); |
|
94 } |
|
95 |
|
96 // Line between two containers |
|
97 var graphics = new PIXI.Graphics(); |
|
98 graphics.beginFill(0xFFFF00); |
|
99 graphics.lineStyle(1, lineColor); |
|
100 if (horizontalView){ |
|
101 graphics.moveTo(0, prSize1); |
|
102 graphics.lineTo(sceneWidth, prSize1); |
|
103 } else { |
|
104 graphics.moveTo(sceneWidth - prSize1, 0); |
|
105 graphics.lineTo(sceneWidth - prSize1, sceneHeight); |
|
106 graphics.moveTo(sceneWidth - (prSize1 + prSize3), 0); |
|
107 graphics.lineTo(sceneWidth - (prSize1 + prSize3), sceneHeight); |
|
108 } |
|
109 graphics.endFill(); |
|
110 stage.addChild(graphics); |
|
111 |
|
112 function addNotes(data){ |
|
113 if(!offsetMusic){ |
|
114 // get difference between the current note timecode and my zero to set the difference between the canvas's zero and the music's zero |
|
115 // in order to place in real time |
|
116 var now = Date.now(); |
|
117 var timeBetweenNowAndStart = now - timePageLoaded; |
|
118 offsetMusic = timeBetweenNowAndStart - data.content[1]; |
|
119 } |
|
120 var note = data.content[3]; |
|
121 var velocity = data.content[4]; |
|
122 if(velocity===0){ |
|
123 if(typeof noteDict[data.content[2]][note]!=='undefined'){ |
|
124 // We close the note in container one |
|
125 var duration = data.content[1] - noteDict[data.content[2]][note].ts; |
|
126 for(var i=0;i<containerList.length;i++){ |
|
127 // addNote(note, startTime, duration, velocity, canal) |
|
128 containerList[i].addNote(note, noteDict[data.content[2]][note].ts, duration, noteDict[data.content[2]][note].velocity, data.content[2]); |
|
129 } |
|
130 // delete entry |
|
131 delete noteDict[data.content[2]][note]; |
|
132 } |
|
133 } |
|
134 else{ |
|
135 if(typeof noteDict[data.content[2]]==='undefined'){ |
|
136 noteDict[data.content[2]] = {}; |
|
137 } |
|
138 noteDict[data.content[2]][note] = {ts: data.content[1], velocity:velocity}; |
|
139 } |
|
140 } |
|
141 |
|
142 function addLine(){ |
|
143 var ts = new Date(); |
|
144 for(var i=0;i<containerList.length;i++){ |
|
145 containerList[i].addLine(ts); |
|
146 } |
|
147 } |
|
148 |
|
149 /* ---------------------------------------------------------------- */ |
|
150 /* ------------------- Init AnnotsRoll containers ----------------- */ |
|
151 /* ---------------------------------------------------------------- */ |
|
152 |
|
153 var AnnotsRoll = require('./annotsRoll.js') |
|
154 |
|
155 var AnnotationRoll = new AnnotsRoll(uberContainer, sceneWidth - (prSize2 + prSize3), 0, prSize3 + prSize2, sceneHeight, prSize3, pixelsPerSecond3, lineInterval); |
|
156 |
|
157 /* ---------------------------------------------------------------- */ |
|
158 /* ------------------- Init generalView container ----------------- */ |
|
159 /* ---------------------------------------------------------------- */ |
|
160 |
|
161 var GeneralView = require('./generalView.js') |
|
162 |
|
163 var GeneralRoll = new GeneralView(uberContainer, 0, 0, sceneWidth - (prSize2 + prSize3), sceneHeight, Date.now(), Date.now() + 300000, 30, 5, 100, categoriesColor); |
|
164 |
|
165 |
|
166 function addAnnots(data){ |
|
167 var title = data.content.category.label; |
|
168 var code = data.content.category.code; |
|
169 var user = data.content.user; |
|
170 if (typeof(categoriesColor[code]) != 'undefined'){ |
|
171 var color = categoriesColor[code]; |
|
172 } |
|
173 else { |
|
174 var code = "default"; |
|
175 var color = categoriesColor[code]; |
|
176 } |
|
177 |
|
178 AnnotationRoll.addAnnot(title, user, color); |
|
179 GeneralRoll.addAnnot(code, Date.now()); |
|
180 } |
|
181 |
|
182 /* ---------------------------------------------------------------- */ |
|
183 /* ----------------------- Socket management ---------------------- */ |
|
184 /* ---------------------------------------------------------------- */ |
|
185 |
|
186 var sock = null; |
|
187 var sock2 = null; |
|
188 var ellog = null; |
|
189 function log(m) { |
|
190 if(logger){ |
|
191 ellog.innerHTML += m + '\n'; |
|
192 ellog.scrollTop = ellog.scrollHeight; |
|
193 } |
|
194 } |
|
195 window.onload = function(){ |
|
196 |
|
197 if(logger){ |
|
198 ellog = document.getElementById('log'); |
|
199 } |
|
200 else{ |
|
201 document.body.removeChild(document.getElementById('log')); |
|
202 } |
|
203 |
|
204 var wsuriInit; |
|
205 var wsuri; |
|
206 var wsuri2; |
|
207 |
|
208 if (window.location.protocol === 'file:') { |
|
209 wsuriInit = 'ws://127.0.0.1:8090/broadcast'; |
|
210 } else { |
|
211 wsuriInit = 'ws://' + window.location.hostname + ':8090/broadcast'; |
|
212 } |
|
213 wsuri = wsuriInit + '?channel=PIANOROLL&event_code='+eventCode; |
|
214 wsuri2 = wsuriInit + '?channel=ANNOT&event_code='+eventCode; |
|
215 |
|
216 if ('WebSocket' in window) { |
|
217 sock = new WebSocket(wsuri); |
|
218 sock2 = new WebSocket(wsuri2); |
|
219 } else if ('MozWebSocket' in window) { |
|
220 sock = new MozWebSocket(wsuri); |
|
221 sock2 = new WebSocket(wsuri2); |
|
222 } else { |
|
223 log('Browser does not support WebSocket!'); |
|
224 window.location = 'http://autobahn.ws/unsupportedbrowser'; |
|
225 } |
|
226 |
|
227 if (sock) { |
|
228 sock.onopen = function(){ |
|
229 if(logger){ |
|
230 log('Connected to ' + wsuri); |
|
231 } |
|
232 }; |
|
233 |
|
234 sock.onclose = function(e) { |
|
235 if(logger){ |
|
236 log('Connection closed (wasClean = ' + e.wasClean + ', code = ' + e.code + ', reason = \'' + e.reason + '\')'); |
|
237 } |
|
238 sock = null; |
|
239 }; |
|
240 |
|
241 sock.onmessage = function(e) { |
|
242 if(logger){ |
|
243 log('Got message: ' + e.data); |
|
244 } |
|
245 addNotes(JSON.parse(e.data)); |
|
246 }; |
|
247 } |
|
248 |
|
249 if (sock2) { |
|
250 sock2.onopen = function(){ |
|
251 if(logger){ |
|
252 log('Connected to ' + wsuri); |
|
253 } |
|
254 }; |
|
255 |
|
256 sock2.onclose = function(e) { |
|
257 if(logger){ |
|
258 log('Connection closed (wasClean = ' + e.wasClean + ', code = ' + e.code + ', reason = \'' + e.reason + '\')'); |
|
259 } |
|
260 sock2 = null; |
|
261 }; |
|
262 |
|
263 sock2.onmessage = function(e) { |
|
264 if(logger){ |
|
265 log('Got message: ' + e.data); |
|
266 } |
|
267 // console.log(e); |
|
268 addAnnots(JSON.parse(e.data)); |
|
269 }; |
|
270 } |
|
271 }; |
|
272 |
|
273 function replaceContainers(){ |
|
274 var diff = (Date.now() - timePageLoaded)/1000;// nb of seconds since page loaded |
|
275 |
|
276 for(var i=0;i<containerList.length;i++){ |
|
277 containerList[i].moveTo(-diff); |
|
278 AnnotationRoll.moveTo(-diff); |
|
279 } |
|
280 |
|
281 renderer.render(stage); |
|
282 } |
|
283 |
|
284 /* ---------------------------------------------------------------- */ |
|
285 /* ---------------------------- Main ------------------------------ */ |
|
286 /* ---------------------------------------------------------------- */ |
|
287 |
|
288 // Init page and intervals |
|
289 addLine(); |
|
290 var moveInterval = window.setInterval(replaceContainers, 1000/manualFramerate); |
|
291 var verticalLinesInterval = window.setInterval(addLine, lineInterval); |
|
292 |
|
293 // Little inteval to show time |
|
294 var nbSec = 0; |
|
295 var mySpan = document.getElementById('myspan'); |
|
296 function updateTime(){ |
|
297 nbSec++; |
|
298 var hours = parseInt( nbSec / 3600 ) % 24; |
|
299 var minutes = parseInt( nbSec / 60 ) % 60; |
|
300 var seconds = nbSec % 60; |
|
301 var timeStr = (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds); |
|
302 mySpan.innerHTML = timeStr; |
|
303 } |
|
304 var secondInterval = window.setInterval(updateTime, 1000); |
|
305 |
|
306 module.exports = { |
|
307 moveInterval: moveInterval, |
|
308 verticalLinesInterval: verticalLinesInterval, |
|
309 secondInterval: secondInterval |
|
310 }; |
|