source: main/trunk/model-sites-dev/respooled/collect/popup-video-respooled/js/game-on.js@ 30093

Last change on this file since 30093 was 30093, checked in by davidb, 9 years ago

Development work done in at JCDL

  • Property svn:executable set to *
File size: 20.3 KB
Line 
1"use strict";
2
3var goDocStorage = null;
4
5var goPaper = null;
6var go_top_level_group = null;;
7
8var go_paper_x_dim = 920;
9var go_paper_y_dim = 445;
10
11var gameOnCurrentTimeXPos = 0;
12var gameOnCurrentTimelineRect = null;
13
14var num_midi_pitches = 128;
15
16var group_x_scale;
17var group_y_scale;
18var group_rotate;
19var group_x_trans;
20var group_y_trans;
21
22function updateGameOnCurrentTimeline()
23{
24 gameOnCurrentTimeXPos = (mediaPlayer.currentTime / mediaPlayer.duration) * go_paper_x_dim;
25
26 var gameOnCurrentTimeYPos = (mediaPlayer.currentTime / mediaPlayer.duration) * go_paper_y_dim;
27 //console.log("*** x pos = " + gameOnCurrentTimeXPos);
28
29 gameOnCurrentTimelineRect.attr({x: gameOnCurrentTimeXPos});
30
31 if (gs.xsltParams.interface_name == "respooled") {
32 //go_top_level_group.translate(group_x_scale*go_paper_y_dim, go_paper_y_dim+(gameOnCurrentTimeYPos * group_x_scale * Math.abs(group_y_scale)));
33 go_top_level_group.translate(group_x_trans, go_paper_y_dim+(gameOnCurrentTimeYPos * group_x_scale * Math.abs(group_y_scale)));
34 }
35
36}
37
38function getDocStorage(docOID)
39{
40 var docStorage = null;
41
42 var site_name = gs.xsltParams.site_name;
43 var collection = gs.cgiParams["c"];
44
45 if (hasLocalStorage) {
46
47 if (goDocStorage == null) {
48 var docStorageStr = localStorage.getItem(docOID);
49 //console.log("***docStorageStr = " + docStorageStr);
50
51 //var docStorage = (docStorageStr != null) ? eval("("+docStorageStr+")") : {palTracks:{}, popTracks:{}};
52 docStorage = eval("("+docStorageStr+")") || {palTracks:{}, popTracks:{}};
53 goDocStorage = docStorage;
54 }
55 else {
56 docStorage = goDocStorage;
57 }
58 }
59
60 console.log("docStorage = " + docStorage);
61 //console.log("docOID = " + docOID);
62 //console.log("*** docOID in docStorage = " + (docOID in docStorage));
63 console.log("*** palTracks = " + (JSON.stringify(docStorage.palTracks)));
64 console.log("*** popTracks = " + (JSON.stringify(docStorage.popTracks)));
65
66 //console.log("*** palTracks.length = " + (Object.keys(docStorage.palTracks).length));
67
68/*
69
70 //if ((docStorage==null) || !(docOID in docStorage) || (docOID in Storage && !(docStorage[docOID].palTracks.length) )) {
71 if ((docStorage==null) || !(docStorage.palTracks) || (docStorage.palTracks && (Object.keys(docStorage.palTracks).length==0))) {
72
73
74 console.log("**** Need to retrieve Respooled data from DL");
75
76 if (docStorage==null) {
77 docStorage = {palTracks:{}, popTracks:{}};
78 }
79 gs.functions.getArchivesMetadata(collection, site_name, docOID,
80 "docStorage", 0, function(metadata) {
81 var metaval_encoded_str = metadata.getValue();
82 var metaval_str = decodeURIComponent(metaval_encoded_str)
83 console.log("***!!! metadata = '" + metaval_str + "'");
84 if (metaval_str != "") {
85 var metaval = eval("("+metaval_str+")");
86 console.log("***!!! metadata JSON = " + JSON.stringify(metaval));
87 docStorage = metaval;
88 }
89 else {
90 docStorage = {palTracks:{}, popTracks:{}};
91 }
92 goDocStorage = docStorage;
93 }
94 );
95
96 }
97*/
98
99 //console.log("*** returning docStorage.palTracks " + JSON.stringify(docStorage.palTracks));
100
101 return docStorage;
102}
103
104
105function saveDocStorage(log_prefix)
106{
107 var docOID = gs.cgiParams.d;
108 var site_name = gs.xsltParams.site_name;
109 var collection = gs.cgiParams["c"];
110
111 if (hasLocalStorage) {
112 console.log(log_prefix + ": Saving in Browser localStorage track data for '" + docOID + "'");
113 localStorage.setItem(docOID,JSON.stringify(goDocStorage));
114 }
115
116 /*
117 var goDocStorageStrEncoded = encodeURIComponent(JSON.stringify(goDocStorage));
118
119 console.log(log_prefix+": Away to save metadata to DL: " + goDocStorageStrEncoded);
120
121 gs.functions.setArchivesMetadata(collection, site_name, docOID,
122 "docStorage", null, goDocStorageStrEncoded, null, "override",
123 function(response){
124 console.log("**** saved Respooled metadata to the DL server")
125 console.log("*** response: " + JSON.stringify(response));
126 }
127 );
128*/
129}
130
131function getActiveTrackLayers(opt_field)
132{
133 var field = opt_field || "name";
134
135 var palActiveLayers = [];
136 $('#palForm input:checked').each(function() {
137 palActiveLayers.push(this[field]);
138 });
139
140 return palActiveLayers;
141}
142
143function getActiveOverlayLayers(opt_field)
144{
145 var field = opt_field || "name";
146
147 var popActiveLayers = [];
148 $('#popForm input:checked').each(function() {
149 popActiveLayers.push(this[field]);
150 });
151
152 return popActiveLayers;
153}
154
155
156function getPalTracks(docOID) {
157
158 if (!("palTracks" in goDocStorage)) {
159 goDocStorage = {palTracks:{}, popTracks:{}};
160 }
161
162 return goDocStorage.palTracks;
163
164}
165
166function getPopTracks(docOID) {
167
168 if (!("popTracks" in goDocStorage)) {
169 goDocStorage = {palTracks:{}, popTracks:{}};
170 }
171
172 return goDocStorage.popTracks;
173
174}
175
176function populatePalList(docStorage)
177{
178 // populate pal List
179 var docOID = gs.cgiParams.d;
180
181 if (hasLocalStorage) {
182
183 var palTracks = getPalTracks(docOID);
184
185 //console.log("*** palTracks = " + JSON.stringify(palTracks));
186 var palListKeys = Object.keys(palTracks).sort();
187
188 for (var i=0; i<palListKeys.length; i++) {
189 var key = palListKeys[i];
190 var track = palTracks[key];
191 var name = key;
192 var cb_name = name.replace(/[ -]/g,"");
193 var cb_value = name;
194
195 var opt_checked = (i==0) ? ' checked="checked"' : "";
196
197 $('#palList').append('<div id="pal'+cb_name+'"><input type="checkbox" '
198 + '" name="'+cb_name+'" value="' + cb_value + '"'
199 + opt_checked + '>'
200 + name + '</div>');
201 }
202 }
203 else {
204 // Put in some fake data for now
205 $('#palList').append('<input type="checkbox" id="palPianoHero" name="PianoHero" value="Piano Hero" checked="checked"/>Piano Hero<br />');
206 $('#palList').append('<input type="checkbox" id="palDrumbeatHero" name="DrumbeatHero" value="Drum-beat Hero" />Drum-beat Hero<br />');
207 }
208}
209
210
211function populatePopList(docStorage)
212{
213 // populate pop List
214 var docOID = gs.cgiParams.d;
215 var hasPopTracks = false;
216
217 if (hasLocalStorage) {
218
219 var popTracks = getPopTracks(docOID);
220
221 //console.log("*** popTracks = " + JSON.stringify(popTracks));
222 var popListKeys = Object.keys(popTracks).sort();
223
224 if (popListKeys.length>0) {
225 hasPopTracks = true;
226 }
227 for (var i=0; i<popListKeys.length; i++) {
228 var key = popListKeys[i];
229 var track = popTracks[key];
230 var name = key;
231 var cb_name = name.replace(/[ -]/g,"");
232 var cb_value = name;
233
234 var opt_checked = (i==0) ? ' checked="checked"' : "";
235
236 $('#popList').append('<div id="pop'+cb_name+'"><input type="checkbox" '
237 + '" name="'+cb_name+'" value="' + cb_value + '"'
238 + opt_checked + '>'
239 + name + '</div>');
240 }
241 }
242
243 if (!hasPopTracks) {
244 // Put in some fake data for now
245 console.log("**** adding baseline Popup Trivia item");
246
247 $('#popList').append('<input type="checkbox" id="popPopupTrivia" name="PopupTrivia" value="Popup Trivia" checked="checked"/>Popup Trivia<br />');
248
249 if (hasLocalStorage) {
250 var popTracks = getPopTracks(docOID);
251 popTracks["Popup Trivia"] = "";
252 }
253
254
255 //$('#palList').append('<input type="checkbox" id="palDrumbeatHero" name="DrumbeatHero" value="Drum-beat Hero" />Drum-beat Hero<br />');
256 }
257}
258
259
260function computeMidiStats(track)
261{
262 var min_midi_pitch = num_midi_pitches-1;
263 var max_midi_pitch = 0;
264
265 var track_chromatic_durations = [];
266 for (var i=0; i<12; i++) {
267 track_chromatic_durations[i] = 0;
268 }
269
270
271 // Process each block within the track
272 for (var b=0; b<track.length; b++) {
273 var track_block = track[b];
274 //var base_ctime = track_block.baseCTime;
275 var block_events = track_block.events;
276
277 var block_chromatic_durations = [];
278 for (var i=0; i<12; i++) {
279 block_chromatic_durations[i] = 0;
280 }
281
282 for (var ne=0; ne<block_events.length; ne++) {
283 var midi_pitch = block_events[ne].midiPitch;
284
285 if (midi_pitch < min_midi_pitch) {
286 min_midi_pitch = midi_pitch;
287 }
288 if (midi_pitch > max_midi_pitch) {
289 max_midi_pitch = midi_pitch;
290 }
291
292 var chromatic_pitch = midi_pitch % 12;
293 var chromatic_duration = block_events[ne].duration;
294 block_chromatic_durations[chromatic_pitch] += chromatic_duration;
295
296 track_chromatic_durations[chromatic_pitch] += chromatic_duration;
297 }
298
299 if (!("_computedKey" in track_block)) {
300 var strongest_profile = khKeyDetection(block_chromatic_durations);
301 track_block._computedKey = strongest_profile;
302 console.log("***### key prediction: " + strongest_profile);
303 }
304
305 }
306
307 if (!("_computedKey" in track)) {
308 var strongest_profile = khKeyDetection(track_chromatic_durations);
309 track._computedKey = strongest_profile;
310 }
311
312 return { "max_midi_pitch": max_midi_pitch, "min_midi_pitch": min_midi_pitch};
313}
314
315
316function displayActiveTrackLayers(docStorage)
317{
318 console.log("displayActiveTrackLayers()");
319
320 goPaper.clear();
321
322 // Clear takes out any previous group element, so need to be regenerated
323 go_top_level_group = new goPaper.group("gameOnPaper",[]);
324
325 var docOID = gs.cgiParams.d;
326
327 if (hasLocalStorage) {
328
329 // 'palTracks' have the form:
330 // palTracks[save_name] = [ { name: "my recording 1", baseCTime: 123.3, events: [ .... ] } ]
331
332 var palTracks = getPalTracks(docOID);
333
334 var total_duration = mediaPlayer.duration;
335 //console.log("*** total duration = " + total_duration);
336
337 var atl = getActiveTrackLayers("value");
338 //console.log("*** atl = " + JSON.stringify(atl));
339
340 var min_midi_pitch = num_midi_pitches-1;
341 var max_midi_pitch = 0;
342
343 for (var i=0; i<atl.length; i++) {
344 var storage_name = atl[i];
345 var track = palTracks[storage_name];
346
347 if (track != null) {
348
349 var midi_stats = computeMidiStats(track);
350 console.log("*** midi stats = " + JSON.stringify(midi_stats));
351
352 if (midi_stats.min_midi_pitch < min_midi_pitch) {
353 min_midi_pitch = midi_stats.min_midi_pitch;
354 }
355 if (midi_stats.max_midi_pitch > max_midi_pitch) {
356 max_midi_pitch = midi_stats.max_midi_pitch;
357 }
358
359 }
360 }
361 //console.log("*** max pitch = " + max_midi_pitch + ", min pitch = " + min_midi_pitch);
362
363 var raw_midi_range = max_midi_pitch - min_midi_pitch + 1;
364 var midi_range = Math.max(4,raw_midi_range);
365
366 //console.log("*** midi_range = " + midi_range);
367
368 var midi_y_dim_spacing = go_paper_y_dim / midi_range;
369
370
371 for (var i=0; i<atl.length; i++) {
372 var storage_name = atl[i];
373 var track = palTracks[storage_name];
374
375 if (track != null) {
376
377 for (var b=0; b<track.length; b++) {
378
379 var track_block = track[b];
380 var base_ctime = track_block.baseCTime;
381
382 var track_fill = track_block.fill;
383 var track_fillbackground = track_block.fillBackground;
384
385 var block_events = track_block.events;
386
387 var block_min_midi_pitch = num_midi_pitches-1;
388 var block_max_midi_pitch = 0;
389
390 var block_events_len = block_events.length;
391 for (var ne=0; ne<block_events_len; ne++) {
392
393 var note_event = block_events[ne];
394 var midi_pitch = note_event.midiPitch;
395
396 var startPercTime = (base_ctime + note_event.startCurrentTime)/total_duration;
397
398 var rx_org = startPercTime * go_paper_x_dim;
399 var ry_org;
400
401 var rx_dim;
402 var ry_dim;
403
404 if (note_event.type && (note_event.type=="drum")) {
405 ry_org = 0;
406
407 rx_dim = 1;
408 ry_dim = go_paper_y_dim;
409 }
410 else {
411 var midi_pitch = note_event.midiPitch;
412
413 //var startPercTime = (base_ctime + note_event.startCurrentTime)/total_duration;
414 //var rx_org = startPercTime * go_paper_x_dim;
415 ry_org = go_paper_y_dim - ((note_event.midiPitch - min_midi_pitch) * midi_y_dim_spacing) - midi_y_dim_spacing;
416
417 rx_dim = (note_event.duration/1000)/total_duration * go_paper_x_dim;
418 ry_dim = midi_y_dim_spacing;
419 }
420
421 var rect = goPaper.rect(rx_org,ry_org,rx_dim,ry_dim-0.2);
422 //rect.attr({stroke:"none", strokeWidth:0.2, fill:"#2E52A4"});
423 //rect.attr({stroke:"black",fill:"#2E52A4"});
424 var fill = note_event.fill || track_fill || "#2E52A4";
425 rect.attr({"stroke":"black","stroke-width":0.25, "fill":fill});
426 go_top_level_group.push(rect);
427
428 if (midi_pitch) {
429 if (midi_pitch < block_min_midi_pitch) {
430 block_min_midi_pitch = midi_pitch;
431 }
432 if (midi_pitch > block_max_midi_pitch) {
433 block_max_midi_pitch = midi_pitch;
434 }
435 }
436
437 }
438
439 var block_midi_range = block_max_midi_pitch - block_min_midi_pitch + 1;
440
441 var last_event = block_events[block_events_len-1];
442 var last_note_off = last_event.midiNoteOff;
443 var block_duration = (base_ctime + last_note_off)/1000.0
444;
445 var block_x_org = (base_ctime/total_duration) * go_paper_x_dim;
446 var block_x_dim = (block_duration/total_duration) * go_paper_x_dim;
447
448 var block_y_org = go_paper_y_dim - ((block_max_midi_pitch - min_midi_pitch) * midi_y_dim_spacing) - midi_y_dim_spacing;
449 var block_y_dim = midi_y_dim_spacing * (block_midi_range);
450
451 if (gs.xsltParams.interface_name != "respooled") {
452 var block_rect = goPaper.rect(block_x_org-1,block_y_org-1,block_x_dim+2,block_y_dim+2); // fudge factor!
453 var fillbackground = track_fillbackground || "rgba(46, 82, 164, 0.5)";
454 block_rect.attr({"stroke":"none", "stroke-width":0, "fill":fillbackground});
455
456 var block_tip = track_block.name;
457
458 if ("_computedKey" in track_block) {
459
460 var computedKey = track_block._computedKey;
461 var key = computedKey.key;
462 block_tip += " , Key: " + key;
463
464 if ("score" in computedKey) {
465 var perc = 100*computedKey.score;
466 block_tip += " with " + perc.toFixed(1) + "% confidence rating";
467 }
468 }
469
470 block_rect.attr({ "title": block_tip});
471
472 go_top_level_group.push(block_rect);
473 }
474
475 }
476 }
477 }
478 }
479
480 gameOnCurrentTimelineRect = goPaper.rect(-2,0,1,go_paper_y_dim);
481 gameOnCurrentTimelineRect.attr({fill: "red", stroke: "red"});
482 go_top_level_group.push(gameOnCurrentTimelineRect);
483
484 go_top_level_group.scale(group_x_scale,group_y_scale);
485 go_top_level_group.rotate(group_rotate,0,0);
486 //go_top_level_group.translate(group_x_scale*go_paper_y_dim,go_paper_y_dim);
487 go_top_level_group.translate(group_x_trans,group_y_trans);
488}
489
490function initGameOn()
491{
492 console.log("initGameOn()");
493
494 if (gs.xsltParams.interface_name == "respooled") {
495 group_x_scale = 2.0;
496 group_y_scale = -5.0;
497 group_rotate = 90.0;
498
499 group_x_trans = 15 + group_x_scale * go_paper_y_dim;
500 group_y_trans = go_paper_y_dim;
501 }
502 else {
503 group_x_scale = 1.0;
504 group_y_scale = 1.0;
505 group_rotate = 0.0;
506
507 group_x_trans = 0.0;
508 group_y_trans = 0.0;
509 }
510
511 goDocStorage = getDocStorage(gs.cgiParams.d);
512
513 //var gmp_x_dim = $('#gameOnPaper').width();
514 //var gmp_y_dim = $('#gameOnPaper').height();
515
516 //console.log("*** gmp_x_dim = " + gmp_x_dim);
517 //console.log("*** gmp_y_dim = " + gmp_y_dim);
518
519
520 //var goPaper = Raphael("gameOnPaper",gmp_x_dim,gmp_y_dim);
521 goPaper = Raphael("gameOnPaper",go_paper_x_dim,go_paper_y_dim);
522 goPaper.canvas.style.backgroundColor = '#FFFFFF';
523
524 if (gs.xsltParams.interface_name == "dlfm") {
525
526 $("#gameOnPaper>svg").panzoom({
527 $zoomIn: $(".zoom-in"),
528 $zoomOut: $(".zoom-out"),
529 $zoomRange: $(".zoom-range"),
530 $reset: $(".reset")
531 });
532
533 $("#gameOnPaper>svg").panzoom("option", "contain", true );
534
535 }
536
537
538 console.log("Browser supports LocalStorage: " + hasLocalStorage);
539
540 populatePalList(goDocStorage);
541 populatePopList(goDocStorage);
542
543 displayActiveTrackLayers(goDocStorage);
544}
545
546// pal routines
547
548function palDeleteConfirmed()
549{
550 //var palActiveLayers = $('input[type=checkbox]:checked', '#palForm');
551
552 var palActiveLayersID = getActiveTrackLayers("name");
553 var palActiveLayersValue = getActiveTrackLayers("value");
554
555 var docOID = gs.cgiParams.d;
556 var palTracks = getPalTracks(docOID);
557
558 for (var i=0; i<palActiveLayersID.length; i++) {
559 var id = palActiveLayersID[i];
560 $('#pal'+id).remove();
561
562 var value = palActiveLayersValue[i];
563 delete palTracks[value];
564 }
565
566 saveDocStorage("palDeleteConfirmed()");
567}
568
569
570function palDelete()
571{
572 $('#delete-recording-popup').dialog('open');
573
574 return false; // no need to process the event any further
575}
576
577function palDisplay()
578{
579 displayActiveTrackLayers(goDocStorage);
580
581 return false; // no need to process the event any further
582}
583
584function palSave()
585{
586 var docOID = gs.cgiParams.d;
587 var palTracks = getPalTracks(docOID);
588
589 var json_edit_str = trackEditor.getSession().getValue();
590 console.log("**** palSave() trackEditor.getSession value = " + json_edit_str);
591
592 var json_edit = eval("("+json_edit_str+")");
593
594 for (var key in json_edit){
595 if (json_edit.hasOwnProperty(key)) {
596 //console.log("*** key = " + key);
597 var val = json_edit[key];
598 console.log("**** Saving under key[" + key + "]: " + JSON.stringify(val));
599 palTracks[key] = val;
600 }
601 }
602
603 saveDocStorage("palSave()");
604
605}
606
607function palEdit()
608{
609 var docOID = gs.cgiParams.d;
610 var palTracks = getPalTracks(docOID);
611
612 var palActiveLayers = getActiveTrackLayers("value");
613
614 var edit_json = {};
615
616 for (var i=0; i<palActiveLayers.length; i++) {
617 var track_name = palActiveLayers[i];
618 edit_json[track_name] = palTracks[track_name];
619 }
620
621 trackEditor.setValue(JSON.stringify(edit_json,null,'\t'));
622 trackEditor.clearSelection();
623
624 $('#edit-recording-popup').dialog('open');
625
626 return false; // no need to process the event any further
627}
628
629//
630// Popup Info Overlay routines
631//
632
633
634function popCreate()
635{
636 $('#create-info-popup').dialog('open');
637
638 return false; // no need to process the event any further
639}
640
641function popDeleteConfirmed()
642{
643 //var popActiveLayers = $('input[type=checkbox]:checked', '#popForm');
644
645 var popActiveLayersID = getActiveOverlayLayers("name");
646 var popActiveLayersValue = getActiveOverlayLayers("value");
647
648 var docOID = gs.cgiParams.d;
649 var popTracks = getPopTracks(docOID);
650
651 for (var i=0; i<popActiveLayersID.length; i++) {
652 var id = popActiveLayersID[i];
653 $('#pop'+id).remove();
654
655 var value = popActiveLayersValue[i];
656 delete popTracks[value];
657 }
658
659 //console.log("***### pop mode, skipping saving for now");
660 saveDocStorage("popDeleteConfirmed()");
661
662}
663
664
665function popDelete()
666{
667 $('#delete-info-popup').dialog('open');
668
669 return false; // no need to process the event any further
670}
671
672function popSave()
673{
674 var docOID = gs.cgiParams.d;
675 var popTracks = getPopTracks(docOID);
676
677 var text_edit_str = infoEditor.getSession().getValue();
678 console.log("**** popSave() infoEditor.getSession value = " + text_edit_str);
679
680 var popActiveLayers = getActiveOverlayLayers();
681 //var json_edit = eval("("+json_edit_str+")");
682
683 var key = popActiveLayers[0];
684 //console.log("**** Saving under key[" + key + "]: " + JSON.stringify(val));
685 console.log("**** Saving under key[" + key + "]: " + text_edit_str);
686 popTracks[key] = text_edit_str;
687
688 /*
689 for (var key in json_edit){
690 if (json_edit.hasOwnProperty(key)) {
691 //console.log("*** key = " + key);
692 var val = json_edit[key];
693 console.log("**** Saving under key[" + key + "]: " + JSON.stringify(val));
694 popTracks[key] = val;
695 }
696 }
697 */
698
699 //console.log("***### pop mode, skipping saving for now");
700 saveDocStorage("popSave()");
701
702}
703
704
705function popEdit()
706{
707 var docOID = gs.cgiParams.d;
708 var popTracks = getPopTracks(docOID);
709
710 var popActiveLayers = getActiveOverlayLayers("value");
711
712 //var edit_json = {};
713 var edit_text = "";
714
715 for (var i=0; i<popActiveLayers.length; i++) {
716 var track_name = popActiveLayers[i];
717 //edit_json[track_name] = popTracks[track_name];
718 edit_text += popTracks[track_name];
719 }
720
721 //infoEditor.setValue(JSON.stringify(edit_json,null,'\t'));
722 infoEditor.setValue(edit_text);
723 infoEditor.clearSelection();
724
725 $('#edit-info-popup').dialog('open');
726
727 return false; // no need to process the event any further
728}
729
730
731
732
Note: See TracBrowser for help on using the repository browser.