wavesurfer.js
Version:
Interactive navigable audio visualization using Web Audio and Canvas
736 lines (716 loc) • 27.3 kB
JavaScript
/*!
* wavesurfer.js spectrogram plugin 6.6.3 (2023-04-04)
* https://wavesurfer-js.org
* @license BSD-3-Clause
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("WaveSurfer", [], factory);
else if(typeof exports === 'object')
exports["WaveSurfer"] = factory();
else
root["WaveSurfer"] = root["WaveSurfer"] || {}, root["WaveSurfer"]["spectrogram"] = factory();
})(self, () => {
return /******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/plugin/spectrogram/fft.js":
/*!***************************************!*\
!*** ./src/plugin/spectrogram/fft.js ***!
\***************************************/
/***/ ((module, exports) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = FFT;
/* eslint-disable complexity, no-redeclare, no-var, one-var */
/**
* Calculate FFT - Based on https://github.com/corbanbrook/dsp.js
*
* @param {Number} bufferSize Buffer size
* @param {Number} sampleRate Sample rate
* @param {Function} windowFunc Window function
* @param {Number} alpha Alpha channel
*/
function FFT(bufferSize, sampleRate, windowFunc, alpha) {
this.bufferSize = bufferSize;
this.sampleRate = sampleRate;
this.bandwidth = 2 / bufferSize * (sampleRate / 2);
this.sinTable = new Float32Array(bufferSize);
this.cosTable = new Float32Array(bufferSize);
this.windowValues = new Float32Array(bufferSize);
this.reverseTable = new Uint32Array(bufferSize);
this.peakBand = 0;
this.peak = 0;
var i;
switch (windowFunc) {
case 'bartlett':
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = 2 / (bufferSize - 1) * ((bufferSize - 1) / 2 - Math.abs(i - (bufferSize - 1) / 2));
}
break;
case 'bartlettHann':
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = 0.62 - 0.48 * Math.abs(i / (bufferSize - 1) - 0.5) - 0.38 * Math.cos(Math.PI * 2 * i / (bufferSize - 1));
}
break;
case 'blackman':
alpha = alpha || 0.16;
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = (1 - alpha) / 2 - 0.5 * Math.cos(Math.PI * 2 * i / (bufferSize - 1)) + alpha / 2 * Math.cos(4 * Math.PI * i / (bufferSize - 1));
}
break;
case 'cosine':
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = Math.cos(Math.PI * i / (bufferSize - 1) - Math.PI / 2);
}
break;
case 'gauss':
alpha = alpha || 0.25;
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = Math.pow(Math.E, -0.5 * Math.pow((i - (bufferSize - 1) / 2) / (alpha * (bufferSize - 1) / 2), 2));
}
break;
case 'hamming':
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = 0.54 - 0.46 * Math.cos(Math.PI * 2 * i / (bufferSize - 1));
}
break;
case 'hann':
case undefined:
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = 0.5 * (1 - Math.cos(Math.PI * 2 * i / (bufferSize - 1)));
}
break;
case 'lanczoz':
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = Math.sin(Math.PI * (2 * i / (bufferSize - 1) - 1)) / (Math.PI * (2 * i / (bufferSize - 1) - 1));
}
break;
case 'rectangular':
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = 1;
}
break;
case 'triangular':
for (i = 0; i < bufferSize; i++) {
this.windowValues[i] = 2 / bufferSize * (bufferSize / 2 - Math.abs(i - (bufferSize - 1) / 2));
}
break;
default:
throw Error("No such window function '" + windowFunc + "'");
}
var limit = 1;
var bit = bufferSize >> 1;
var i;
while (limit < bufferSize) {
for (i = 0; i < limit; i++) {
this.reverseTable[i + limit] = this.reverseTable[i] + bit;
}
limit = limit << 1;
bit = bit >> 1;
}
for (i = 0; i < bufferSize; i++) {
this.sinTable[i] = Math.sin(-Math.PI / i);
this.cosTable[i] = Math.cos(-Math.PI / i);
}
this.calculateSpectrum = function (buffer) {
// Locally scope variables for speed up
var bufferSize = this.bufferSize,
cosTable = this.cosTable,
sinTable = this.sinTable,
reverseTable = this.reverseTable,
real = new Float32Array(bufferSize),
imag = new Float32Array(bufferSize),
bSi = 2 / this.bufferSize,
sqrt = Math.sqrt,
rval,
ival,
mag,
spectrum = new Float32Array(bufferSize / 2);
var k = Math.floor(Math.log(bufferSize) / Math.LN2);
if (Math.pow(2, k) !== bufferSize) {
throw 'Invalid buffer size, must be a power of 2.';
}
if (bufferSize !== buffer.length) {
throw 'Supplied buffer is not the same size as defined FFT. FFT Size: ' + bufferSize + ' Buffer Size: ' + buffer.length;
}
var halfSize = 1,
phaseShiftStepReal,
phaseShiftStepImag,
currentPhaseShiftReal,
currentPhaseShiftImag,
off,
tr,
ti,
tmpReal;
for (var i = 0; i < bufferSize; i++) {
real[i] = buffer[reverseTable[i]] * this.windowValues[reverseTable[i]];
imag[i] = 0;
}
while (halfSize < bufferSize) {
phaseShiftStepReal = cosTable[halfSize];
phaseShiftStepImag = sinTable[halfSize];
currentPhaseShiftReal = 1;
currentPhaseShiftImag = 0;
for (var fftStep = 0; fftStep < halfSize; fftStep++) {
var i = fftStep;
while (i < bufferSize) {
off = i + halfSize;
tr = currentPhaseShiftReal * real[off] - currentPhaseShiftImag * imag[off];
ti = currentPhaseShiftReal * imag[off] + currentPhaseShiftImag * real[off];
real[off] = real[i] - tr;
imag[off] = imag[i] - ti;
real[i] += tr;
imag[i] += ti;
i += halfSize << 1;
}
tmpReal = currentPhaseShiftReal;
currentPhaseShiftReal = tmpReal * phaseShiftStepReal - currentPhaseShiftImag * phaseShiftStepImag;
currentPhaseShiftImag = tmpReal * phaseShiftStepImag + currentPhaseShiftImag * phaseShiftStepReal;
}
halfSize = halfSize << 1;
}
for (var i = 0, N = bufferSize / 2; i < N; i++) {
rval = real[i];
ival = imag[i];
mag = bSi * sqrt(rval * rval + ival * ival);
if (mag > this.peak) {
this.peakBand = i;
this.peak = mag;
}
spectrum[i] = mag;
}
return spectrum;
};
}
module.exports = exports.default;
/***/ }),
/***/ "./src/plugin/spectrogram/index.js":
/*!*****************************************!*\
!*** ./src/plugin/spectrogram/index.js ***!
\*****************************************/
/***/ ((module, exports, __webpack_require__) => {
Object.defineProperty(exports, "__esModule", ({
value: true
}));
exports["default"] = void 0;
var _fft = _interopRequireDefault(__webpack_require__(/*! ./fft */ "./src/plugin/spectrogram/fft.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
/**
* @typedef {Object} SpectrogramPluginParams
* @property {string|HTMLElement} container Selector of element or element in
* which to render
* @property {number} fftSamples=512 Number of samples to fetch to FFT. Must be
* a power of 2.
* @property {boolean} splitChannels=false Render with separate spectrograms for
* the channels of the audio
* @property {number} height=fftSamples/2 Height of the spectrogram view in CSS
* pixels
* @property {boolean} labels Set to true to display frequency labels.
* @property {number} noverlap Size of the overlapping window. Must be <
* fftSamples. Auto deduced from canvas size by default.
* @property {string} windowFunc='hann' The window function to be used. One of
* these: `'bartlett'`, `'bartlettHann'`, `'blackman'`, `'cosine'`, `'gauss'`,
* `'hamming'`, `'hann'`, `'lanczoz'`, `'rectangular'`, `'triangular'`
* @property {?number} alpha Some window functions have this extra value.
* (Between 0 and 1)
* @property {number} pixelRatio=wavesurfer.params.pixelRatio to control the
* size of the spectrogram in relation with its canvas. 1 = Draw on the whole
* canvas. 2 = Draw on a quarter (1/2 the length and 1/2 the width)
* @property {number} frequencyMin=0 Min frequency to scale spectrogram.
* @property {number} frequencyMax=12000 Max frequency to scale spectrogram.
* Set this to samplerate/2 to draw whole range of spectrogram.
* @property {?boolean} deferInit Set to true to manually call
* `initPlugin('spectrogram')`
* @property {?number[][]} colorMap A 256 long array of 4-element arrays.
* Each entry should contain a float between 0 and 1 and specify
* r, g, b, and alpha.
*/
/**
* Render a spectrogram visualisation of the audio.
*
* @implements {PluginClass}
* @extends {Observer}
* @example
* // es6
* import SpectrogramPlugin from 'wavesurfer.spectrogram.js';
*
* // commonjs
* var SpectrogramPlugin = require('wavesurfer.spectrogram.js');
*
* // if you are using <script> tags
* var SpectrogramPlugin = window.WaveSurfer.spectrogram;
*
* // ... initialising wavesurfer with the plugin
* var wavesurfer = WaveSurfer.create({
* // wavesurfer options ...
* plugins: [
* SpectrogramPlugin.create({
* // plugin options ...
* })
* ]
* });
*/
var SpectrogramPlugin = /*#__PURE__*/function () {
function SpectrogramPlugin(params, ws) {
var _this = this;
_classCallCheck(this, SpectrogramPlugin);
this.params = params;
this.wavesurfer = ws;
this.util = ws.util;
this.frequenciesDataUrl = params.frequenciesDataUrl;
this._onScroll = function (e) {
_this.updateScroll(e);
};
this._onRender = function () {
_this.render();
};
this._onWrapperClick = function (e) {
_this._wrapperClickHandler(e);
};
this._onReady = function () {
var drawer = _this.drawer = ws.drawer;
_this.container = 'string' == typeof params.container ? document.querySelector(params.container) : params.container;
if (!_this.container) {
throw Error('No container for WaveSurfer spectrogram');
}
if (params.colorMap) {
if (params.colorMap.length < 256) {
throw new Error('Colormap must contain 256 elements');
}
for (var i = 0; i < params.colorMap.length; i++) {
var cmEntry = params.colorMap[i];
if (cmEntry.length !== 4) {
throw new Error('ColorMap entries must contain 4 values');
}
}
_this.colorMap = params.colorMap;
} else {
_this.colorMap = [];
for (var _i = 0; _i < 256; _i++) {
var val = (255 - _i) / 256;
_this.colorMap.push([val, val, val, 1]);
}
}
_this.width = drawer.width;
_this.pixelRatio = _this.params.pixelRatio || ws.params.pixelRatio;
_this.fftSamples = _this.params.fftSamples || ws.params.fftSamples || 512;
_this.height = _this.params.height || _this.fftSamples / 2;
_this.noverlap = params.noverlap;
_this.windowFunc = params.windowFunc;
_this.alpha = params.alpha;
_this.splitChannels = params.splitChannels;
_this.channels = _this.splitChannels ? ws.backend.buffer.numberOfChannels : 1;
// Getting file's original samplerate is difficult(#1248).
// So set 12kHz default to render like wavesurfer.js 5.x.
_this.frequencyMin = params.frequencyMin || 0;
_this.frequencyMax = params.frequencyMax || 12000;
_this.createWrapper();
_this.createCanvas();
_this.render();
drawer.wrapper.addEventListener('scroll', _this._onScroll);
ws.on('redraw', _this._onRender);
};
}
_createClass(SpectrogramPlugin, [{
key: "init",
value: function init() {
// Check if wavesurfer is ready
if (this.wavesurfer.isReady) {
this._onReady();
} else {
this.wavesurfer.once('ready', this._onReady);
}
}
}, {
key: "destroy",
value: function destroy() {
this.unAll();
this.wavesurfer.un('ready', this._onReady);
this.wavesurfer.un('redraw', this._onRender);
this.drawer && this.drawer.wrapper.removeEventListener('scroll', this._onScroll);
this.wavesurfer = null;
this.util = null;
this.params = null;
if (this.wrapper) {
this.wrapper.removeEventListener('click', this._onWrapperClick);
this.wrapper.parentNode.removeChild(this.wrapper);
this.wrapper = null;
}
}
}, {
key: "createWrapper",
value: function createWrapper() {
var prevSpectrogram = this.container.querySelector('spectrogram');
if (prevSpectrogram) {
this.container.removeChild(prevSpectrogram);
}
var wsParams = this.wavesurfer.params;
this.wrapper = document.createElement('spectrogram');
// if labels are active
if (this.params.labels) {
var labelsEl = this.labelsEl = document.createElement('canvas');
labelsEl.classList.add('spec-labels');
this.drawer.style(labelsEl, {
position: 'absolute',
zIndex: 9,
height: "".concat(this.height * this.channels, "px"),
width: "55px"
});
this.wrapper.appendChild(labelsEl);
this.loadLabels('rgba(68,68,68,0.5)', '12px', '10px', '', '#fff', '#f7f7f7', 'center', '#specLabels');
}
this.drawer.style(this.wrapper, {
display: 'block',
position: 'relative',
userSelect: 'none',
webkitUserSelect: 'none',
height: "".concat(this.height * this.channels, "px")
});
if (wsParams.fillParent || wsParams.scrollParent) {
this.drawer.style(this.wrapper, {
width: '100%',
overflowX: 'hidden',
overflowY: 'hidden'
});
}
this.container.appendChild(this.wrapper);
this.wrapper.addEventListener('click', this._onWrapperClick);
}
}, {
key: "_wrapperClickHandler",
value: function _wrapperClickHandler(event) {
event.preventDefault();
var relX = 'offsetX' in event ? event.offsetX : event.layerX;
this.fireEvent('click', relX / this.width || 0);
}
}, {
key: "createCanvas",
value: function createCanvas() {
var canvas = this.canvas = this.wrapper.appendChild(document.createElement('canvas'));
this.spectrCc = canvas.getContext('2d');
this.util.style(canvas, {
position: 'absolute',
zIndex: 4
});
}
}, {
key: "render",
value: function render() {
this.updateCanvasStyle();
if (this.frequenciesDataUrl) {
this.loadFrequenciesData(this.frequenciesDataUrl);
} else {
this.getFrequencies(this.drawSpectrogram);
}
}
}, {
key: "updateCanvasStyle",
value: function updateCanvasStyle() {
var width = Math.round(this.width / this.pixelRatio) + 'px';
this.canvas.width = this.width;
this.canvas.height = this.fftSamples / 2 * this.channels;
this.canvas.style.width = width;
this.canvas.style.height = this.height + 'px';
}
}, {
key: "drawSpectrogram",
value: function drawSpectrogram(frequenciesData, my) {
if (!isNaN(frequenciesData[0][0])) {
// data is 1ch [sample, freq] format
// to [channel, sample, freq] format
frequenciesData = [frequenciesData];
}
var spectrCc = my.spectrCc;
var height = my.fftSamples / 2;
var width = my.width;
var freqFrom = my.buffer.sampleRate / 2;
var freqMin = my.frequencyMin;
var freqMax = my.frequencyMax;
if (!spectrCc) {
return;
}
var _loop = function _loop(c) {
// for each channel
var pixels = my.resample(frequenciesData[c]);
var imageData = new ImageData(width, height);
for (var i = 0; i < pixels.length; i++) {
for (var j = 0; j < pixels[i].length; j++) {
var colorMap = my.colorMap[pixels[i][j]];
var redIndex = ((height - j) * width + i) * 4;
imageData.data[redIndex] = colorMap[0] * 255;
imageData.data[redIndex + 1] = colorMap[1] * 255;
imageData.data[redIndex + 2] = colorMap[2] * 255;
imageData.data[redIndex + 3] = colorMap[3] * 255;
}
}
// scale and stack spectrograms
createImageBitmap(imageData).then(function (renderer) {
return spectrCc.drawImage(renderer, 0, height * (1 - freqMax / freqFrom),
// source x, y
width, height * (freqMax - freqMin) / freqFrom,
// source width, height
0, height * c,
// destination x, y
width, height // destination width, height
);
});
};
for (var c = 0; c < frequenciesData.length; c++) {
_loop(c);
}
}
}, {
key: "getFrequencies",
value: function getFrequencies(callback) {
var fftSamples = this.fftSamples;
var buffer = this.buffer = this.wavesurfer.backend.buffer;
var channels = this.channels;
if (!buffer) {
this.fireEvent('error', 'Web Audio buffer is not available');
return;
}
// This may differ from file samplerate. Browser resamples audio.
var sampleRate = buffer.sampleRate;
var frequencies = [];
var noverlap = this.noverlap;
if (!noverlap) {
var uniqueSamplesPerPx = buffer.length / this.canvas.width;
noverlap = Math.max(0, Math.round(fftSamples - uniqueSamplesPerPx));
}
var fft = new _fft.default(fftSamples, sampleRate, this.windowFunc, this.alpha);
for (var c = 0; c < channels; c++) {
// for each channel
var channelData = buffer.getChannelData(c);
var channelFreq = [];
var currentOffset = 0;
while (currentOffset + fftSamples < channelData.length) {
var segment = channelData.slice(currentOffset, currentOffset + fftSamples);
var spectrum = fft.calculateSpectrum(segment);
var array = new Uint8Array(fftSamples / 2);
var j = void 0;
for (j = 0; j < fftSamples / 2; j++) {
array[j] = Math.max(-255, Math.log10(spectrum[j]) * 45);
}
channelFreq.push(array);
// channelFreq: [sample, freq]
currentOffset += fftSamples - noverlap;
}
frequencies.push(channelFreq);
// frequencies: [channel, sample, freq]
}
callback(frequencies, this);
}
}, {
key: "loadFrequenciesData",
value: function loadFrequenciesData(url) {
var _this2 = this;
var request = this.util.fetchFile({
url: url
});
request.on('success', function (data) {
return _this2.drawSpectrogram(JSON.parse(data), _this2);
});
request.on('error', function (e) {
return _this2.fireEvent('error', e);
});
return request;
}
}, {
key: "freqType",
value: function freqType(freq) {
return freq >= 1000 ? (freq / 1000).toFixed(1) : Math.round(freq);
}
}, {
key: "unitType",
value: function unitType(freq) {
return freq >= 1000 ? 'KHz' : 'Hz';
}
}, {
key: "loadLabels",
value: function loadLabels(bgFill, fontSizeFreq, fontSizeUnit, fontType, textColorFreq, textColorUnit, textAlign, container) {
var frequenciesHeight = this.height;
bgFill = bgFill || 'rgba(68,68,68,0)';
fontSizeFreq = fontSizeFreq || '12px';
fontSizeUnit = fontSizeUnit || '10px';
fontType = fontType || 'Helvetica';
textColorFreq = textColorFreq || '#fff';
textColorUnit = textColorUnit || '#fff';
textAlign = textAlign || 'center';
container = container || '#specLabels';
var bgWidth = 55;
var getMaxY = frequenciesHeight || 512;
var labelIndex = 5 * (getMaxY / 256);
var freqStart = this.frequencyMin;
var step = (this.frequencyMax - freqStart) / labelIndex;
// prepare canvas element for labels
var ctx = this.labelsEl.getContext('2d');
var dispScale = window.devicePixelRatio;
this.labelsEl.height = this.height * this.channels * dispScale;
this.labelsEl.width = bgWidth * dispScale;
ctx.scale(dispScale, dispScale);
if (!ctx) {
return;
}
for (var c = 0; c < this.channels; c++) {
// for each channel
// fill background
ctx.fillStyle = bgFill;
ctx.fillRect(0, c * getMaxY, bgWidth, (1 + c) * getMaxY);
ctx.fill();
var i = void 0;
// render labels
for (i = 0; i <= labelIndex; i++) {
ctx.textAlign = textAlign;
ctx.textBaseline = 'middle';
var freq = freqStart + step * i;
var label = this.freqType(freq);
var units = this.unitType(freq);
var yLabelOffset = 2;
var x = 16;
var y = void 0;
if (i == 0) {
y = (1 + c) * getMaxY + i - 10;
// unit label
ctx.fillStyle = textColorUnit;
ctx.font = fontSizeUnit + ' ' + fontType;
ctx.fillText(units, x + 24, y);
// freq label
ctx.fillStyle = textColorFreq;
ctx.font = fontSizeFreq + ' ' + fontType;
ctx.fillText(label, x, y);
} else {
y = (1 + c) * getMaxY - i * 50 + yLabelOffset;
// unit label
ctx.fillStyle = textColorUnit;
ctx.font = fontSizeUnit + ' ' + fontType;
ctx.fillText(units, x + 24, y);
// freq label
ctx.fillStyle = textColorFreq;
ctx.font = fontSizeFreq + ' ' + fontType;
ctx.fillText(label, x, y);
}
}
}
}
}, {
key: "updateScroll",
value: function updateScroll(e) {
if (this.wrapper) {
this.wrapper.scrollLeft = e.target.scrollLeft;
}
}
}, {
key: "resample",
value: function resample(oldMatrix) {
var columnsNumber = this.width;
var newMatrix = [];
var oldPiece = 1 / oldMatrix.length;
var newPiece = 1 / columnsNumber;
var i;
for (i = 0; i < columnsNumber; i++) {
var column = new Array(oldMatrix[0].length);
var j = void 0;
for (j = 0; j < oldMatrix.length; j++) {
var oldStart = j * oldPiece;
var oldEnd = oldStart + oldPiece;
var newStart = i * newPiece;
var newEnd = newStart + newPiece;
var overlap = oldEnd <= newStart || newEnd <= oldStart ? 0 : Math.min(Math.max(oldEnd, newStart), Math.max(newEnd, oldStart)) - Math.max(Math.min(oldEnd, newStart), Math.min(newEnd, oldStart));
var k = void 0;
/* eslint-disable max-depth */
if (overlap > 0) {
for (k = 0; k < oldMatrix[0].length; k++) {
if (column[k] == null) {
column[k] = 0;
}
column[k] += overlap / newPiece * oldMatrix[j][k];
}
}
/* eslint-enable max-depth */
}
var intColumn = new Uint8Array(oldMatrix[0].length);
var m = void 0;
for (m = 0; m < oldMatrix[0].length; m++) {
intColumn[m] = column[m];
}
newMatrix.push(intColumn);
}
return newMatrix;
}
}], [{
key: "create",
value:
/**
* Spectrogram plugin definition factory
*
* This function must be used to create a plugin definition which can be
* used by wavesurfer to correctly instantiate the plugin.
*
* @param {SpectrogramPluginParams} params Parameters used to initialise the plugin
* @return {PluginDefinition} An object representing the plugin.
*/
function create(params) {
return {
name: 'spectrogram',
deferInit: params && params.deferInit ? params.deferInit : false,
params: params,
staticProps: {
FFT: _fft.default
},
instance: SpectrogramPlugin
};
}
}]);
return SpectrogramPlugin;
}();
exports["default"] = SpectrogramPlugin;
module.exports = exports.default;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module is referenced by other modules so it can't be inlined
/******/ var __webpack_exports__ = __webpack_require__("./src/plugin/spectrogram/index.js");
/******/
/******/ return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=wavesurfer.spectrogram.js.map