comparison core.js @ 1688:a449b8cdfb31

Standalone version. Movable sliders with rating Comment boxes Submission to XML file TODO: Click track to listen
author Nicholas Jillings <nickjillings@users.noreply.github.com>
date Wed, 25 Mar 2015 12:48:29 +0000
parents c97a35dc45e5
children a6364db4c2ea
comparison
equal deleted inserted replaced
1687:8c942feff9aa 1688:a449b8cdfb31
7 7
8 /* create the web audio API context and store in audioContext*/ 8 /* create the web audio API context and store in audioContext*/
9 var audioContext; 9 var audioContext;
10 var projectXML; 10 var projectXML;
11 var audioEngineContext; 11 var audioEngineContext;
12 var projectReturn;
12 13
13 window.onload = function() { 14 window.onload = function() {
14 // Function called once the browser has loaded all files. 15 // Function called once the browser has loaded all files.
15 // This should perform any initial commands such as structure / loading documents 16 // This should perform any initial commands such as structure / loading documents
16 17
17 // Create a web audio API context 18 // Create a web audio API context
18 // NORE: Currently this will only work with webkit browsers (Chrome/Safari)! 19 // NORE: Currently this will only work with webkit browsers (Chrome/Safari)!
19 audioContext = new webkitAudioContext; 20 audioContext = new AudioContext;
20 21
21 // Create the audio engine object 22 // Create the audio engine object
22 audioEngineContext = new AudioEngine(); 23 audioEngineContext = new AudioEngine();
23 } 24 }
24 25
50 } 51 }
51 52
52 function createProjectSave(destURL) { 53 function createProjectSave(destURL) {
53 // Save the data from interface into XML and send to destURL 54 // Save the data from interface into XML and send to destURL
54 // If destURL is null then download XML in client 55 // If destURL is null then download XML in client
56 // Now time to render file locally
57 var xmlDoc = interfaceXMLSave();
58 if (destURL == "null" || destURL == undefined) {
59 var parent = document.createElement("div");
60 parent.appendChild(xmlDoc);
61 var file = [parent.innerHTML];
62 var bb = new Blob(file,{type : 'application/xml'});
63 var dnlk = window.URL.createObjectURL(bb);
64 var a = document.createElement("a");
65 a.hidden = '';
66 a.href = dnlk;
67 a.download = "save.xml";
68 a.textContent = "Save File";
69
70 var submitDiv = document.getElementById('download-point');
71 submitDiv.appendChild(a);
72 }
55 } 73 }
56 74
57 function AudioEngine() { 75 function AudioEngine() {
58 76
59 // Create two output paths, the main outputGain and fooGain. 77 // Create two output paths, the main outputGain and fooGain.
62 // because web audio will optimise and any route which does not go to the destination gets ignored. 80 // because web audio will optimise and any route which does not go to the destination gets ignored.
63 this.outputGain = audioContext.createGain(); 81 this.outputGain = audioContext.createGain();
64 this.fooGain = audioContext.createGain(); 82 this.fooGain = audioContext.createGain();
65 this.fooGain.gain = 0; 83 this.fooGain.gain = 0;
66 84
85 // Use this to detect playback state: 0 - stopped, 1 - playing
86 this.status = 0;
87
67 // Connect both gains to output 88 // Connect both gains to output
68 this.outputGain.connect(audioContext.destination); 89 this.outputGain.connect(audioContext.destination);
69 this.fooGain.connect(audioContext.destination); 90 this.fooGain.connect(audioContext.destination);
70 91
71 // Create store for new audioObjects 92 // Create store for new audioObjects
72 this.audioObjects = []; 93 this.audioObjects = [];
73 94
74 this.play = function() { 95 this.play = function() {
75 // Send play command to all playback buffers for synchronised start 96 // Send play command to all playback buffers for synchronised start
76 // Also start timer callbacks to detect if playback has finished 97 // Also start timer callbacks to detect if playback has finished
98 if (this.status == 0) {
99 // First get current clock
100 var timer = audioContext.currentTime;
101 // Add 3 seconds
102 timer += 3.0;
103
104 // Send play to all tracks
105 for (var i=0; i<this.audioObjects.length; i++)
106 {
107 this.audioObjects[i].play(timer);
108 }
109 this.status = 1;
110 }
77 } 111 }
78 112
79 this.stop = function() { 113 this.stop = function() {
80 // Send stop and reset command to all playback buffers 114 // Send stop and reset command to all playback buffers
115 if (this.status == 1) {
116 for (var i=0; i<this.audioObjects.length; i++)
117 {
118 this.audioObjects[i].stop();
119 }
120 this.status = 0;
121 }
81 } 122 }
82 123
83 this.newTrack = function(url) { 124 this.newTrack = function(url) {
84 // Pull data from given URL into new audio buffer 125 // Pull data from given URL into new audio buffer
85 // URLs must either be from the same source OR be setup to 'Access-Control-Allow-Origin' 126 // URLs must either be from the same source OR be setup to 'Access-Control-Allow-Origin'
86 var request = new XMLHttpRequest(); 127
87 request.open('GET',url,true);
88 request.responseType = 'arraybuffer';
89 // Create the audioObject with ID of the new track length; 128 // Create the audioObject with ID of the new track length;
90 audioObjectId = this.audioObjects.length 129 audioObjectId = this.audioObjects.length
91 this.audioObjects[audioObjectId] = new audioObject(audioObjectId); 130 this.audioObjects[audioObjectId] = new audioObject(audioObjectId);
92 131
93 // Create callback to decode the data asynchronously 132 // AudioObject will get track itself.
94 request.onload = function() { 133 this.audioObjects[audioObjectId].constructTrack(url);
95 audioContext.decodeAudioData(request.response, function(decodedData) {
96 audioObj = audioEngineContext.audioObjects[audioObjectId];
97 audioObj.buffer = decodedData;
98 audioObj.bufferNode.buffer = audioObj.buffer;
99 audioObj.state = 1;
100 }, console.log("Err - Buffer not added to " + audioObjectId));
101 }
102 request.send();
103 } 134 }
104 135
105 } 136 }
106 137
107 function audioObject(id) { 138 function audioObject(id) {
129 this.stop = function() { 160 this.stop = function() {
130 this.bufferNode.stop(0); 161 this.bufferNode.stop(0);
131 this.bufferNode = audioContext.createBufferSource(); 162 this.bufferNode = audioContext.createBufferSource();
132 this.bufferNode.connect(this.outputGain); 163 this.bufferNode.connect(this.outputGain);
133 this.bufferNode.buffer = this.buffer; 164 this.bufferNode.buffer = this.buffer;
165 this.bufferNode.loop = true;
166 }
167
168 this.constructTrack = function(url) {
169 var request = new XMLHttpRequest();
170 request.open('GET',url,true);
171 request.responseType = 'arraybuffer';
172
173 var audioObj = this;
174
175 // Create callback to decode the data asynchronously
176 request.onloadend = function() {
177 audioContext.decodeAudioData(request.response, function(decodedData) {
178 audioObj.buffer = decodedData;
179 audioObj.bufferNode.buffer = audioObj.buffer;
180 audioObj.bufferNode.loop = true;
181 audioObj.state = 1;
182 }, function(){
183 // Should only be called if there was an error, but sometimes gets called continuously
184 // Check here if the error is genuine
185 if (audioObj.state == 0 || audioObj.buffer == undefined) {
186 // Genuine error
187 console.log('FATAL - Error loading buffer on '+audioObj.id);
188 }
189 });
190 }
191 request.send();
134 } 192 }
135 193
136 } 194 }