wavesurfer.js 6.5.1 → 7.0.0-alpha.1

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.
Files changed (132) hide show
  1. package/.eslintrc.json +24 -0
  2. package/.prettierrc +8 -0
  3. package/README.md +26 -117
  4. package/dist/base-plugin.d.ts +10 -0
  5. package/dist/base-plugin.js +13 -0
  6. package/dist/decoder.d.ts +10 -0
  7. package/dist/decoder.js +43 -0
  8. package/dist/event-emitter.d.ts +11 -0
  9. package/dist/event-emitter.js +21 -0
  10. package/dist/fetcher.d.ts +4 -0
  11. package/dist/fetcher.js +17 -0
  12. package/dist/index.d.ts +92 -0
  13. package/dist/index.js +166 -0
  14. package/dist/player-webaudio.d.ts +8 -0
  15. package/dist/player-webaudio.js +31 -0
  16. package/dist/player.d.ts +16 -0
  17. package/dist/player.js +40 -0
  18. package/dist/plugins/regions.d.ts +48 -0
  19. package/dist/plugins/regions.js +183 -0
  20. package/dist/renderer.d.ts +34 -0
  21. package/dist/renderer.js +193 -0
  22. package/dist/timer.d.ts +10 -0
  23. package/dist/timer.js +17 -0
  24. package/examples/audio.ogg +0 -0
  25. package/examples/bars.js +19 -0
  26. package/examples/basic.js +8 -0
  27. package/examples/gradient.js +28 -0
  28. package/examples/regions.js +63 -0
  29. package/examples/video.js +19 -0
  30. package/examples/webaudio.js +14 -0
  31. package/package.json +19 -99
  32. package/src/base-plugin.ts +20 -0
  33. package/src/decoder.ts +41 -0
  34. package/src/event-emitter.ts +35 -0
  35. package/src/fetcher.ts +7 -0
  36. package/src/index.ts +252 -0
  37. package/src/player-webaudio.ts +34 -0
  38. package/src/player.ts +50 -0
  39. package/src/plugins/regions.ts +240 -0
  40. package/src/renderer.ts +250 -0
  41. package/src/timer.ts +27 -0
  42. package/tsconfig.json +105 -0
  43. package/tutorial/index.html +47 -0
  44. package/tutorial/src/editor.js +70 -0
  45. package/tutorial/src/init.js +66 -0
  46. package/tutorial/src/url.js +25 -0
  47. package/tutorial/style.css +211 -0
  48. package/yarn-error.log +1049 -0
  49. package/LICENSE +0 -29
  50. package/dist/plugin/wavesurfer.cursor.js +0 -418
  51. package/dist/plugin/wavesurfer.cursor.js.map +0 -1
  52. package/dist/plugin/wavesurfer.cursor.min.js +0 -7
  53. package/dist/plugin/wavesurfer.cursor.min.js.map +0 -1
  54. package/dist/plugin/wavesurfer.elan.js +0 -381
  55. package/dist/plugin/wavesurfer.elan.js.map +0 -1
  56. package/dist/plugin/wavesurfer.elan.min.js +0 -7
  57. package/dist/plugin/wavesurfer.elan.min.js.map +0 -1
  58. package/dist/plugin/wavesurfer.markers.js +0 -520
  59. package/dist/plugin/wavesurfer.markers.js.map +0 -1
  60. package/dist/plugin/wavesurfer.markers.min.js +0 -7
  61. package/dist/plugin/wavesurfer.markers.min.js.map +0 -1
  62. package/dist/plugin/wavesurfer.mediasession.js +0 -181
  63. package/dist/plugin/wavesurfer.mediasession.js.map +0 -1
  64. package/dist/plugin/wavesurfer.mediasession.min.js +0 -7
  65. package/dist/plugin/wavesurfer.mediasession.min.js.map +0 -1
  66. package/dist/plugin/wavesurfer.microphone.js +0 -466
  67. package/dist/plugin/wavesurfer.microphone.js.map +0 -1
  68. package/dist/plugin/wavesurfer.microphone.min.js +0 -7
  69. package/dist/plugin/wavesurfer.microphone.min.js.map +0 -1
  70. package/dist/plugin/wavesurfer.minimap.js +0 -440
  71. package/dist/plugin/wavesurfer.minimap.js.map +0 -1
  72. package/dist/plugin/wavesurfer.minimap.min.js +0 -7
  73. package/dist/plugin/wavesurfer.minimap.min.js.map +0 -1
  74. package/dist/plugin/wavesurfer.playhead.js +0 -300
  75. package/dist/plugin/wavesurfer.playhead.js.map +0 -1
  76. package/dist/plugin/wavesurfer.playhead.min.js +0 -7
  77. package/dist/plugin/wavesurfer.playhead.min.js.map +0 -1
  78. package/dist/plugin/wavesurfer.regions.js +0 -1335
  79. package/dist/plugin/wavesurfer.regions.js.map +0 -1
  80. package/dist/plugin/wavesurfer.regions.min.js +0 -7
  81. package/dist/plugin/wavesurfer.regions.min.js.map +0 -1
  82. package/dist/plugin/wavesurfer.spectrogram.js +0 -736
  83. package/dist/plugin/wavesurfer.spectrogram.js.map +0 -1
  84. package/dist/plugin/wavesurfer.spectrogram.min.js +0 -7
  85. package/dist/plugin/wavesurfer.spectrogram.min.js.map +0 -1
  86. package/dist/plugin/wavesurfer.timeline.js +0 -649
  87. package/dist/plugin/wavesurfer.timeline.js.map +0 -1
  88. package/dist/plugin/wavesurfer.timeline.min.js +0 -7
  89. package/dist/plugin/wavesurfer.timeline.min.js.map +0 -1
  90. package/dist/wavesurfer-html-init.js +0 -381
  91. package/dist/wavesurfer-html-init.js.map +0 -1
  92. package/dist/wavesurfer-html-init.min.js +0 -7
  93. package/dist/wavesurfer-html-init.min.js.map +0 -1
  94. package/dist/wavesurfer.js +0 -6145
  95. package/dist/wavesurfer.js.map +0 -1
  96. package/dist/wavesurfer.min.js +0 -7
  97. package/dist/wavesurfer.min.js.map +0 -1
  98. package/src/drawer.canvasentry.js +0 -427
  99. package/src/drawer.js +0 -413
  100. package/src/drawer.multicanvas.js +0 -617
  101. package/src/html-init.js +0 -241
  102. package/src/mediaelement-webaudio.js +0 -77
  103. package/src/mediaelement.js +0 -443
  104. package/src/peakcache.js +0 -127
  105. package/src/plugin/cursor/index.js +0 -350
  106. package/src/plugin/elan/index.js +0 -307
  107. package/src/plugin/markers/index.js +0 -436
  108. package/src/plugin/mediasession/index.js +0 -94
  109. package/src/plugin/microphone/index.js +0 -415
  110. package/src/plugin/minimap/index.js +0 -403
  111. package/src/plugin/playhead/index.js +0 -226
  112. package/src/plugin/regions/index.js +0 -478
  113. package/src/plugin/regions/region.js +0 -875
  114. package/src/plugin/spectrogram/fft.js +0 -222
  115. package/src/plugin/spectrogram/index.js +0 -522
  116. package/src/plugin/timeline/index.js +0 -600
  117. package/src/util/absMax.js +0 -16
  118. package/src/util/clamp.js +0 -11
  119. package/src/util/fetch.js +0 -222
  120. package/src/util/frame.js +0 -13
  121. package/src/util/get-id.js +0 -22
  122. package/src/util/index.js +0 -14
  123. package/src/util/max.js +0 -16
  124. package/src/util/min.js +0 -16
  125. package/src/util/observer.js +0 -144
  126. package/src/util/orientation.js +0 -98
  127. package/src/util/prevent-click.js +0 -19
  128. package/src/util/request-animation-frame.js +0 -15
  129. package/src/util/silence-mode.js +0 -42
  130. package/src/util/style.js +0 -16
  131. package/src/wavesurfer.js +0 -1797
  132. package/src/webaudio.js +0 -779
