annotate interfaces/timeline.js @ 2479:dbe43b4ab7aa

Starting timeline.js interface
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Wed, 03 Aug 2016 14:52:04 +0100
parents
children 713a2d059a16
rev   line source
nicholas@2479 1 /**
nicholas@2479 2 * WAET Timeline
nicholas@2479 3 * This interface plots a waveform timeline per audio fragment on a page. Clicking on the fragment will generate a comment box for processing.
nicholas@2479 4 */
nicholas@2479 5
nicholas@2479 6 // Once this is loaded and parsed, begin execution
nicholas@2479 7 loadInterface();
nicholas@2479 8
nicholas@2479 9 function loadInterface() {
nicholas@2479 10 // Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
nicholas@2479 11 // holding div's, or setting up any nodes which are present for the entire test sequence
nicholas@2479 12
nicholas@2479 13 interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
nicholas@2479 14
nicholas@2479 15 interfaceContext.insertPoint = document.getElementById("topLevelBody");
nicholas@2479 16 var testContent = document.createElement("div");
nicholas@2479 17
nicholas@2479 18 // Create the top div and Title element
nicholas@2479 19 var title = document.createElement("div");
nicholas@2479 20 title.className = "title";
nicholas@2479 21 title.align = "center";
nicholas@2479 22 var titleSpan = document.createElement("span");
nicholas@2479 23 titleSpan.id = "test-title";
nicholas@2479 24 titleSpan.textContent = "Listening Test";
nicholas@2479 25 title.appendChild(titleSpan);
nicholas@2479 26
nicholas@2479 27 var pagetitle = document.createElement("div");
nicholas@2479 28 pagetitle.className = "pageTitle";
nicholas@2479 29 pagetitle.align = "center";
nicholas@2479 30 titleSpan = document.createElement("span");
nicholas@2479 31 titleSpan.id = "page-title";
nicholas@2479 32 pagetitle.appendChild(titleSpan);
nicholas@2479 33
nicholas@2479 34 // Create Interface buttons
nicholas@2479 35 var interfaceButtons = document.createElement("div");
nicholas@2479 36 interfaceButtons.id = 'interface-buttons';
nicholas@2479 37 interfaceButtons.style.height = "25px";
nicholas@2479 38
nicholas@2479 39 // Create playback start/stop points
nicholas@2479 40 var playback = document.createElement("button");
nicholas@2479 41 playback.innerHTML = "Stop";
nicholas@2479 42 playback.id = "playback-button";
nicholas@2479 43 playback.onclick = function() {
nicholas@2479 44 if (audioEngineContext.status == 1) {
nicholas@2479 45 audioEngineContext.stop();
nicholas@2479 46 this.innerHTML = "Stop";
nicholas@2479 47 var time = audioEngineContext.timer.getTestTime();
nicholas@2479 48 console.log("Stopped at "+time);
nicholas@2479 49 }
nicholas@2479 50 };
nicholas@2479 51 // Create Submit (save) button
nicholas@2479 52 var submit = document.createElement("button");
nicholas@2479 53 submit.innerHTML = 'Next';
nicholas@2479 54 submit.onclick = buttonSubmitClick;
nicholas@2479 55 submit.id = 'submit-button';
nicholas@2479 56 submit.style.float = 'left';
nicholas@2479 57 // Append the interface buttons into the interfaceButtons object.
nicholas@2479 58 interfaceButtons.appendChild(playback);
nicholas@2479 59 interfaceButtons.appendChild(submit);
nicholas@2479 60
nicholas@2479 61 // Create outside reference holder
nicholas@2479 62 var outsideRef = document.createElement("div");
nicholas@2479 63 outsideRef.id = "outside-reference-holder";
nicholas@2479 64
nicholas@2479 65 // Create content point
nicholas@2479 66 var content = document.createElement("div");
nicholas@2479 67 content.id = "timeline-test-content";
nicholas@2479 68
nicholas@2479 69 //Inject
nicholas@2479 70 testContent.appendChild(title);
nicholas@2479 71 testContent.appendChild(pagetitle);
nicholas@2479 72 testContent.appendChild(interfaceButtons);
nicholas@2479 73 testContent.appendChild(outsideRef);
nicholas@2479 74 testContent.appendChild(content);
nicholas@2479 75 interfaceContext.insertPoint.appendChild(testContent);
nicholas@2479 76
nicholas@2479 77 // Load the full interface
nicholas@2479 78 testState.initialise();
nicholas@2479 79 testState.advanceState();
nicholas@2479 80 };
nicholas@2479 81
nicholas@2479 82 function loadTest(page)
nicholas@2479 83 {
nicholas@2479 84 // Called each time a new test page is to be build. The page specification node is the only item passed in
nicholas@2479 85 var content = document.getElementById("timeline-test-content");
nicholas@2479 86 content.innerHTML = "";
nicholas@2479 87 var interfaceObj = page.interfaces;
nicholas@2479 88 if (interfaceObj.length > 1)
nicholas@2479 89 {
nicholas@2479 90 console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
nicholas@2479 91 }
nicholas@2479 92 interfaceObj = interfaceObj[0];
nicholas@2479 93
nicholas@2479 94 //Set the page title
nicholas@2479 95 if (typeof page.title == "string" && page.title.length > 0)
nicholas@2479 96 {
nicholas@2479 97 document.getElementById("test-title").textContent = page.title;
nicholas@2479 98 }
nicholas@2479 99
nicholas@2479 100 if (interfaceObj.title != null) {
nicholas@2479 101 document.getElementById("page-title").textContent = interfaceObj.title;
nicholas@2479 102 }
nicholas@2479 103
nicholas@2479 104 // Delete outside reference
nicholas@2479 105 var outsideReferenceHolder = document.getElementById("outside-reference-holder");
nicholas@2479 106 outsideReferenceHolder.innerHTML = "";
nicholas@2479 107
nicholas@2479 108 var commentBoxPrefix = "Comment on track";
nicholas@2479 109 if (interfaceObj.commentBoxPrefix != undefined) {
nicholas@2479 110 commentBoxPrefix = interfaceObj.commentBoxPrefix;
nicholas@2479 111 }
nicholas@2479 112
nicholas@2479 113 $(page.audioElements).each(function(index,element){
nicholas@2479 114 var audioObject = audioEngineContext.newTrack(element);
nicholas@2479 115 if (page.audioElements.type == 'outside-reference') {
nicholas@2479 116 var refNode = interfaceContext.outsideReferenceDOM(audioObject,index,outsideReferenceHolder);
nicholas@2479 117 audioObject.bindInterface(orNode);
nicholas@2479 118 } else {
nicholas@2479 119 switch(audioObject.specification.parent.label) {
nicholas@2479 120 case "none":
nicholas@2479 121 label = "";
nicholas@2479 122 break;
nicholas@2479 123 case "letter":
nicholas@2479 124 label = String.fromCharCode(97 + index);
nicholas@2479 125 break;
nicholas@2479 126 case "capital":
nicholas@2479 127 label = String.fromCharCode(65 + index);
nicholas@2479 128 break;
nicholas@2479 129 default:
nicholas@2479 130 label = ""+index;
nicholas@2479 131 break;
nicholas@2479 132 }
nicholas@2479 133 var node = new interfaceObject(audioObject,label);
nicholas@2479 134
nicholas@2479 135 content.appendChild(node.DOM);
nicholas@2479 136 audioObject.bindInterface(node);
nicholas@2479 137 }
nicholas@2479 138 });
nicholas@2479 139
nicholas@2479 140 resizeWindow();
nicholas@2479 141 }
nicholas@2479 142
nicholas@2479 143 function interfaceObject(audioObject,labelstr)
nicholas@2479 144 {
nicholas@2479 145 // Each audio object has a waveform guide and self-generated comments
nicholas@2479 146 this.parent = audioObject;
nicholas@2479 147 this.DOM = document.createElement("div");
nicholas@2479 148 this.DOM.className = "timeline-element";
nicholas@2479 149 this.DOM.id = audioObject.specification.id;
nicholas@2479 150
nicholas@2479 151 var root = document.createElement("div");
nicholas@2479 152 root.className = "timeline-element-content";
nicholas@2479 153 this.DOM.appendChild(root);
nicholas@2479 154
nicholas@2479 155 var label = document.createElement("div");
nicholas@2479 156 label.style.textAlign = "center";
nicholas@2479 157 var labelSpan = document.createElement("span");
nicholas@2479 158 labelSpan.textContent = "Fragment "+labelstr;
nicholas@2479 159 label.appendChild(labelSpan);
nicholas@2479 160 root.appendChild(label);
nicholas@2479 161
nicholas@2479 162 var canvasHolder = document.createElement("div");
nicholas@2479 163 canvasHolder.className = "timeline-element-canvas-holder";
nicholas@2479 164 var buttonHolder = document.createElement("div");
nicholas@2479 165 buttonHolder.className = "timeline-element-button-holder";
nicholas@2479 166 var commentHolder = document.createElement("div");
nicholas@2479 167 commentHolder.className = "timeline-element-comment-holder";
nicholas@2479 168
nicholas@2479 169 root.appendChild(canvasHolder);
nicholas@2479 170 root.appendChild(buttonHolder);
nicholas@2479 171 root.appendChild(commentHolder);
nicholas@2479 172
nicholas@2479 173 this.comments = {
nicholas@2479 174 parent: this,
nicholas@2479 175 list: [],
nicholas@2479 176 Comment: function(parent,time, str) {
nicholas@2479 177 this.parent = parent;
nicholas@2479 178 this.time = time;
nicholas@2479 179 this.DOM = document.createElement("div");
nicholas@2479 180 this.DOM.className = "comment-div";
nicholas@2479 181 this.title = document.createElement("span");
nicholas@2479 182 if (str != undefined) {
nicholas@2479 183 this.title.textContent = str;
nicholas@2479 184 } else {
nicholas@2479 185 this.title.textContent = "Time: "+time.toFixed(2)+"s";
nicholas@2479 186 }
nicholas@2479 187 this.textarea = document.createElement("textarea");
nicholas@2479 188 this.textarea.className = "trackComment";
nicholas@2479 189 this.DOM.appendChild(this.title);
nicholas@2479 190 this.DOM.appendChild(document.createElement("br"));
nicholas@2479 191 this.DOM.appendChild(this.textarea);
nicholas@2479 192 this.resize = function() {
nicholas@2479 193 var w = window.innerWidth;
nicholas@2479 194 w = Math.min(w,800);
nicholas@2479 195 w = Math.max(w,200);
nicholas@2479 196 var elem_w = w / 2.5;
nicholas@2479 197 elem_w = Math.max(elem_w,190);
nicholas@2479 198 this.DOM.style.width = elem_w+"px";
nicholas@2479 199 this.textarea.style.width = (elem_w-5)+"px";
nicholas@2479 200 }
nicholas@2479 201 this.resize();
nicholas@2479 202 },
nicholas@2479 203 newComment: function(time) {
nicholas@2479 204 var node = new this.Comment(this,time);
nicholas@2479 205 this.list.push(node);
nicholas@2479 206 commentHolder.appendChild(node.DOM);
nicholas@2479 207 return node;
nicholas@2479 208 },
nicholas@2479 209 deleteComment: function(comment) {
nicholas@2479 210
nicholas@2479 211 },
nicholas@2479 212 clearList: function() {
nicholas@2479 213
nicholas@2479 214 }
nicholas@2479 215 }
nicholas@2479 216
nicholas@2479 217 this.canvas = {
nicholas@2479 218 parent: this,
nicholas@2479 219 comments: this.comments,
nicholas@2479 220 layer1: document.createElement("canvas"),
nicholas@2479 221 layer2: document.createElement("canvas"),
nicholas@2479 222 layer3: document.createElement("canvas"),
nicholas@2479 223 layer4: document.createElement("canvas"),
nicholas@2479 224 resize: function(w) {
nicholas@2479 225 this.layer1.width = w;
nicholas@2479 226 this.layer2.width = w;
nicholas@2479 227 this.layer3.width = w;
nicholas@2479 228 this.layer4.width = w;
nicholas@2479 229 this.layer1.style.width = w+"px";
nicholas@2479 230 this.layer2.style.width = w+"px";
nicholas@2479 231 this.layer3.style.width = w+"px";
nicholas@2479 232 this.layer4.style.width = w+"px";
nicholas@2479 233 },
nicholas@2479 234 handleEvent: function(event) {
nicholas@2479 235 switch(event.currentTarget) {
nicholas@2479 236 case this.layer1:
nicholas@2479 237 switch(event.type) {
nicholas@2479 238 case "mousemove":
nicholas@2479 239 this.drawMouse(event);
nicholas@2479 240 break;
nicholas@2479 241 case "mouseleave":
nicholas@2479 242 this.clearCanvas(this.layer1);
nicholas@2479 243 break;
nicholas@2479 244 case "click":
nicholas@2479 245 var rect = this.layer1.getBoundingClientRect();
nicholas@2479 246 var pixX = event.clientX - rect.left;
nicholas@2479 247 var tpp = this.parent.parent.buffer.buffer.duration/this.layer1.width;
nicholas@2479 248 this.comments.newComment(pixX*tpp);
nicholas@2479 249 this.drawMarkers();
nicholas@2479 250 break;
nicholas@2479 251 }
nicholas@2479 252 break;
nicholas@2479 253 }
nicholas@2479 254 },
nicholas@2479 255 drawWaveform: function() {
nicholas@2479 256 var buffer = this.parent.parent.buffer.buffer;
nicholas@2479 257 var context = this.layer4.getContext("2d");
nicholas@2479 258 context.lineWidth = 1;
nicholas@2479 259 context.strokeStyle = "#888";
nicholas@2479 260 context.clearRect(0,0,this.layer4.width, this.layer4.height);
nicholas@2479 261 var data = buffer.getChannelData(0);
nicholas@2479 262 var t_per_pixel = buffer.duration/this.layer4.width;
nicholas@2479 263 var s_per_pixel = data.length/this.layer4.width;
nicholas@2479 264 var pixX = 0;
nicholas@2479 265 while (pixX < this.layer4.width) {
nicholas@2479 266 var start = Math.floor(s_per_pixel*pixX);
nicholas@2479 267 var end = Math.min(Math.ceil(s_per_pixel*(pixX+1)),data.length);
nicholas@2479 268 var frame = data.subarray(start,end);
nicholas@2479 269 var min = frame[0];
nicholas@2479 270 var max = min;
nicholas@2479 271 for (var n=0; n<frame.length; n++) {
nicholas@2479 272 if (frame[n] < min) {min = frame[n];}
nicholas@2479 273 if (frame[n] > max) {max = frame[n];}
nicholas@2479 274 }
nicholas@2479 275 // Assuming min/max normalised between [-1, 1] to map to [150, 0]
nicholas@2479 276 context.beginPath();
nicholas@2479 277 context.moveTo(pixX+0.5,(min+1)*-75+150);
nicholas@2479 278 context.lineTo(pixX+0.5,(max+1)*-75+150);
nicholas@2479 279 context.stroke();
nicholas@2479 280 pixX++;
nicholas@2479 281 }
nicholas@2479 282 },
nicholas@2479 283 drawMouse: function(event) {
nicholas@2479 284 var context = this.layer1.getContext("2d");
nicholas@2479 285 context.clearRect(0,0,this.layer1.width, this.layer1.height);
nicholas@2479 286 var rect = this.layer1.getBoundingClientRect();
nicholas@2479 287 var pixX = event.clientX - rect.left;
nicholas@2479 288 pixX = Math.floor(pixX)-0.5;
nicholas@2479 289 context.strokeStyle = "#800";
nicholas@2479 290 context.beginPath();
nicholas@2479 291 context.moveTo(pixX,0);
nicholas@2479 292 context.lineTo(pixX,this.layer1.height);
nicholas@2479 293 context.stroke();
nicholas@2479 294 },
nicholas@2479 295 drawTicker: function() {
nicholas@2479 296 var context = this.layer2.getContext("2d");
nicholas@2479 297 context.clearRect(0,0,this.layer2.width, this.layer2.height);
nicholas@2479 298 var time = this.parent.parent.getCurrentPosition();
nicholas@2479 299 var ratio = time / this.parent.parent.buffer.buffer.duration;
nicholas@2479 300 var pixX = Math.floor(ratio*this.layer2.width)+0.5;
nicholas@2479 301 context.strokeStyle = "#080";
nicholas@2479 302 context.beginPath();
nicholas@2479 303 context.moveTo(pixX,0);
nicholas@2479 304 context.lineTo(pixX,this.layer2.height);
nicholas@2479 305 context.stroke();
nicholas@2479 306 },
nicholas@2479 307 drawMarkers: function() {
nicholas@2479 308 var context = this.layer3.getContext("2d");
nicholas@2479 309 context.clearRect(0,0,this.layer3.width, this.layer3.height);
nicholas@2479 310 context.strokeStyle = "#008";
nicholas@2479 311 var tpp = this.parent.parent.buffer.buffer.duration/this.layer1.width;
nicholas@2479 312 for (var i=0; i<this.comments.list.length; i++) {
nicholas@2479 313 var comment = this.comments.list[i];
nicholas@2479 314 var pixX = Math.floor(comment.time/tpp)+0.5;
nicholas@2479 315 context.beginPath();
nicholas@2479 316 context.moveTo(pixX,0);
nicholas@2479 317 context.lineTo(pixX,this.layer3.height);
nicholas@2479 318 context.stroke();
nicholas@2479 319 }
nicholas@2479 320 },
nicholas@2479 321 clearCanvas: function(canvas) {
nicholas@2479 322 var context = canvas.getContext("2d");
nicholas@2479 323 context.clearRect(0,0,canvas.width, canvas.height);
nicholas@2479 324 }
nicholas@2479 325 }
nicholas@2479 326 this.canvas.layer1.className = "timeline-element-canvas canvas-layer1 canvas-disabled";
nicholas@2479 327 this.canvas.layer2.className = "timeline-element-canvas canvas-layer2";
nicholas@2479 328 this.canvas.layer3.className = "timeline-element-canvas canvas-layer3";
nicholas@2479 329 this.canvas.layer4.className = "timeline-element-canvas canvas-layer3";
nicholas@2479 330 this.canvas.layer1.height = "150";
nicholas@2479 331 this.canvas.layer2.height = "150";
nicholas@2479 332 this.canvas.layer3.height = "150";
nicholas@2479 333 this.canvas.layer4.height = "150";
nicholas@2479 334 canvasHolder.appendChild(this.canvas.layer1);
nicholas@2479 335 canvasHolder.appendChild(this.canvas.layer2);
nicholas@2479 336 canvasHolder.appendChild(this.canvas.layer3);
nicholas@2479 337 canvasHolder.appendChild(this.canvas.layer4);
nicholas@2479 338 this.canvas.layer1.addEventListener("mousemove",this.canvas);
nicholas@2479 339 this.canvas.layer1.addEventListener("mouseleave",this.canvas);
nicholas@2479 340 this.canvas.layer1.addEventListener("click",this.canvas);
nicholas@2479 341
nicholas@2479 342 var canvasIntervalID = null;
nicholas@2479 343
nicholas@2479 344 this.playButton = {
nicholas@2479 345 parent: this,
nicholas@2479 346 DOM: document.createElement("button"),
nicholas@2479 347 handleEvent: function(event) {
nicholas@2479 348 var id = this.parent.parent.id;
nicholas@2479 349 var str = this.DOM.textContent;
nicholas@2479 350 if (str == "Play") {
nicholas@2479 351 audioEngineContext.play(id);
nicholas@2479 352 } else if (str == "Stop") {
nicholas@2479 353 audioEngineContext.stop();
nicholas@2479 354 }
nicholas@2479 355 }
nicholas@2479 356 }
nicholas@2479 357 this.playButton.DOM.addEventListener("click",this.playButton);
nicholas@2479 358 this.playButton.DOM.className = "timeline-button timeline-button-disabled";
nicholas@2479 359 this.playButton.DOM.disabled = true;
nicholas@2479 360 this.playButton.DOM.textContent = "Wait";
nicholas@2479 361
nicholas@2479 362 this.clearButton = {
nicholas@2479 363 parent: this,
nicholas@2479 364 DOM: document.createElement("button"),
nicholas@2479 365 handleEvent: function(event) {
nicholas@2479 366 this.parent.comments.clearList();
nicholas@2479 367 }
nicholas@2479 368 }
nicholas@2479 369 this.clearButton.DOM.addEventListener("click",this.clearButton);
nicholas@2479 370 this.clearButton.DOM.className = "timeline-button";
nicholas@2479 371 this.clearButton.DOM.textContent = "Clear";
nicholas@2479 372
nicholas@2479 373
nicholas@2479 374 buttonHolder.appendChild(this.playButton.DOM);
nicholas@2479 375 buttonHolder.appendChild(this.clearButton.DOM);
nicholas@2479 376
nicholas@2479 377 this.resize = function() {
nicholas@2479 378 var w = window.innerWidth;
nicholas@2479 379 w = Math.min(w,800);
nicholas@2479 380 w = Math.max(w,200);
nicholas@2479 381 root.style.width = w+"px";
nicholas@2479 382 var c_w = w-100;
nicholas@2479 383 this.canvas.resize(c_w);
nicholas@2479 384 }
nicholas@2479 385
nicholas@2479 386 this.enable = function()
nicholas@2479 387 {
nicholas@2479 388 // This is used to tell the interface object that playback of this node is ready
nicholas@2479 389 this.canvas.layer1.addEventListener("click",this.canvas);
nicholas@2479 390 this.canvas.layer1.className = "timeline-element-canvas canvas-layer1";
nicholas@2479 391 this.playButton.DOM.className = "timeline-button timeline-button-play";
nicholas@2479 392 this.playButton.DOM.textContent = "Play";
nicholas@2479 393 this.playButton.DOM.disabled = false;
nicholas@2479 394
nicholas@2479 395 this.canvas.drawWaveform();
nicholas@2479 396 };
nicholas@2479 397 this.updateLoading = function(progress)
nicholas@2479 398 {
nicholas@2479 399 // progress is a value from 0 to 100 indicating the current download state of media files
nicholas@2479 400 progress = String(progress);
nicholas@2479 401 progress = progress.substr(0,5);
nicholas@2479 402 this.playButton.DOM.textContent = "Loading: "+progress+'%';
nicholas@2479 403 };
nicholas@2479 404 this.startPlayback = function()
nicholas@2479 405 {
nicholas@2479 406 // Called when playback has begun
nicholas@2479 407 canvasIntervalID = window.setInterval(this.canvas.drawTicker.bind(this.canvas),100);
nicholas@2479 408 this.playButton.DOM.textContent = "Stop";
nicholas@2479 409 };
nicholas@2479 410 this.stopPlayback = function()
nicholas@2479 411 {
nicholas@2479 412 // Called when playback has stopped. This gets called even if playback never started!
nicholas@2479 413 window.clearInterval(canvasIntervalID);
nicholas@2479 414 this.canvas.clearCanvas(this.canvas.layer2);
nicholas@2479 415 this.playButton.DOM.textContent = "Play";
nicholas@2479 416 };
nicholas@2479 417 this.getValue = function()
nicholas@2479 418 {
nicholas@2479 419 // Return the current value of the object. If there is no value, return 0
nicholas@2479 420 return 0;
nicholas@2479 421 };
nicholas@2479 422 this.getPresentedId = function()
nicholas@2479 423 {
nicholas@2479 424 // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
nicholas@2479 425 return labelSpan.textContent;
nicholas@2479 426 };
nicholas@2479 427 this.canMove = function()
nicholas@2479 428 {
nicholas@2479 429 // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
nicholas@2479 430 // These are checked primarily if the interface check option 'fragmentMoved' is enabled.
nicholas@2479 431 return false;
nicholas@2479 432 };
nicholas@2479 433 this.exportXMLDOM = function(audioObject) {
nicholas@2479 434 // Called by the audioObject holding this element to export the interface <value> node.
nicholas@2479 435 // If there is no value node (such as outside reference), return null
nicholas@2479 436 // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
nicholas@2479 437 // Use storage.document.createElement('value'); to generate the XML node.
nicholas@2479 438 return null;
nicholas@2479 439 };
nicholas@2479 440 this.error = function() {
nicholas@2479 441 // If there is an error with the audioObject, this will be called to indicate a failure
nicholas@2479 442 }
nicholas@2479 443 };
nicholas@2479 444
nicholas@2479 445 function resizeWindow(event)
nicholas@2479 446 {
nicholas@2479 447 // Called on every window resize event, use this to scale your page properly
nicholas@2479 448 for (var i=0; i<audioEngineContext.audioObjects.length; i++) {
nicholas@2479 449 audioEngineContext.audioObjects[i].interfaceDOM.resize();
nicholas@2479 450 }
nicholas@2479 451 }
nicholas@2479 452
nicholas@2479 453 function buttonSubmitClick()
nicholas@2479 454 {
nicholas@2479 455 }
nicholas@2479 456
nicholas@2479 457 function pageXMLSave(store, pageSpecification)
nicholas@2479 458 {
nicholas@2479 459 // MANDATORY
nicholas@2479 460 // Saves a specific test page
nicholas@2479 461 // You can use this space to add any extra nodes to your XML <audioHolder> saves
nicholas@2479 462 // Get the current <page> information in store (remember to appendChild your data to it)
nicholas@2479 463 // pageSpecification is the current page node configuration
nicholas@2479 464 // To create new XML nodes, use storage.document.createElement();
nicholas@2479 465 }