Mercurial > hg > webaudioevaluationtool
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 } |