wavesurfer.js 6.6.1 → 6.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/plugin/wavesurfer.cursor.js +1 -1
- package/dist/plugin/wavesurfer.cursor.min.js +1 -1
- package/dist/plugin/wavesurfer.elan.js +1 -1
- package/dist/plugin/wavesurfer.elan.min.js +1 -1
- package/dist/plugin/wavesurfer.markers.js +12 -3
- package/dist/plugin/wavesurfer.markers.js.map +1 -1
- package/dist/plugin/wavesurfer.markers.min.js +2 -2
- package/dist/plugin/wavesurfer.markers.min.js.map +1 -1
- package/dist/plugin/wavesurfer.mediasession.js +1 -1
- package/dist/plugin/wavesurfer.mediasession.min.js +1 -1
- package/dist/plugin/wavesurfer.microphone.js +1 -1
- package/dist/plugin/wavesurfer.microphone.min.js +1 -1
- package/dist/plugin/wavesurfer.minimap.js +1 -1
- package/dist/plugin/wavesurfer.minimap.min.js +1 -1
- package/dist/plugin/wavesurfer.playhead.js +1 -1
- package/dist/plugin/wavesurfer.playhead.min.js +1 -1
- package/dist/plugin/wavesurfer.regions.js +1 -1
- package/dist/plugin/wavesurfer.regions.min.js +1 -1
- package/dist/plugin/wavesurfer.spectrogram.js +34 -128
- package/dist/plugin/wavesurfer.spectrogram.js.map +1 -1
- package/dist/plugin/wavesurfer.spectrogram.min.js +2 -2
- package/dist/plugin/wavesurfer.spectrogram.min.js.map +1 -1
- package/dist/plugin/wavesurfer.timeline.js +1 -1
- package/dist/plugin/wavesurfer.timeline.min.js +1 -1
- package/dist/wavesurfer-html-init.js +1 -1
- package/dist/wavesurfer-html-init.min.js +1 -1
- package/dist/wavesurfer.js +16 -186
- package/dist/wavesurfer.js.map +1 -1
- package/dist/wavesurfer.min.js +2 -2
- package/dist/wavesurfer.min.js.map +1 -1
- package/package.json +1 -1
- package/src/drawer.canvasentry.js +0 -43
- package/src/drawer.js +4 -0
- package/src/drawer.multicanvas.js +1 -71
- package/src/plugin/markers/index.js +9 -2
- package/src/plugin/spectrogram/index.js +30 -121
- package/src/wavesurfer.js +0 -33
- package/src/webaudio.js +9 -26
package/package.json
CHANGED
|
@@ -66,11 +66,6 @@ export default class CanvasEntry {
|
|
|
66
66
|
* @type {object}
|
|
67
67
|
*/
|
|
68
68
|
this.canvasContextAttributes = {};
|
|
69
|
-
/**
|
|
70
|
-
* The Timeout id used to track this canvas entry.
|
|
71
|
-
*/
|
|
72
|
-
this.drawTimeout = null;
|
|
73
|
-
|
|
74
69
|
}
|
|
75
70
|
|
|
76
71
|
/**
|
|
@@ -130,27 +125,21 @@ export default class CanvasEntry {
|
|
|
130
125
|
*/
|
|
131
126
|
clearWave() {
|
|
132
127
|
// wave
|
|
133
|
-
this.waveCtx.save();
|
|
134
|
-
this.waveCtx.setTransform(1, 0, 0, 1, 0, 0);
|
|
135
128
|
this.waveCtx.clearRect(
|
|
136
129
|
0,
|
|
137
130
|
0,
|
|
138
131
|
this.waveCtx.canvas.width,
|
|
139
132
|
this.waveCtx.canvas.height
|
|
140
133
|
);
|
|
141
|
-
this.waveCtx.restore();
|
|
142
134
|
|
|
143
135
|
// progress
|
|
144
136
|
if (this.hasProgressCanvas) {
|
|
145
|
-
this.progressCtx.save();
|
|
146
|
-
this.progressCtx.setTransform(1, 0, 0, 1, 0, 0);
|
|
147
137
|
this.progressCtx.clearRect(
|
|
148
138
|
0,
|
|
149
139
|
0,
|
|
150
140
|
this.progressCtx.canvas.width,
|
|
151
141
|
this.progressCtx.canvas.height
|
|
152
142
|
);
|
|
153
|
-
this.progressCtx.restore();
|
|
154
143
|
}
|
|
155
144
|
}
|
|
156
145
|
|
|
@@ -435,36 +424,4 @@ export default class CanvasEntry {
|
|
|
435
424
|
return this.wave.toDataURL(format, quality);
|
|
436
425
|
}
|
|
437
426
|
}
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Stretches existing canvas
|
|
441
|
-
* @param {Number} newTotalWidth total width of wave in pixels
|
|
442
|
-
*/
|
|
443
|
-
stretchCanvas(newTotalWidth) {
|
|
444
|
-
//Calculate the start and width of this canvas
|
|
445
|
-
let start = Math.round(this.start * newTotalWidth);
|
|
446
|
-
let width = Math.round(this.end * newTotalWidth - start);
|
|
447
|
-
|
|
448
|
-
//Stretch canvas
|
|
449
|
-
let elementSize = { width: width + 'px' };
|
|
450
|
-
let elementStart = {left: start + 'px'};
|
|
451
|
-
style(this.wave, elementSize);
|
|
452
|
-
style(this.wave, elementStart);
|
|
453
|
-
if (this.hasProgressCanvas) {
|
|
454
|
-
style(this.progress, elementSize);
|
|
455
|
-
style(this.progress, elementStart);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
/**
|
|
460
|
-
* Set the left offset of the canvas
|
|
461
|
-
* @param {Number} position in px for the canvas to start
|
|
462
|
-
*/
|
|
463
|
-
setLeft(position) {
|
|
464
|
-
let elementStart = {left: position + 'px'};
|
|
465
|
-
style(this.wave, elementStart);
|
|
466
|
-
if (this.hasProgressCanvas) {
|
|
467
|
-
style(this.progress, elementStart);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
427
|
}
|
package/src/drawer.js
CHANGED
|
@@ -272,6 +272,10 @@ export default class Drawer extends util.Observer {
|
|
|
272
272
|
* @return {boolean} Whether the width of the container was updated or not
|
|
273
273
|
*/
|
|
274
274
|
setWidth(width) {
|
|
275
|
+
if (this.width == width) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
|
|
275
279
|
this.width = width;
|
|
276
280
|
|
|
277
281
|
if (this.params.fillParent || this.params.scrollParent) {
|
|
@@ -89,14 +89,6 @@ export default class MultiCanvas extends Drawer {
|
|
|
89
89
|
* @type {boolean}
|
|
90
90
|
*/
|
|
91
91
|
this.vertical = params.vertical;
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Whether to use the optimsized zoom rendering
|
|
95
|
-
* Automatically toggles to true if stretchCanvases() function is called
|
|
96
|
-
*
|
|
97
|
-
* @type {boolean}
|
|
98
|
-
*/
|
|
99
|
-
this.optimiseZoom = false;
|
|
100
92
|
}
|
|
101
93
|
|
|
102
94
|
/**
|
|
@@ -165,16 +157,10 @@ export default class MultiCanvas extends Drawer {
|
|
|
165
157
|
|
|
166
158
|
let canvasWidth = this.maxCanvasWidth + this.overlap;
|
|
167
159
|
const lastCanvas = this.canvases.length - 1;
|
|
168
|
-
let leftOffset = 0;
|
|
169
160
|
this.canvases.forEach((entry, i) => {
|
|
170
161
|
if (i == lastCanvas) {
|
|
171
162
|
canvasWidth = this.width - this.maxCanvasWidth * lastCanvas;
|
|
172
163
|
}
|
|
173
|
-
|
|
174
|
-
//Set left offset and add to next entry
|
|
175
|
-
entry.setLeft(leftOffset);
|
|
176
|
-
leftOffset += canvasWidth / this.params.pixelRatio;
|
|
177
|
-
|
|
178
164
|
this.updateDimensions(entry, canvasWidth, this.height);
|
|
179
165
|
|
|
180
166
|
entry.clearWave();
|
|
@@ -424,39 +410,7 @@ export default class MultiCanvas extends Drawer {
|
|
|
424
410
|
this.canvases.forEach((entry, i) => {
|
|
425
411
|
this.setFillStyles(entry, waveColor, progressColor);
|
|
426
412
|
this.applyCanvasTransforms(entry, this.params.vertical);
|
|
427
|
-
|
|
428
|
-
if (this.optimiseZoom) {
|
|
429
|
-
//Optimising zoom functionality
|
|
430
|
-
//If there's a wrapper, optimise for the view
|
|
431
|
-
let priority = 0;
|
|
432
|
-
if (this.wrapper) {
|
|
433
|
-
let canvasRect = entry.wave.getBoundingClientRect();
|
|
434
|
-
let wrapperRect = this.wrapper.getBoundingClientRect();
|
|
435
|
-
|
|
436
|
-
//Determine whether canvas is in viewframe or not and assign priority
|
|
437
|
-
if (Math.floor(canvasRect['left']) > Math.ceil(wrapperRect['right'])) {
|
|
438
|
-
//Canvas is to the right of view window
|
|
439
|
-
let distance = canvasRect['left'] - wrapperRect['right'];
|
|
440
|
-
priority = Math.ceil(distance / wrapperRect['width']);
|
|
441
|
-
} else if (Math.ceil(canvasRect['right']) < Math.floor(wrapperRect['left'])) {
|
|
442
|
-
//Canvas is to the left of the view window
|
|
443
|
-
let distance = wrapperRect['left'] - canvasRect['right'];
|
|
444
|
-
priority = Math.ceil(distance / wrapperRect['width']);
|
|
445
|
-
}
|
|
446
|
-
} else {
|
|
447
|
-
//Everything is equal priority
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
//This staggers the drawing of canvases so they don't all draw at once
|
|
451
|
-
entry.clearWave();
|
|
452
|
-
clearTimeout(entry.drawTimeout);
|
|
453
|
-
entry.drawTimeout = setTimeout(function(){
|
|
454
|
-
entry.drawLines(peaks, absmax, halfH, offsetY, start, end);
|
|
455
|
-
entry.drawTimeout = null;
|
|
456
|
-
}, 25 * priority);
|
|
457
|
-
} else {
|
|
458
|
-
entry.drawLines(peaks, absmax, halfH, offsetY, start, end);
|
|
459
|
-
}
|
|
413
|
+
entry.drawLines(peaks, absmax, halfH, offsetY, start, end);
|
|
460
414
|
});
|
|
461
415
|
}
|
|
462
416
|
|
|
@@ -652,30 +606,6 @@ export default class MultiCanvas extends Drawer {
|
|
|
652
606
|
}
|
|
653
607
|
}
|
|
654
608
|
|
|
655
|
-
/**
|
|
656
|
-
* Stretches the canvases to mimic zoom without recalculation
|
|
657
|
-
*
|
|
658
|
-
* @param {Number} desiredWidth new width of the wave display
|
|
659
|
-
* @param {Number} progress Value between 0 and 1 for wave progress
|
|
660
|
-
*/
|
|
661
|
-
stretchCanvases(desiredWidth, progress) {
|
|
662
|
-
if (!this.optimiseZoom) {
|
|
663
|
-
//Enable optimsed zooming
|
|
664
|
-
this.optimiseZoom = true;
|
|
665
|
-
}
|
|
666
|
-
let totalCanvasWidth = Math.round(desiredWidth / this.params.pixelRatio);
|
|
667
|
-
this.width = desiredWidth;
|
|
668
|
-
|
|
669
|
-
for (let i = 0; i < this.canvases.length; i++) {
|
|
670
|
-
this.canvases[i].stretchCanvas(totalCanvasWidth);
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
//Update progress
|
|
674
|
-
let progressPos = progress * totalCanvasWidth;
|
|
675
|
-
this.updateProgress(progressPos);
|
|
676
|
-
this.recenterOnPosition(progressPos, true);
|
|
677
|
-
}
|
|
678
|
-
|
|
679
609
|
/**
|
|
680
610
|
* Render the new progress
|
|
681
611
|
*
|
|
@@ -70,6 +70,9 @@ export default class MarkersPlugin {
|
|
|
70
70
|
}
|
|
71
71
|
return this.markers.add(options);
|
|
72
72
|
},
|
|
73
|
+
getMarkers() {
|
|
74
|
+
return this.markers;
|
|
75
|
+
},
|
|
73
76
|
clearMarkers() {
|
|
74
77
|
this.markers && this.markers.clear();
|
|
75
78
|
}
|
|
@@ -181,9 +184,13 @@ export default class MarkersPlugin {
|
|
|
181
184
|
/**
|
|
182
185
|
* Remove a marker
|
|
183
186
|
*
|
|
184
|
-
* @param {number}
|
|
187
|
+
* @param {number|Object} indexOrMarker Index of the marker to remove or the marker object itself
|
|
185
188
|
*/
|
|
186
|
-
remove(
|
|
189
|
+
remove(indexOrMarker) {
|
|
190
|
+
let index = indexOrMarker;
|
|
191
|
+
if (isNaN(index)) {
|
|
192
|
+
index = this.markers.findIndex(marker => marker === indexOrMarker);
|
|
193
|
+
}
|
|
187
194
|
let marker = this.markers[index];
|
|
188
195
|
if (!marker) {
|
|
189
196
|
return;
|
|
@@ -92,9 +92,6 @@ export default class SpectrogramPlugin {
|
|
|
92
92
|
this._onRender = () => {
|
|
93
93
|
this.render();
|
|
94
94
|
};
|
|
95
|
-
this._onZoom = () => {
|
|
96
|
-
this.stretchCanvases();
|
|
97
|
-
};
|
|
98
95
|
this._onWrapperClick = e => {
|
|
99
96
|
this._wrapperClickHandler(e);
|
|
100
97
|
};
|
|
@@ -139,9 +136,6 @@ export default class SpectrogramPlugin {
|
|
|
139
136
|
this.alpha = params.alpha;
|
|
140
137
|
this.splitChannels = params.splitChannels;
|
|
141
138
|
this.channels = this.splitChannels ? ws.backend.buffer.numberOfChannels : 1;
|
|
142
|
-
this.canvases = [];
|
|
143
|
-
this.canvasesTimeouts = [];
|
|
144
|
-
this.scrollLeftTracker = 0; //Tracks the desired scrollLeft value
|
|
145
139
|
|
|
146
140
|
// Getting file's original samplerate is difficult(#1248).
|
|
147
141
|
// So set 12kHz default to render like wavesurfer.js 5.x.
|
|
@@ -149,11 +143,10 @@ export default class SpectrogramPlugin {
|
|
|
149
143
|
this.frequencyMax = params.frequencyMax || 12000;
|
|
150
144
|
|
|
151
145
|
this.createWrapper();
|
|
152
|
-
this.
|
|
146
|
+
this.createCanvas();
|
|
153
147
|
this.render();
|
|
154
148
|
|
|
155
149
|
drawer.wrapper.addEventListener('scroll', this._onScroll);
|
|
156
|
-
ws.on('zoom', this._onZoom);
|
|
157
150
|
ws.on('redraw', this._onRender);
|
|
158
151
|
};
|
|
159
152
|
}
|
|
@@ -238,49 +231,17 @@ export default class SpectrogramPlugin {
|
|
|
238
231
|
this.fireEvent('click', relX / this.width || 0);
|
|
239
232
|
}
|
|
240
233
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
*/
|
|
244
|
-
addCanvas() {
|
|
245
|
-
const canvas = (this.wrapper.appendChild(
|
|
234
|
+
createCanvas() {
|
|
235
|
+
const canvas = (this.canvas = this.wrapper.appendChild(
|
|
246
236
|
document.createElement('canvas')
|
|
247
237
|
));
|
|
248
238
|
|
|
239
|
+
this.spectrCc = canvas.getContext('2d');
|
|
240
|
+
|
|
249
241
|
this.util.style(canvas, {
|
|
250
242
|
position: 'absolute',
|
|
251
243
|
zIndex: 4
|
|
252
244
|
});
|
|
253
|
-
|
|
254
|
-
this.canvases.push(canvas);
|
|
255
|
-
this.canvasesTimeouts.push(null);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Remove a canvas from this.canvases
|
|
260
|
-
*/
|
|
261
|
-
removeCanvas() {
|
|
262
|
-
//Stop drawing (if drawing)
|
|
263
|
-
clearTimeout(this.canvasesTimeouts[this.canvasesTimeouts.length - 1]);
|
|
264
|
-
|
|
265
|
-
let lastEntry = this.canvases[this.canvases.length - 1];
|
|
266
|
-
lastEntry.parentElement.removeChild(lastEntry);
|
|
267
|
-
|
|
268
|
-
this.canvases.pop();
|
|
269
|
-
this.canvasesTimeouts.pop();
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* Ensure the correct number of canvases for the size of the spectrogram
|
|
274
|
-
*/
|
|
275
|
-
updateCanvases() {
|
|
276
|
-
let canvasesRequired = Math.ceil(this.width / 4000);
|
|
277
|
-
|
|
278
|
-
while (this.canvases.length < canvasesRequired) {
|
|
279
|
-
this.addCanvas();
|
|
280
|
-
}
|
|
281
|
-
while (this.canvases.length > canvasesRequired) {
|
|
282
|
-
this.removeCanvas();
|
|
283
|
-
}
|
|
284
245
|
}
|
|
285
246
|
|
|
286
247
|
render() {
|
|
@@ -294,14 +255,11 @@ export default class SpectrogramPlugin {
|
|
|
294
255
|
}
|
|
295
256
|
|
|
296
257
|
updateCanvasStyle() {
|
|
297
|
-
this.
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
this.canvases[i].style.width = Math.round(this.canvases[i].width / this.pixelRatio) + 'px';
|
|
303
|
-
this.canvases[i].style.height = this.height + 'px';
|
|
304
|
-
}
|
|
258
|
+
const width = Math.round(this.width / this.pixelRatio) + 'px';
|
|
259
|
+
this.canvas.width = this.width;
|
|
260
|
+
this.canvas.height = this.fftSamples / 2 * this.channels;
|
|
261
|
+
this.canvas.style.width = width;
|
|
262
|
+
this.canvas.style.height = this.height + 'px';
|
|
305
263
|
}
|
|
306
264
|
|
|
307
265
|
drawSpectrogram(frequenciesData, my) {
|
|
@@ -310,61 +268,25 @@ export default class SpectrogramPlugin {
|
|
|
310
268
|
frequenciesData = [frequenciesData];
|
|
311
269
|
}
|
|
312
270
|
|
|
313
|
-
my.
|
|
314
|
-
|
|
315
|
-
//Stop canvases still being drawn
|
|
316
|
-
for (let i = 0; i < my.canvasesTimeouts.length; i++) {
|
|
317
|
-
clearTimeout(my.canvasesTimeouts[i]);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
const view = [my.scrollLeftTracker, my.scrollLeftTracker + my.wrapper.clientWidth];
|
|
321
|
-
|
|
322
|
-
for (let canvasNum = 0; canvasNum < my.canvases.length; canvasNum++) {
|
|
323
|
-
const canvasLeft = canvasNum * Math.floor(my.width / my.canvases.length / my.pixelRatio);
|
|
324
|
-
const canvasRight = (canvasNum + 1) * Math.floor(my.width / my.canvases.length / my.pixelRatio);
|
|
325
|
-
const canvasBound = [canvasLeft, canvasRight];
|
|
326
|
-
my.canvases[canvasNum].style['left'] = canvasLeft + 'px';
|
|
327
|
-
|
|
328
|
-
//Optimise drawing for the view
|
|
329
|
-
let priority = 0;
|
|
330
|
-
if (canvasBound[0] > view[1]) {
|
|
331
|
-
//Canvas is to the right of view window
|
|
332
|
-
let distance = canvasBound[0] - view[1];
|
|
333
|
-
priority = Math.ceil(distance / (view[1] - view[0]));
|
|
334
|
-
} else if (canvasBound[1] < view[0]) {
|
|
335
|
-
//Canvas is to the left of the view window
|
|
336
|
-
let distance = view[0] - canvasBound[1];
|
|
337
|
-
priority = Math.ceil(distance / (view[1] - view[0]));
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
//delay = 25ms * number of viewport widths away the canvas is
|
|
341
|
-
my.canvasesTimeouts[canvasNum] = setTimeout(my.drawToCanvas, 25 * priority, frequenciesData, my, canvasNum);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Draw spectrogram channel to a specific canvas
|
|
347
|
-
* @param {[Number, Number, Number]} frequenciesData spectrogram data in [channel, sample, freq] format
|
|
348
|
-
* @param {SpectrogramPlugin} my variable with 'this' in it
|
|
349
|
-
* @param {Number} canvasNum Canvas to draw to
|
|
350
|
-
*/
|
|
351
|
-
drawToCanvas(frequenciesData, my, canvasNum) {
|
|
271
|
+
const spectrCc = my.spectrCc;
|
|
352
272
|
const height = my.fftSamples / 2;
|
|
273
|
+
const width = my.width;
|
|
353
274
|
const freqFrom = my.buffer.sampleRate / 2;
|
|
354
275
|
const freqMin = my.frequencyMin;
|
|
355
276
|
const freqMax = my.frequencyMax;
|
|
356
277
|
|
|
357
|
-
|
|
278
|
+
if (!spectrCc) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
358
281
|
|
|
359
|
-
|
|
360
|
-
const
|
|
361
|
-
const
|
|
362
|
-
const imageData = new ImageData(pixels.length, height);
|
|
282
|
+
for (let c = 0; c < frequenciesData.length; c++) { // for each channel
|
|
283
|
+
const pixels = my.resample(frequenciesData[c]);
|
|
284
|
+
const imageData = new ImageData(width, height);
|
|
363
285
|
|
|
364
286
|
for (let i = 0; i < pixels.length; i++) {
|
|
365
287
|
for (let j = 0; j < pixels[i].length; j++) {
|
|
366
288
|
const colorMap = my.colorMap[pixels[i][j]];
|
|
367
|
-
const redIndex = ((height - j) *
|
|
289
|
+
const redIndex = ((height - j) * width + i) * 4;
|
|
368
290
|
imageData.data[redIndex] = colorMap[0] * 255;
|
|
369
291
|
imageData.data[redIndex + 1] = colorMap[1] * 255;
|
|
370
292
|
imageData.data[redIndex + 2] = colorMap[2] * 255;
|
|
@@ -372,20 +294,16 @@ export default class SpectrogramPlugin {
|
|
|
372
294
|
}
|
|
373
295
|
}
|
|
374
296
|
|
|
375
|
-
//
|
|
376
|
-
createImageBitmap(imageData).then(renderer =>
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
});
|
|
297
|
+
// scale and stack spectrograms
|
|
298
|
+
createImageBitmap(imageData).then(renderer =>
|
|
299
|
+
spectrCc.drawImage(renderer,
|
|
300
|
+
0, height * (1 - freqMax / freqFrom), // source x, y
|
|
301
|
+
width, height * (freqMax - freqMin) / freqFrom, // source width, height
|
|
302
|
+
0, height * c, // destination x, y
|
|
303
|
+
width, height // destination width, height
|
|
304
|
+
)
|
|
305
|
+
);
|
|
386
306
|
}
|
|
387
|
-
//Drawing is finished
|
|
388
|
-
my.canvasesTimeouts[canvasNum] = null;
|
|
389
307
|
}
|
|
390
308
|
|
|
391
309
|
getFrequencies(callback) {
|
|
@@ -404,7 +322,7 @@ export default class SpectrogramPlugin {
|
|
|
404
322
|
|
|
405
323
|
let noverlap = this.noverlap;
|
|
406
324
|
if (!noverlap) {
|
|
407
|
-
const uniqueSamplesPerPx = buffer.length / this.width;
|
|
325
|
+
const uniqueSamplesPerPx = buffer.length / this.canvas.width;
|
|
408
326
|
noverlap = Math.max(0, Math.round(fftSamples - uniqueSamplesPerPx));
|
|
409
327
|
}
|
|
410
328
|
|
|
@@ -543,13 +461,12 @@ export default class SpectrogramPlugin {
|
|
|
543
461
|
|
|
544
462
|
updateScroll(e) {
|
|
545
463
|
if (this.wrapper) {
|
|
546
|
-
this.scrollLeftTracker = e.target.scrollLeft;
|
|
547
464
|
this.wrapper.scrollLeft = e.target.scrollLeft;
|
|
548
465
|
}
|
|
549
466
|
}
|
|
550
467
|
|
|
551
468
|
resample(oldMatrix) {
|
|
552
|
-
const columnsNumber =
|
|
469
|
+
const columnsNumber = this.width;
|
|
553
470
|
const newMatrix = [];
|
|
554
471
|
|
|
555
472
|
const oldPiece = 1 / oldMatrix.length;
|
|
@@ -602,12 +519,4 @@ export default class SpectrogramPlugin {
|
|
|
602
519
|
|
|
603
520
|
return newMatrix;
|
|
604
521
|
}
|
|
605
|
-
|
|
606
|
-
stretchCanvases() {
|
|
607
|
-
for (let i = 0; i < this.canvases.length; i++) {
|
|
608
|
-
this.canvases[i].style.width = Math.round(this.drawer.width / this.canvases.length / this.pixelRatio) + 'px';
|
|
609
|
-
const canvasLeft = i * Math.floor(this.drawer.width / this.canvases.length / this.pixelRatio);
|
|
610
|
-
this.canvases[i].style['left'] = canvasLeft + 'px';
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
522
|
}
|
package/src/wavesurfer.js
CHANGED
|
@@ -1275,21 +1275,6 @@ export default class WaveSurfer extends util.Observer {
|
|
|
1275
1275
|
this.drawBuffer();
|
|
1276
1276
|
}
|
|
1277
1277
|
|
|
1278
|
-
/**
|
|
1279
|
-
* Calls getPeaks() and drawPeaks()
|
|
1280
|
-
* @param {WaveSurfer} wavesurfer the Wavesurfer to get/draw peaks from/to
|
|
1281
|
-
* @param {number} width The width of the area that should be drawn
|
|
1282
|
-
* @param {number} start The x-offset of the beginning of the area that
|
|
1283
|
-
* should be rendered
|
|
1284
|
-
* @param {number} end The x-offset of the end of the area that should be
|
|
1285
|
-
* rendered
|
|
1286
|
-
*/
|
|
1287
|
-
getAndDrawPeaks(wavesurfer, width, start, end) {
|
|
1288
|
-
let peaks;
|
|
1289
|
-
peaks = wavesurfer.backend.getPeaks(width, start, end);
|
|
1290
|
-
wavesurfer.drawer.drawPeaks(peaks, width, start, end);
|
|
1291
|
-
}
|
|
1292
|
-
|
|
1293
1278
|
/**
|
|
1294
1279
|
* Get the correct peaks for current wave view-port and render wave
|
|
1295
1280
|
*
|
|
@@ -1371,24 +1356,6 @@ export default class WaveSurfer extends util.Observer {
|
|
|
1371
1356
|
this.fireEvent('zoom', pxPerSec);
|
|
1372
1357
|
}
|
|
1373
1358
|
|
|
1374
|
-
/**
|
|
1375
|
-
* Call this function while moving the zoom slider to stretch the canvases
|
|
1376
|
-
* of the wave without recalculating
|
|
1377
|
-
*
|
|
1378
|
-
* @param {Number} pxPerSec value returned from the zoom slider
|
|
1379
|
-
*/
|
|
1380
|
-
zooming(pxPerSec) {
|
|
1381
|
-
//Calculate the new width, this cannot be smaller than the parent container width
|
|
1382
|
-
let desiredWidth = Math.round(this.getDuration() * pxPerSec * this.params.pixelRatio);
|
|
1383
|
-
let parentWidth = this.drawer.getWidth();
|
|
1384
|
-
desiredWidth = Math.max(parentWidth, desiredWidth);
|
|
1385
|
-
|
|
1386
|
-
//Stretch canvases
|
|
1387
|
-
this.drawer.stretchCanvases(desiredWidth, this.backend.getPlayedPercents());
|
|
1388
|
-
|
|
1389
|
-
this.fireEvent('zoom', pxPerSec);
|
|
1390
|
-
}
|
|
1391
|
-
|
|
1392
1359
|
/**
|
|
1393
1360
|
* Decode buffer and load
|
|
1394
1361
|
*
|
package/src/webaudio.js
CHANGED
|
@@ -8,16 +8,12 @@ const FINISHED = 'finished';
|
|
|
8
8
|
/**
|
|
9
9
|
* WebAudio backend
|
|
10
10
|
*
|
|
11
|
-
* @extends {Observer}
|
|
11
|
+
* @extends {util.Observer}
|
|
12
12
|
*/
|
|
13
13
|
export default class WebAudio extends util.Observer {
|
|
14
|
-
/** scriptBufferSize: size of the processing buffer */
|
|
15
|
-
static scriptBufferSize = 256;
|
|
16
14
|
/** audioContext: allows to process audio with WebAudio API */
|
|
17
15
|
audioContext = null;
|
|
18
16
|
/** @private */
|
|
19
|
-
offlineAudioContext = null;
|
|
20
|
-
/** @private */
|
|
21
17
|
stateBehaviors = {
|
|
22
18
|
[PLAYING]: {
|
|
23
19
|
init() {
|
|
@@ -33,7 +29,6 @@ export default class WebAudio extends util.Observer {
|
|
|
33
29
|
},
|
|
34
30
|
[PAUSED]: {
|
|
35
31
|
init() {
|
|
36
|
-
this.removeOnAudioProcess();
|
|
37
32
|
},
|
|
38
33
|
getPlayedPercents() {
|
|
39
34
|
const duration = this.getDuration();
|
|
@@ -45,7 +40,6 @@ export default class WebAudio extends util.Observer {
|
|
|
45
40
|
},
|
|
46
41
|
[FINISHED]: {
|
|
47
42
|
init() {
|
|
48
|
-
this.removeOnAudioProcess();
|
|
49
43
|
this.fireEvent('finish');
|
|
50
44
|
},
|
|
51
45
|
getPlayedPercents() {
|
|
@@ -233,40 +227,29 @@ export default class WebAudio extends util.Observer {
|
|
|
233
227
|
createScriptNode() {
|
|
234
228
|
if (this.params.audioScriptProcessor) {
|
|
235
229
|
this.scriptNode = this.params.audioScriptProcessor;
|
|
236
|
-
|
|
237
|
-
if (this.ac.createScriptProcessor) {
|
|
238
|
-
this.scriptNode = this.ac.createScriptProcessor(
|
|
239
|
-
WebAudio.scriptBufferSize
|
|
240
|
-
);
|
|
241
|
-
} else {
|
|
242
|
-
this.scriptNode = this.ac.createJavaScriptNode(
|
|
243
|
-
WebAudio.scriptBufferSize
|
|
244
|
-
);
|
|
245
|
-
}
|
|
230
|
+
this.scriptNode.connect(this.ac.destination);
|
|
246
231
|
}
|
|
247
|
-
this.scriptNode.connect(this.ac.destination);
|
|
248
232
|
}
|
|
249
233
|
|
|
250
234
|
/** @private */
|
|
251
235
|
addOnAudioProcess() {
|
|
252
|
-
|
|
236
|
+
const loop = () => {
|
|
253
237
|
const time = this.getCurrentTime();
|
|
254
238
|
|
|
255
|
-
if (time >= this.getDuration()) {
|
|
239
|
+
if (time >= this.getDuration() && this.state !== this.states[FINISHED]) {
|
|
256
240
|
this.setState(FINISHED);
|
|
257
241
|
this.fireEvent('pause');
|
|
258
|
-
} else if (time >= this.scheduledPause) {
|
|
242
|
+
} else if (time >= this.scheduledPause && this.state !== this.states[PAUSED]) {
|
|
259
243
|
this.pause();
|
|
260
244
|
} else if (this.state === this.states[PLAYING]) {
|
|
261
245
|
this.fireEvent('audioprocess', time);
|
|
246
|
+
util.frame(loop)();
|
|
262
247
|
}
|
|
263
248
|
};
|
|
264
|
-
}
|
|
265
249
|
|
|
266
|
-
|
|
267
|
-
removeOnAudioProcess() {
|
|
268
|
-
this.scriptNode.onaudioprocess = null;
|
|
250
|
+
loop();
|
|
269
251
|
}
|
|
252
|
+
|
|
270
253
|
/** Create analyser node to perform audio analysis */
|
|
271
254
|
createAnalyserNode() {
|
|
272
255
|
this.analyser = this.ac.createAnalyser();
|
|
@@ -526,7 +509,7 @@ export default class WebAudio extends util.Observer {
|
|
|
526
509
|
this.disconnectFilters();
|
|
527
510
|
this.disconnectSource();
|
|
528
511
|
this.gainNode.disconnect();
|
|
529
|
-
this.scriptNode.disconnect();
|
|
512
|
+
this.scriptNode && this.scriptNode.disconnect();
|
|
530
513
|
this.analyser.disconnect();
|
|
531
514
|
|
|
532
515
|
// close the audioContext if closeAudioContext option is set to true
|