1 |
|
---|
2 | // Audio objects
|
---|
3 | var baseSong;
|
---|
4 | var leftSong;
|
---|
5 | var rightSong;
|
---|
6 |
|
---|
7 | var pannedPlayback = new Audio();
|
---|
8 |
|
---|
9 | var leftBuffers = [];
|
---|
10 | var rightBuffers = [];
|
---|
11 |
|
---|
12 | var leftStartTimeSecs = 0.0;
|
---|
13 | var rightStartTimeSecs = 0.0;
|
---|
14 | var leftStartTimeOffset = 0;
|
---|
15 | var rightStartTimeOffset = 0;
|
---|
16 |
|
---|
17 | var totalFullBufferSize = 0;
|
---|
18 |
|
---|
19 | function resetAudioBuffers()
|
---|
20 | {
|
---|
21 | console.log("Panned audio playback buffers initialized/reset");
|
---|
22 |
|
---|
23 | pannedPlayback = new Audio();
|
---|
24 |
|
---|
25 | leftBuffers = [];
|
---|
26 | rightBuffers = [];
|
---|
27 |
|
---|
28 | leftStartTimeSecs = 0.0;
|
---|
29 | rightStartTimeSecs = 0.0;
|
---|
30 | leftStartTimeOffset = 0;
|
---|
31 | rightStartTimeOffset = 0;
|
---|
32 |
|
---|
33 | totalFullBufferSize = 0;
|
---|
34 | }
|
---|
35 |
|
---|
36 | function dualPlay(evt)
|
---|
37 | {
|
---|
38 | //var target = evt.target;
|
---|
39 | //console.log("target = " + target);
|
---|
40 |
|
---|
41 | var img_x = $("#selfSimImgId").offset().left;
|
---|
42 | var img_y = $("#selfSimImgId").offset().top;
|
---|
43 |
|
---|
44 | var mouse_x = evt.clientX;
|
---|
45 | var mouse_y = evt.clientY;
|
---|
46 |
|
---|
47 | var x_org = mouse_x - img_x;
|
---|
48 | var y_org = mouse_y - img_y;
|
---|
49 |
|
---|
50 | //console.log("mouse (x y) = (" + mouse_x + "," + mouse_y + ")");
|
---|
51 | //console.log("(x y) = (" + x_org + "," + y_org + ")");
|
---|
52 |
|
---|
53 | var mysong = document.getElementById("mysong");
|
---|
54 | var barWidth = mysong.getElementWidth();
|
---|
55 |
|
---|
56 | var baseSongSrc="sites/localsite/collect/" + collect +"/import/"+source;
|
---|
57 |
|
---|
58 | leftStartTimeSecs = duration * x_org / barWidth;
|
---|
59 | rightStartTimeSecs = duration * y_org / barWidth;
|
---|
60 |
|
---|
61 | var sampleMult = * baseSong.mozSampleRate * baseSong.mozChannels;
|
---|
62 | leftStartTimeOffset = leftStartTimeSecs * sampleMult;
|
---|
63 | rightStartTimeOffset = rightStartTimeSecs * sampleMult;
|
---|
64 |
|
---|
65 | leftSong.src = baseSongSrc;
|
---|
66 | rightSong.src = baseSongSrc;
|
---|
67 |
|
---|
68 | resetAudioBuffer();
|
---|
69 | }
|
---|
70 |
|
---|
71 | function svgInitSimilarityPlay()
|
---|
72 | {
|
---|
73 | var mysong = document.getElementById("mysong");
|
---|
74 | var barWidth = mysong.getElementWidth();
|
---|
75 |
|
---|
76 | var baseSongSrc="sites/localsite/collect/" + collect +"/import/"+source;
|
---|
77 |
|
---|
78 | baseSong = new Audio();
|
---|
79 | baseSong.src = baseSongSrc;
|
---|
80 | baseSong.control = "control";
|
---|
81 |
|
---|
82 | baseSong.addEventListener('MozAudioAvailable', audioAvailable, false);
|
---|
83 | baseSong.addEventListener('loadedmetadata', loadedMetadata, false);
|
---|
84 |
|
---|
85 | leftSong = new Audio();
|
---|
86 | leftSong.addEventListener('MozAudioAvailable', audioAvailableLeft, false);
|
---|
87 | leftSong.addEventListener('loadedmetadata', loadedMetadataLeft, false);
|
---|
88 |
|
---|
89 | rightSong = new Audio();
|
---|
90 | rightSong.addEventListener('MozAudioAvailable', audioAvailableRight, false);
|
---|
91 | rightSong.addEventListener('loadedmetadata', loadedMetadataRight, false);
|
---|
92 |
|
---|
93 |
|
---|
94 | // Set up self similarity image
|
---|
95 |
|
---|
96 | var selfSimImgSrc="sites/localsite/collect/" + collect +"/bordered/"+self_sim_png;
|
---|
97 | console.log("self sim img = " + selfSimImgSrc);
|
---|
98 |
|
---|
99 | var simPlayLine = document.getElementById("simPlayLineGroup");
|
---|
100 |
|
---|
101 | var selfSimImg = document.createElementNS(SVG_NS,"image");
|
---|
102 | selfSimImg.setAttributeNS(XLINK_NS, "xlink:href", selfSimImgSrc);
|
---|
103 |
|
---|
104 | var selfSimImgHeight = barWidth * (815.0 / 776.0);
|
---|
105 |
|
---|
106 | selfSimImg.setAttribute("x",0);
|
---|
107 | selfSimImg.setAttribute("y",30);
|
---|
108 | selfSimImg.setAttribute("id","selfSimImgId");
|
---|
109 | selfSimImg.setAttribute("width",barWidth);
|
---|
110 | selfSimImg.setAttribute("height",selfSimImgHeight);
|
---|
111 | selfSimImg.setAttribute("onclick","dualPlay(evt)");
|
---|
112 |
|
---|
113 | simPlayLine.appendChild(selfSimImg);
|
---|
114 | /*
|
---|
115 |
|
---|
116 | var searchImgElem = document.createElementNS(SVG_NS,'image');
|
---|
117 | searchImgElem.setAttributeNS(XLINK_NS, "xlink:href",
|
---|
118 | "ext/audioDB/icons/search20.png");
|
---|
119 | searchImgElem.setAttribute("x","544");
|
---|
120 | searchImgElem.setAttribute("y","42");
|
---|
121 | searchImgElem.setAttribute("width","20");
|
---|
122 | searchImgElem.setAttribute("height","20");
|
---|
123 | //var onclickSearch ="searchSubmit(100)";
|
---|
124 | var onclickSearch ="dualPlay(evt)";
|
---|
125 | searchImgElem.setAttribute("onclick",onclickSearch);
|
---|
126 | simPlayLine.appendChild(searchImgElem);
|
---|
127 | */
|
---|
128 |
|
---|
129 |
|
---|
130 | var svgSimilarityPlay = document.getElementById("svgSimilarityPlay");
|
---|
131 | svgSimilarityPlay.setAttribute("height",30 + selfSimImgHeight);
|
---|
132 |
|
---|
133 |
|
---|
134 | }
|
---|
135 |
|
---|
136 |
|
---|
137 |
|
---|
138 |
|
---|
139 | function loadedMetadata() {
|
---|
140 | // Mute baseSong audio.
|
---|
141 | baseSong.volume = 0;
|
---|
142 |
|
---|
143 | // Set up a pannedPlayback for baseSong to routed through
|
---|
144 | console.log("num channels = " + baseSong.mozChannels);
|
---|
145 |
|
---|
146 | pannedPlayback.mozSetup(2, baseSong.mozSampleRate);
|
---|
147 |
|
---|
148 | }
|
---|
149 |
|
---|
150 |
|
---|
151 | function loadedMetadataLeft() {
|
---|
152 | // Mute baseSong audio.
|
---|
153 | leftSong.volume = 0;
|
---|
154 |
|
---|
155 | leftSong.currentTime = leftStartTimeSecs;
|
---|
156 | leftSong.play();
|
---|
157 | }
|
---|
158 |
|
---|
159 |
|
---|
160 | function loadedMetadataRigh() {
|
---|
161 | // Mute baseSong audio.
|
---|
162 | rightSong.volume = 0;
|
---|
163 |
|
---|
164 | rightSong.currentTime = rightStartTimeSecs;
|
---|
165 | rightSong.play();
|
---|
166 | }
|
---|
167 |
|
---|
168 | function audioAvailable(event) {
|
---|
169 | // Write the current framebuffer
|
---|
170 | alert("audioAvailable() should no longer be called");
|
---|
171 | var frameBuffer = event.frameBuffer; // frameBuffer is Float32Array
|
---|
172 | //writeAudio(frameBuffer);
|
---|
173 | }
|
---|
174 |
|
---|
175 | function audioAvailableLeft(event)
|
---|
176 | {
|
---|
177 | // Write the current framebuffer
|
---|
178 | var frameBuffer = event.frameBuffer;
|
---|
179 | writeAudio(frameBuffer,"left");
|
---|
180 | }
|
---|
181 |
|
---|
182 | function audioAvailableRight(event)
|
---|
183 | {
|
---|
184 | // Write the current framebuffer
|
---|
185 | var frameBuffer = event.frameBuffer;
|
---|
186 | writeAudio(frameBuffer,"right");
|
---|
187 | }
|
---|
188 |
|
---|
189 |
|
---|
190 |
|
---|
191 |
|
---|
192 | function activeAudioBuffer(audioBuffer,currentFullBufferSize,startTime)
|
---|
193 | {
|
---|
194 | var buffer;
|
---|
195 | if (currentFullBufferSize < startTime) {
|
---|
196 | // active audio starts at offset within this segment of audioBuffer
|
---|
197 |
|
---|
198 | var position = startTime - currentFullBufferSize;
|
---|
199 | buffer = audioBuffer.subarray(position);
|
---|
200 | }
|
---|
201 | else {
|
---|
202 | buffer = audioBuffer;
|
---|
203 | }
|
---|
204 | return buffer;
|
---|
205 | }
|
---|
206 |
|
---|
207 | function panLeftEffect(buffer,s,panned_buffer,d)
|
---|
208 | {
|
---|
209 | panned_buffer[d] = buffer[s];
|
---|
210 | if ((d+1) < panned_buffer.length) {
|
---|
211 | panned_buffer[d+1] = 0;
|
---|
212 | }
|
---|
213 | }
|
---|
214 |
|
---|
215 | function panRightEffect(buffer,s,panned_buffer,d)
|
---|
216 | {
|
---|
217 | panned_buffer[d] = 0;
|
---|
218 | if ((d+1) < panned_buffer.length) {
|
---|
219 | panned_buffer[d+1] = buffer[s];
|
---|
220 | }
|
---|
221 | }
|
---|
222 |
|
---|
223 | function panAudioBuffersHead(buffer,position,panEffect)
|
---|
224 | {
|
---|
225 | var remaining_len = buffer.length - position;
|
---|
226 | var panned_buffer;
|
---|
227 | if (baseSong.mozChannels == 1) {
|
---|
228 | panned_buffer = new Float32Array(remaining_len * 2);
|
---|
229 |
|
---|
230 | var d=0;
|
---|
231 | for (var s=position; s < buffer.length; s++) {
|
---|
232 | panEffect(buffer,s,panned_buffer,d);
|
---|
233 | d += 2;
|
---|
234 | }
|
---|
235 | }
|
---|
236 | else {
|
---|
237 | // assume stereo
|
---|
238 | panned_buffer = new Float32Array(remaining_len);
|
---|
239 |
|
---|
240 | var d=0;
|
---|
241 | for (var s=position; s < buffer.length; s+=2) {
|
---|
242 | panEffect(buffer,s,panned_buffer,d);
|
---|
243 | d += 2;
|
---|
244 | }
|
---|
245 | }
|
---|
246 |
|
---|
247 | return panned_buffer;
|
---|
248 | }
|
---|
249 |
|
---|
250 | function mergeLeftAndRightPan(leftPannedBuffer,rightPannedBuffer)
|
---|
251 | {
|
---|
252 | // left and right buffers guaranteed to be stereo samples
|
---|
253 |
|
---|
254 | var leftLen = leftPannedBuffer.length;
|
---|
255 | var rightLen = rightPannedBuffer.length;
|
---|
256 | var maxLen = Math.max(leftLen,rightLen);
|
---|
257 |
|
---|
258 | var pannedBuffer = new Float32Array(maxLen);
|
---|
259 |
|
---|
260 | for (i=0; i < maxLen; i+=2) {
|
---|
261 |
|
---|
262 | if (i < leftLen) {
|
---|
263 | pannedBuffer[i] = leftPannedBuffer[i];
|
---|
264 | }
|
---|
265 | else {
|
---|
266 | pannedBuffer[i] = 0;
|
---|
267 | }
|
---|
268 |
|
---|
269 | if (i < leftLen) {
|
---|
270 | pannedBuffer[i+1] = rightPannedBuffer[i+1];
|
---|
271 | }
|
---|
272 | else {
|
---|
273 | pannedBuffer[i+1] = 0;
|
---|
274 | }
|
---|
275 | }
|
---|
276 |
|
---|
277 | return pannedBuffer;
|
---|
278 |
|
---|
279 | }
|
---|
280 |
|
---|
281 | function writeAudio(audioBuffer,channel) {
|
---|
282 |
|
---|
283 | // audioBuffer is Float32Array
|
---|
284 | var audioBufferLen = audioBuffer.length;
|
---|
285 |
|
---|
286 | if ((totalFullBufferSize + audioBufferLen) > leftStartTimeOffset) {
|
---|
287 | var leftBuffer = activeAudioBuffer(audioBuffer,totalFullBufferSize,leftStartTime);
|
---|
288 | leftBuffers.push({buffer: leftBuffer, position: 0});
|
---|
289 | }
|
---|
290 |
|
---|
291 | if ((totalFullBufferSize + audioBufferLen) > rightStartTimeOffset) {
|
---|
292 | var rightBuffer = activeAudioBuffer(audioBuffer,totalFullBufferSize,rightStartTime);
|
---|
293 | rightBuffers.push({buffer: rightBuffer, position: 0});
|
---|
294 | }
|
---|
295 |
|
---|
296 | totalFullBufferSize += audioBufferLen;
|
---|
297 |
|
---|
298 |
|
---|
299 | // If there's buffered data in both left and right buffers,
|
---|
300 | // then it's time to play something
|
---|
301 |
|
---|
302 | while((leftBuffers.length > 0) && (rightBuffers.length > 0)) {
|
---|
303 |
|
---|
304 | var leftBuffer = leftBuffers[0].buffer;
|
---|
305 | var leftBufferPos = leftBuffers[0].position;
|
---|
306 | var leftPannedBuffer = panAudioBuffersHead(leftBuffer,leftBufferPos,panLeftEffect);
|
---|
307 |
|
---|
308 | var rightBuffer = rightBuffers[0].buffer;
|
---|
309 | var rightBufferPos = rightBuffers[0].position;
|
---|
310 | var rightPannedBuffer = panAudioBuffersHead(rightBuffer,rightBufferPos,panRightEffect);
|
---|
311 |
|
---|
312 | var pannedBuffer = mergeLeftAndRightPan(leftPannedBuffer,rightPannedBuffer);
|
---|
313 |
|
---|
314 | //var written = pannedPlayback.mozWriteAudio(buffer.subarray(position));
|
---|
315 | var written = pannedPlayback.mozWriteAudio(pannedBuffer);
|
---|
316 |
|
---|
317 | // // If all data wasn't written, keep it in the buffers:
|
---|
318 | var doBreak = false;
|
---|
319 |
|
---|
320 | if (leftBufferPos + written < leftBuffer.length) {
|
---|
321 | leftBuffers[0].position = leftBufferPos + written;
|
---|
322 | doBreak = true;
|
---|
323 | }
|
---|
324 | else {
|
---|
325 | leftBuffers.shift();
|
---|
326 | }
|
---|
327 |
|
---|
328 | if (rightBufferPos + written < rightBuffer.length) {
|
---|
329 | rightBuffers[0].position = rightBufferPos + written;
|
---|
330 | doBreak = true;
|
---|
331 | }
|
---|
332 | else {
|
---|
333 | rightBuffers.shift();
|
---|
334 | }
|
---|
335 |
|
---|
336 | if (doBreak) {
|
---|
337 | break;
|
---|
338 | }
|
---|
339 | }
|
---|
340 | }
|
---|