@@ -1,522 +0,0 @@
1
- /* eslint-enable complexity, no-redeclare, no-var, one-var */
2
-
3
- import FFT from './fft';
4
-
5
- /**
6
- * @typedef {Object} SpectrogramPluginParams
7
- * @property {string|HTMLElement} container Selector of element or element in
8
- * which to render
9
- * @property {number} fftSamples=512 Number of samples to fetch to FFT. Must be
10
- * a power of 2.
11
- * @property {boolean} splitChannels=false Render with separate spectrograms for
12
- * the channels of the audio
13
- * @property {number} height=fftSamples/2 Height of the spectrogram view in CSS
14
- * pixels
15
- * @property {boolean} labels Set to true to display frequency labels.
16
- * @property {number} noverlap Size of the overlapping window. Must be <
17
- * fftSamples. Auto deduced from canvas size by default.
18
- * @property {string} windowFunc='hann' The window function to be used. One of
19
- * these: `'bartlett'`, `'bartlettHann'`, `'blackman'`, `'cosine'`, `'gauss'`,
20
- * `'hamming'`, `'hann'`, `'lanczoz'`, `'rectangular'`, `'triangular'`
21
- * @property {?number} alpha Some window functions have this extra value.
22
- * (Between 0 and 1)
23
- * @property {number} pixelRatio=wavesurfer.params.pixelRatio to control the
24
- * size of the spectrogram in relation with its canvas. 1 = Draw on the whole
25
- * canvas. 2 = Draw on a quarter (1/2 the length and 1/2 the width)
26
- * @property {number} frequencyMin=0 Min frequency to scale spectrogram.
27
- * @property {number} frequencyMax=12000 Max frequency to scale spectrogram.
28
- * Set this to samplerate/2 to draw whole range of spectrogram.
29
- * @property {?boolean} deferInit Set to true to manually call
30
- * `initPlugin('spectrogram')`
31
- * @property {?number[][]} colorMap A 256 long array of 4-element arrays.
32
- * Each entry should contain a float between 0 and 1 and specify
33
- * r, g, b, and alpha.
34
- */
35
-
36
- /**
37
- * Render a spectrogram visualisation of the audio.
38
- *
39
- * @implements {PluginClass}
40
- * @extends {Observer}
41
- * @example
42
- * // es6
43
- * import SpectrogramPlugin from 'wavesurfer.spectrogram.js';
44
- *
45
- * // commonjs
46
- * var SpectrogramPlugin = require('wavesurfer.spectrogram.js');
47
- *
48
- * // if you are using <script> tags
49
- * var SpectrogramPlugin = window.WaveSurfer.spectrogram;
50
- *
51
- * // ... initialising wavesurfer with the plugin
52
- * var wavesurfer = WaveSurfer.create({
53
- * // wavesurfer options ...
54
- * plugins: [
55
- * SpectrogramPlugin.create({
56
- * // plugin options ...
57
- * })
58
- * ]
59
- * });
60
- */
61
- export default class SpectrogramPlugin {
62
- /**
63
- * Spectrogram plugin definition factory
64
- *
65
- * This function must be used to create a plugin definition which can be
66
- * used by wavesurfer to correctly instantiate the plugin.
67
- *
68
- * @param {SpectrogramPluginParams} params Parameters used to initialise the plugin
69
- * @return {PluginDefinition} An object representing the plugin.
70
- */
71
- static create(params) {
72
- return {
73
- name: 'spectrogram',
74
- deferInit: params && params.deferInit ? params.deferInit : false,
75
- params: params,
76
- staticProps: {
77
- FFT: FFT
78
- },
79
- instance: SpectrogramPlugin
80
- };
81
- }
82
-
83
- constructor(params, ws) {
84
- this.params = params;
85
- this.wavesurfer = ws;
86
- this.util = ws.util;
87
-
88
- this.frequenciesDataUrl = params.frequenciesDataUrl;
89
- this._onScroll = e => {
90
- this.updateScroll(e);
91
- };
92
- this._onRender = () => {
93
- this.render();
94
- };
95
- this._onWrapperClick = e => {
96
- this._wrapperClickHandler(e);
97
- };
98
- this._onReady = () => {
99
- const drawer = (this.drawer = ws.drawer);
100
-
101
- this.container =
102
- 'string' == typeof params.container
103
- ? document.querySelector(params.container)
104
- : params.container;
105
-
106
- if (!this.container) {
107
- throw Error('No container for WaveSurfer spectrogram');
108
- }
109
- if (params.colorMap) {
110
- if (params.colorMap.length < 256) {
111
- throw new Error('Colormap must contain 256 elements');
112
- }
113
- for (let i = 0; i < params.colorMap.length; i++) {
114
- const cmEntry = params.colorMap[i];
115
- if (cmEntry.length !== 4) {
116
- throw new Error(
117
- 'ColorMap entries must contain 4 values'
118
- );
119
- }
120
- }
121
- this.colorMap = params.colorMap;
122
- } else {
123
- this.colorMap = [];
124
- for (let i = 0; i < 256; i++) {
125
- const val = (255 - i) / 256;
126
- this.colorMap.push([val, val, val, 1]);
127
- }
128
- }
129
- this.width = drawer.width;
130
- this.pixelRatio = this.params.pixelRatio || ws.params.pixelRatio;
131
- this.fftSamples =
132
- this.params.fftSamples || ws.params.fftSamples || 512;
133
- this.height = this.params.height || this.fftSamples / 2;
134
- this.noverlap = params.noverlap;
135
- this.windowFunc = params.windowFunc;
136
- this.alpha = params.alpha;
137
- this.splitChannels = params.splitChannels;
138
- this.channels = this.splitChannels ? ws.backend.buffer.numberOfChannels : 1;
139
-
140
- // Getting file's original samplerate is difficult(#1248).
141
- // So set 12kHz default to render like wavesurfer.js 5.x.
142
- this.frequencyMin = params.frequencyMin || 0;
143
- this.frequencyMax = params.frequencyMax || 12000;
144
-
145
- this.createWrapper();
146
- this.createCanvas();
147
- this.render();
148
-
149
- drawer.wrapper.addEventListener('scroll', this._onScroll);
150
- ws.on('redraw', this._onRender);
151
- };
152
- }
153
-
154
- init() {
155
- // Check if wavesurfer is ready
156
- if (this.wavesurfer.isReady) {
157
- this._onReady();
158
- } else {
159
- this.wavesurfer.once('ready', this._onReady);
160
- }
161
- }
162
-
163
- destroy() {
164
- this.unAll();
165
- this.wavesurfer.un('ready', this._onReady);
166
- this.wavesurfer.un('redraw', this._onRender);
167
- this.drawer && this.drawer.wrapper.removeEventListener('scroll', this._onScroll);
168
- this.wavesurfer = null;
169
- this.util = null;
170
- this.params = null;
171
- if (this.wrapper) {
172
- this.wrapper.removeEventListener('click', this._onWrapperClick);
173
- this.wrapper.parentNode.removeChild(this.wrapper);
174
- this.wrapper = null;
175
- }
176
- }
177
-
178
- createWrapper() {
179
- const prevSpectrogram = this.container.querySelector('spectrogram');
180
- if (prevSpectrogram) {
181
- this.container.removeChild(prevSpectrogram);
182
- }
183
- const wsParams = this.wavesurfer.params;
184
- this.wrapper = document.createElement('spectrogram');
185
- // if labels are active
186
- if (this.params.labels) {
187
- const labelsEl = (this.labelsEl = document.createElement('canvas'));
188
- labelsEl.classList.add('spec-labels');
189
- this.drawer.style(labelsEl, {
190
- position: 'absolute',
191
- zIndex: 9,
192
- height: `${this.height * this.channels}px`,
193
- width: `55px`
194
- });
195
- this.wrapper.appendChild(labelsEl);
196
- this.loadLabels(
197
- 'rgba(68,68,68,0.5)',
198
- '12px',
199
- '10px',
200
- '',
201
- '#fff',
202
- '#f7f7f7',
203
- 'center',
204
- '#specLabels'
205
- );
206
- }
207
-
208
- this.drawer.style(this.wrapper, {
209
- display: 'block',
210
- position: 'relative',
211
- userSelect: 'none',
212
- webkitUserSelect: 'none',
213
- height: `${this.height * this.channels}px`
214
- });
215
-
216
- if (wsParams.fillParent || wsParams.scrollParent) {
217
- this.drawer.style(this.wrapper, {
218
- width: '100%',
219
- overflowX: 'hidden',
220
- overflowY: 'hidden'
221
- });
222
- }
223
- this.container.appendChild(this.wrapper);
224
-
225
- this.wrapper.addEventListener('click', this._onWrapperClick);
226
- }
227
-
228
- _wrapperClickHandler(event) {
229
- event.preventDefault();
230
- const relX = 'offsetX' in event ? event.offsetX : event.layerX;
231
- this.fireEvent('click', relX / this.width || 0);
232
- }
233
-
234
- createCanvas() {
235
- const canvas = (this.canvas = this.wrapper.appendChild(
236
- document.createElement('canvas')
237
- ));
238
-
239
- this.spectrCc = canvas.getContext('2d');
240
-
241
- this.util.style(canvas, {
242
- position: 'absolute',
243
- zIndex: 4
244
- });
245
- }
246
-
247
- render() {
248
- this.updateCanvasStyle();
249
-
250
- if (this.frequenciesDataUrl) {
251
- this.loadFrequenciesData(this.frequenciesDataUrl);
252
- } else {
253
- this.getFrequencies(this.drawSpectrogram);
254
- }
255
- }
256
-
257
- updateCanvasStyle() {
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';
263
- }
264
-
265
- drawSpectrogram(frequenciesData, my) {
266
- if (!isNaN(frequenciesData[0][0])) { // data is 1ch [sample, freq] format
267
- // to [channel, sample, freq] format
268
- frequenciesData = [frequenciesData];
269
- }
270
-
271
- const spectrCc = my.spectrCc;
272
- const height = my.fftSamples / 2;
273
- const width = my.width;
274
- const freqFrom = my.buffer.sampleRate / 2;
275
- const freqMin = my.frequencyMin;
276
- const freqMax = my.frequencyMax;
277
-
278
- if (!spectrCc) {
279
- return;
280
- }
281
-
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);
285
-
286
- for (let i = 0; i < pixels.length; i++) {
287
- for (let j = 0; j < pixels[i].length; j++) {
288
- const colorMap = my.colorMap[pixels[i][j]];
289
- const redIndex = ((height - j) * width + i) * 4;
290
- imageData.data[redIndex] = colorMap[0] * 255;
291
- imageData.data[redIndex + 1] = colorMap[1] * 255;
292
- imageData.data[redIndex + 2] = colorMap[2] * 255;
293
- imageData.data[redIndex + 3] = colorMap[3] * 255;
294
- }
295
- }
296
-
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
- );
306
- }
307
- }
308
-
309
- getFrequencies(callback) {
310
- const fftSamples = this.fftSamples;
311
- const buffer = (this.buffer = this.wavesurfer.backend.buffer);
312
- const channels = this.channels;
313
-
314
- if (!buffer) {
315
- this.fireEvent('error', 'Web Audio buffer is not available');
316
- return;
317
- }
318
-
319
- // This may differ from file samplerate. Browser resamples audio.
320
- const sampleRate = buffer.sampleRate;
321
- const frequencies = [];
322
-
323
- let noverlap = this.noverlap;
324
- if (!noverlap) {
325
- const uniqueSamplesPerPx = buffer.length / this.canvas.width;
326
- noverlap = Math.max(0, Math.round(fftSamples - uniqueSamplesPerPx));
327
- }
328
-
329
- const fft = new FFT(
330
- fftSamples,
331
- sampleRate,
332
- this.windowFunc,
333
- this.alpha
334
- );
335
-
336
- for (let c = 0; c < channels; c++) { // for each channel
337
- const channelData = buffer.getChannelData(c);
338
- const channelFreq = [];
339
- let currentOffset = 0;
340
-
341
- while (currentOffset + fftSamples < channelData.length) {
342
- const segment = channelData.slice(
343
- currentOffset,
344
- currentOffset + fftSamples
345
- );
346
- const spectrum = fft.calculateSpectrum(segment);
347
- const array = new Uint8Array(fftSamples / 2);
348
- let j;
349
- for (j = 0; j < fftSamples / 2; j++) {
350
- array[j] = Math.max(-255, Math.log10(spectrum[j]) * 45);
351
- }
352
- channelFreq.push(array);
353
- // channelFreq: [sample, freq]
354
-
355
- currentOffset += fftSamples - noverlap;
356
- }
357
- frequencies.push(channelFreq);
358
- // frequencies: [channel, sample, freq]
359
- }
360
- callback(frequencies, this);
361
- }
362
-
363
- loadFrequenciesData(url) {
364
- const request = this.util.fetchFile({ url: url });
365
-
366
- request.on('success', data =>
367
- this.drawSpectrogram(JSON.parse(data), this)
368
- );
369
- request.on('error', e => this.fireEvent('error', e));
370
-
371
- return request;
372
- }
373
-
374
- freqType(freq) {
375
- return freq >= 1000 ? (freq / 1000).toFixed(1) : Math.round(freq);
376
- }
377
-
378
- unitType(freq) {
379
- return freq >= 1000 ? 'KHz' : 'Hz';
380
- }
381
-
382
- loadLabels(
383
- bgFill,
384
- fontSizeFreq,
385
- fontSizeUnit,
386
- fontType,
387
- textColorFreq,
388
- textColorUnit,
389
- textAlign,
390
- container
391
- ) {
392
- const frequenciesHeight = this.height;
393
- bgFill = bgFill || 'rgba(68,68,68,0)';
394
- fontSizeFreq = fontSizeFreq || '12px';
395
- fontSizeUnit = fontSizeUnit || '10px';
396
- fontType = fontType || 'Helvetica';
397
- textColorFreq = textColorFreq || '#fff';
398
- textColorUnit = textColorUnit || '#fff';
399
- textAlign = textAlign || 'center';
400
- container = container || '#specLabels';
401
- const bgWidth = 55;
402
- const getMaxY = frequenciesHeight || 512;
403
- const labelIndex = 5 * (getMaxY / 256);
404
- const freqStart = this.frequencyMin;
405
- const step = (this.frequencyMax - freqStart) / labelIndex;
406
-
407
- // prepare canvas element for labels
408
- const ctx = this.labelsEl.getContext('2d');
409
- const dispScale = window.devicePixelRatio;
410
- this.labelsEl.height = this.height * this.channels * dispScale;
411
- this.labelsEl.width = bgWidth * dispScale;
412
- ctx.scale(dispScale, dispScale);
413
-
414
- if (!ctx) {
415
- return;
416
- }
417
-
418
- for (let c = 0; c < this.channels; c++) { // for each channel
419
- // fill background
420
- ctx.fillStyle = bgFill;
421
- ctx.fillRect(0, c * getMaxY, bgWidth, (1 + c) * getMaxY);
422
- ctx.fill();
423
- let i;
424
-
425
- // render labels
426
- for (i = 0; i <= labelIndex; i++) {
427
- ctx.textAlign = textAlign;
428
- ctx.textBaseline = 'middle';
429
-
430
- const freq = freqStart + step * i;
431
- const label = this.freqType(freq);
432
- const units = this.unitType(freq);
433
- const yLabelOffset = 2;
434
- const x = 16;
435
- let y;
436
-
437
- if (i == 0) {
438
- y = (1 + c) * getMaxY + i - 10;
439
- // unit label
440
- ctx.fillStyle = textColorUnit;
441
- ctx.font = fontSizeUnit + ' ' + fontType;
442
- ctx.fillText(units, x + 24, y);
443
- // freq label
444
- ctx.fillStyle = textColorFreq;
445
- ctx.font = fontSizeFreq + ' ' + fontType;
446
- ctx.fillText(label, x, y);
447
- } else {
448
- y = (1 + c) * getMaxY - i * 50 + yLabelOffset;
449
- // unit label
450
- ctx.fillStyle = textColorUnit;
451
- ctx.font = fontSizeUnit + ' ' + fontType;
452
- ctx.fillText(units, x + 24, y);
453
- // freq label
454
- ctx.fillStyle = textColorFreq;
455
- ctx.font = fontSizeFreq + ' ' + fontType;
456
- ctx.fillText(label, x, y);
457
- }
458
- }
459
- }
460
- }
461
-
462
- updateScroll(e) {
463
- if (this.wrapper) {
464
- this.wrapper.scrollLeft = e.target.scrollLeft;
465
- }
466
- }
467
-
468
- resample(oldMatrix) {
469
- const columnsNumber = this.width;
470
- const newMatrix = [];
471
-
472
- const oldPiece = 1 / oldMatrix.length;
473
- const newPiece = 1 / columnsNumber;
474
- let i;
475
-
476
- for (i = 0; i < columnsNumber; i++) {
477
- const column = new Array(oldMatrix[0].length);
478
- let j;
479
-
480
- for (j = 0; j < oldMatrix.length; j++) {
481
- const oldStart = j * oldPiece;
482
- const oldEnd = oldStart + oldPiece;
483
- const newStart = i * newPiece;
484
- const newEnd = newStart + newPiece;
485
-
486
- const overlap =
487
- oldEnd <= newStart || newEnd <= oldStart
488
- ? 0
489
- : Math.min(
490
- Math.max(oldEnd, newStart),
491
- Math.max(newEnd, oldStart)
492
- ) -
493
- Math.max(
494
- Math.min(oldEnd, newStart),
495
- Math.min(newEnd, oldStart)
496
- );
497
- let k;
498
- /* eslint-disable max-depth */
499
- if (overlap > 0) {
500
- for (k = 0; k < oldMatrix[0].length; k++) {
501
- if (column[k] == null) {
502
- column[k] = 0;
503
- }
504
- column[k] += (overlap / newPiece) * oldMatrix[j][k];
505
- }
506
- }
507
- /* eslint-enable max-depth */
508
- }
509
-
510
- const intColumn = new Uint8Array(oldMatrix[0].length);
511
- let m;
512
-
513
- for (m = 0; m < oldMatrix[0].length; m++) {
514
- intColumn[m] = column[m];
515
- }
516
-
517
- newMatrix.push(intColumn);
518
- }
519
-
520
- return newMatrix;
521
- }
522
- }