UNPKG

essentia.js

Version:

JavaScript library for music/audio analysis and processing, powered by Essentia WebAssembly

734 lines (729 loc) 324 kB
/*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ function __awaiter(thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } /** * @license * Copyright (C) 2006-2020 Music Technology Group - Universitat Pompeu Fabra * * This file is part of Essentia * * Essentia is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation (FSF), either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the Affero GNU General Public License * version 3 along with this program. If not, see http://www.gnu.org/licenses/ */ // NOTE: The following code snippets are machine generated. Do not edit. /** * essentia.js-core JS API * @class * @example * const essentia = new Essentia(EssentiaWASM); */ var Essentia = /** @class */ (function () { /** * @constructs * @param {EssentiaWASM} Essentia WASM backend (emcripten global module object) which is loaded from 'essentia-wasm.*.js file' * @param {boolean} [isDebug=false] */ function Essentia(EssentiaWASM, isDebug) { if (isDebug === void 0) { isDebug = false; } this.EssentiaWASM = EssentiaWASM; this.isDebug = isDebug; this.algorithms = new EssentiaWASM.EssentiaJS(isDebug); this.module = EssentiaWASM; this.version = this.algorithms.version; this.algorithmNames = this.algorithms.algorithmNames; } /** * Decode and returns the audio buffer of a given audio url or blob uri using Web Audio API. * (NOTE: This method doesn't works on Safari browser) * @async * @method * @param {string} audioURL web url or blob uri of a audio file * @param {AudioContext} webAudioCtx an instance of Web Audio API `AudioContext` * @returns {AudioBuffer} decoded audio buffer object * @memberof Essentia */ Essentia.prototype.getAudioBufferFromURL = function (audioURL, webAudioCtx) { return __awaiter(this, void 0, void 0, function () { var response, arrayBuffer, audioBuffer; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, fetch(audioURL)]; case 1: response = _a.sent(); return [4 /*yield*/, response.arrayBuffer()]; case 2: arrayBuffer = _a.sent(); return [4 /*yield*/, webAudioCtx.decodeAudioData(arrayBuffer)]; case 3: audioBuffer = _a.sent(); return [2 /*return*/, audioBuffer]; } }); }); }; /** * Decode and returns the audio channel data from an given audio url or blob uri using Web Audio API. * (NOTE: This method doesn't works on Safari browser) * @async * @method * @param {string} audioURL web url or blob uri of a audio file * @param {AudioContext} webAudioCtx an instance of Web Audio API `AudioContext` * @param {number} [channel=0] audio channel number * @returns {Float32Array} decode and returns the audio data as Float32 array for the given channel * @memberof Essentia */ Essentia.prototype.getAudioChannelDataFromURL = function (audioURL, webAudioCtx, channel) { if (channel === void 0) { channel = 0; } return __awaiter(this, void 0, void 0, function () { var response, arrayBuffer, audioBuffer; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, fetch(audioURL)]; case 1: response = _a.sent(); return [4 /*yield*/, response.arrayBuffer()]; case 2: arrayBuffer = _a.sent(); return [4 /*yield*/, webAudioCtx.decodeAudioData(arrayBuffer)]; case 3: audioBuffer = _a.sent(); return [2 /*return*/, audioBuffer.getChannelData(channel)]; } }); }); }; /** * Convert an AudioBuffer object to a Mono audio signal array. The audio signal is downmixed * to mono using essentia `MonoMixer` algorithm if the audio buffer has 2 channels of audio. * Throws an expection if the input AudioBuffer object has more than 2 channels of audio. * @method * @param {AudioBuffer} buffer `AudioBuffer` object decoded from an audio file. * @returns {Float32Array} audio channel data. (downmixed to mono if its stereo signal). * @memberof Essentia */ Essentia.prototype.audioBufferToMonoSignal = function (buffer) { if (buffer.numberOfChannels === 1) { return buffer.getChannelData(0); } if (buffer.numberOfChannels === 2) { var left = this.arrayToVector(buffer.getChannelData(0)); var right = this.arrayToVector(buffer.getChannelData(1)); var monoSignal = this.MonoMixer(left, right); return this.vectorToArray(monoSignal); } throw new Error('Unexpected number of channels found in audio buffer. Only accepts mono or stereo audio buffers.'); }; /** * Method to shutdown essentia algorithm instance after it's use * @method * @memberof Essentia */ Essentia.prototype.shutdown = function () { this.algorithms.shutdown(); }; /** * Method for re-instantiating essentia algorithms instance after using the shutdown method * @method * @memberof Essentia */ Essentia.prototype.reinstantiate = function () { this.algorithms = new this.module.EssentiaJS(this.isDebug); }; /** * Delete essentiajs class instance * @method * @memberof Essentia */ Essentia.prototype.delete = function () { this.algorithms.delete(); }; /** * Convert an input JS array into VectorFloat type * @method * @param {Float32Array} inputArray input JS typed array * @returns {VectorFloat} returns vector float * @memberof Essentia */ Essentia.prototype.arrayToVector = function (inputArray) { return this.module.arrayToVector(inputArray); }; /** * Convert an input VectorFloat array into typed JS Float32Array * @method * @param {VectorFloat} inputVector input VectorFloat array * @returns {Float32Array} returns converted JS typed array * @memberof Essentia */ Essentia.prototype.vectorToArray = function (inputVector) { return this.module.vectorToArray(inputVector); }; /** * Cuts an audio signal data into overlapping frames given frame size and hop size * @method * @param {Float32Array} inputAudioData a single channel audio channel data * @param {number} [frameSize=2048] frame size for cutting the audio signal * @param {number} [hopSize=1024] size of overlapping frame * @returns {VectorVectorFloat} Returns a 2D vector float of sliced audio frames * @memberof Essentia */ Essentia.prototype.FrameGenerator = function (inputAudioData, frameSize, hopSize) { if (frameSize === void 0) { frameSize = 2048; } if (hopSize === void 0) { hopSize = 1024; } return this.algorithms.FrameGenerator(inputAudioData, frameSize, hopSize); }; /** * This algorithm downmixes the signal into a single channel given a stereo signal. It is a wrapper around https://essentia.upf.edu/reference/std_MonoMixer.html. * @method * @param {VectorFloat} leftChannel the left channel of the stereo audio signal * @param {VectorFloat} rightChannel the right channel of the stereo audio signal * @returns {object} {audio: 'the downmixed mono signal'} * @memberof Essentia */ Essentia.prototype.MonoMixer = function (leftSignal, rightSignal) { return this.algorithms.MonoMixer(leftSignal, rightSignal); }; /** * This algorithm computes the EBUR128 loudness descriptors of an audio signal. It is a wrapper around https://essentia.upf.edu/reference/std_LoudnessEBUR128.html. * @method * @param {VectorFloat} leftChannel the left channel of the stereo audio signal * @param {VectorFloat} rightChannel the right channel of the stereo audio signal * @param {number} [hopSize=0.1] the hop size with which the loudness is computed [s] * @param {number} [sampleRate=44100] the sampling rate of the audio signal [Hz] * @param {boolean} [startAtZero=false] start momentary/short-term loudness estimation at time 0 (zero-centered loudness estimation windows) if true; otherwise start both windows at time 0 (time positions for momentary and short-term values will not be syncronized) * @returns {object} {momentaryLoudness: 'momentary loudness (over 400ms) (LUFS)', shortTermLoudness: 'short-term loudness (over 3 seconds) (LUFS)', integratedLoudness: 'integrated loudness (overall) (LUFS)', loudnessRange: 'loudness range over an arbitrary long time interval [3] (dB, LU)'} * @memberof Essentia */ Essentia.prototype.LoudnessEBUR128 = function (leftSignal, rightSignal, hopSize, sampleRate, startAtZero) { if (hopSize === void 0) { hopSize = 0.1; } if (sampleRate === void 0) { sampleRate = 44100; } if (startAtZero === void 0) { startAtZero = false; } return this.algorithms.LoudnessEBUR128(leftSignal, rightSignal, hopSize, sampleRate, startAtZero); }; // NOTE: The following code snippets are machine generated. Do not edit. /** * This algorithm computes the ratio between the pitch energy after the pitch maximum and the pitch energy before the pitch maximum. Sounds having an monotonically ascending pitch or one unique pitch will show a value of (0,1], while sounds having a monotonically descending pitch will show a value of [1,inf). In case there is no energy before the max pitch, the algorithm will return the energy after the maximum pitch. Check https://essentia.upf.edu/reference/std_AfterMaxToBeforeMaxEnergyRatio.html for more details. * @method * @param {VectorFloat} pitch the array of pitch values [Hz] * @returns {object} {afterMaxToBeforeMaxEnergyRatio: 'the ratio between the pitch energy after the pitch maximum to the pitch energy before the pitch maximum'} * @memberof Essentia */ Essentia.prototype.AfterMaxToBeforeMaxEnergyRatio = function (pitch) { return this.algorithms.AfterMaxToBeforeMaxEnergyRatio(pitch); }; /** * This algorithm implements a IIR all-pass filter of order 1 or 2. Because of its dependence on IIR, IIR's requirements are inherited. Check https://essentia.upf.edu/reference/std_AllPass.html for more details. * @method * @param {VectorFloat} signal the input signal * @param {number} [bandwidth=500] the bandwidth of the filter [Hz] (used only for 2nd-order filters) * @param {number} [cutoffFrequency=1500] the cutoff frequency for the filter [Hz] * @param {number} [order=1] the order of the filter * @param {number} [sampleRate=44100] the sampling rate of the audio signal [Hz] * @returns {object} {signal: 'the filtered signal'} * @memberof Essentia */ Essentia.prototype.AllPass = function (signal, bandwidth, cutoffFrequency, order, sampleRate) { if (bandwidth === void 0) { bandwidth = 500; } if (cutoffFrequency === void 0) { cutoffFrequency = 1500; } if (order === void 0) { order = 1; } if (sampleRate === void 0) { sampleRate = 44100; } return this.algorithms.AllPass(signal, bandwidth, cutoffFrequency, order, sampleRate); }; /** * This algorithm creates a wave file in which a given audio signal is mixed with a series of time onsets. The sonification of the onsets can be heard as beeps, or as short white noise pulses if configured to do so. Check https://essentia.upf.edu/reference/std_AudioOnsetsMarker.html for more details. * @method * @param {VectorFloat} signal the input signal * @param {any[]} [onsets=[]] the list of onset locations [s] * @param {number} [sampleRate=44100] the sampling rate of the output signal [Hz] * @param {string} [type=beep] the type of sound to be added on the event * @returns {object} {signal: 'the input signal mixed with bursts at onset locations'} * @memberof Essentia */ Essentia.prototype.AudioOnsetsMarker = function (signal, onsets, sampleRate, type) { if (onsets === void 0) { onsets = []; } if (sampleRate === void 0) { sampleRate = 44100; } if (type === void 0) { type = 'beep'; } var veconsets = new this.module.VectorFloat(); for (var i = 0; i < veconsets.size(); i++) { veconsets.push_back(onsets[i]); } return this.algorithms.AudioOnsetsMarker(signal, veconsets, sampleRate, type); }; /** * This algorithm computes the autocorrelation vector of a signal. It uses the version most commonly used in signal processing, which doesn't remove the mean from the observations. Using the 'generalized' option this algorithm computes autocorrelation as described in [3]. Check https://essentia.upf.edu/reference/std_AutoCorrelation.html for more details. * @method * @param {VectorFloat} array the array to be analyzed * @param {number} [frequencyDomainCompression=0.5] factor at which FFT magnitude is compressed (only used if 'generalized' is set to true, see [3]) * @param {boolean} [generalized=false] bool value to indicate whether to compute the 'generalized' autocorrelation as described in [3] * @param {string} [normalization=standard] type of normalization to compute: either 'standard' (default) or 'unbiased' * @returns {object} {autoCorrelation: 'the autocorrelation vector'} * @memberof Essentia */ Essentia.prototype.AutoCorrelation = function (array, frequencyDomainCompression, generalized, normalization) { if (frequencyDomainCompression === void 0) { frequencyDomainCompression = 0.5; } if (generalized === void 0) { generalized = false; } if (normalization === void 0) { normalization = 'standard'; } return this.algorithms.AutoCorrelation(array, frequencyDomainCompression, generalized, normalization); }; /** * This algorithm computes the bark-frequency cepstrum coefficients of a spectrum. Bark bands and their subsequent usage in cepstral analysis have shown to be useful in percussive content [1, 2] This algorithm is implemented using the Bark scaling approach in the Rastamat version of the MFCC algorithm and in a similar manner to the MFCC-FB40 default specs: Check https://essentia.upf.edu/reference/std_BFCC.html for more details. * @method * @param {VectorFloat} spectrum the audio spectrum * @param {number} [dctType=2] the DCT type * @param {number} [highFrequencyBound=11000] the upper bound of the frequency range [Hz] * @param {number} [inputSize=1025] the size of input spectrum * @param {number} [liftering=0] the liftering coefficient. Use '0' to bypass it * @param {string} [logType=dbamp] logarithmic compression type. Use 'dbpow' if working with power and 'dbamp' if working with magnitudes * @param {number} [lowFrequencyBound=0] the lower bound of the frequency range [Hz] * @param {string} [normalize=unit_sum] 'unit_max' makes the vertex of all the triangles equal to 1, 'unit_sum' makes the area of all the triangles equal to 1 * @param {number} [numberBands=40] the number of bark bands in the filter * @param {number} [numberCoefficients=13] the number of output cepstrum coefficients * @param {number} [sampleRate=44100] the sampling rate of the audio signal [Hz] * @param {string} [type=power] use magnitude or power spectrum * @param {string} [weighting=warping] type of weighting function for determining triangle area * @returns {object} {bands: 'the energies in bark bands', bfcc: 'the bark frequency cepstrum coefficients'} * @memberof Essentia */ Essentia.prototype.BFCC = function (spectrum, dctType, highFrequencyBound, inputSize, liftering, logType, lowFrequencyBound, normalize, numberBands, numberCoefficients, sampleRate, type, weighting) { if (dctType === void 0) { dctType = 2; } if (highFrequencyBound === void 0) { highFrequencyBound = 11000; } if (inputSize === void 0) { inputSize = 1025; } if (liftering === void 0) { liftering = 0; } if (logType === void 0) { logType = 'dbamp'; } if (lowFrequencyBound === void 0) { lowFrequencyBound = 0; } if (normalize === void 0) { normalize = 'unit_sum'; } if (numberBands === void 0) { numberBands = 40; } if (numberCoefficients === void 0) { numberCoefficients = 13; } if (sampleRate === void 0) { sampleRate = 44100; } if (type === void 0) { type = 'power'; } if (weighting === void 0) { weighting = 'warping'; } return this.algorithms.BFCC(spectrum, dctType, highFrequencyBound, inputSize, liftering, logType, lowFrequencyBound, normalize, numberBands, numberCoefficients, sampleRate, type, weighting); }; /** * This algorithm implements a break point function which linearly interpolates between discrete xy-coordinates to construct a continuous function. Check https://essentia.upf.edu/reference/std_BPF.html for more details. * @method * @param {number} x the input coordinate (x-axis) * @param {any[]} [xPoints=[0, 1]] the x-coordinates of the points forming the break-point function (the points must be arranged in ascending order and cannot contain duplicates) * @param {any[]} [yPoints=[0, 1]] the y-coordinates of the points forming the break-point function * @returns {object} {y: 'the output coordinate (y-axis)'} * @memberof Essentia */ Essentia.prototype.BPF = function (x, xPoints, yPoints) { if (xPoints === void 0) { xPoints = [0, 1]; } if (yPoints === void 0) { yPoints = [0, 1]; } var vecxPoints = new this.module.VectorFloat(); for (var i = 0; i < vecxPoints.size(); i++) { vecxPoints.push_back(xPoints[i]); } var vecyPoints = new this.module.VectorFloat(); for (var i = 0; i < vecyPoints.size(); i++) { vecyPoints.push_back(yPoints[i]); } return this.algorithms.BPF(x, vecxPoints, vecyPoints); }; /** * This algorithm implements a 2nd order IIR band-pass filter. Because of its dependence on IIR, IIR's requirements are inherited. Check https://essentia.upf.edu/reference/std_BandPass.html for more details. * @method * @param {VectorFloat} signal the input audio signal * @param {number} [bandwidth=500] the bandwidth of the filter [Hz] * @param {number} [cutoffFrequency=1500] the cutoff frequency for the filter [Hz] * @param {number} [sampleRate=44100] the sampling rate of the audio signal [Hz] * @returns {object} {signal: 'the filtered signal'} * @memberof Essentia */ Essentia.prototype.BandPass = function (signal, bandwidth, cutoffFrequency, sampleRate) { if (bandwidth === void 0) { bandwidth = 500; } if (cutoffFrequency === void 0) { cutoffFrequency = 1500; } if (sampleRate === void 0) { sampleRate = 44100; } return this.algorithms.BandPass(signal, bandwidth, cutoffFrequency, sampleRate); }; /** * This algorithm implements a 2nd order IIR band-reject filter. Because of its dependence on IIR, IIR's requirements are inherited. Check https://essentia.upf.edu/reference/std_BandReject.html for more details. * @method * @param {VectorFloat} signal the input signal * @param {number} [bandwidth=500] the bandwidth of the filter [Hz] * @param {number} [cutoffFrequency=1500] the cutoff frequency for the filter [Hz] * @param {number} [sampleRate=44100] the sampling rate of the audio signal [Hz] * @returns {object} {signal: 'the filtered signal'} * @memberof Essentia */ Essentia.prototype.BandReject = function (signal, bandwidth, cutoffFrequency, sampleRate) { if (bandwidth === void 0) { bandwidth = 500; } if (cutoffFrequency === void 0) { cutoffFrequency = 1500; } if (sampleRate === void 0) { sampleRate = 44100; } return this.algorithms.BandReject(signal, bandwidth, cutoffFrequency, sampleRate); }; /** * This algorithm computes energy in Bark bands of a spectrum. The band frequencies are: [0.0, 50.0, 100.0, 150.0, 200.0, 300.0, 400.0, 510.0, 630.0, 770.0, 920.0, 1080.0, 1270.0, 1480.0, 1720.0, 2000.0, 2320.0, 2700.0, 3150.0, 3700.0, 4400.0, 5300.0, 6400.0, 7700.0, 9500.0, 12000.0, 15500.0, 20500.0, 27000.0]. The first two Bark bands [0,100] and [100,200] have been split in half for better resolution (because of an observed better performance in beat detection). For each bark band the power-spectrum (mag-squared) is summed. Check https://essentia.upf.edu/reference/std_BarkBands.html for more details. * @method * @param {VectorFloat} spectrum the input spectrum * @param {number} [numberBands=27] the number of desired barkbands * @param {number} [sampleRate=44100] the sampling rate of the audio signal [Hz] * @returns {object} {bands: 'the energy of the bark bands'} * @memberof Essentia */ Essentia.prototype.BarkBands = function (spectrum, numberBands, sampleRate) { if (numberBands === void 0) { numberBands = 27; } if (sampleRate === void 0) { sampleRate = 44100; } return this.algorithms.BarkBands(spectrum, numberBands, sampleRate); }; /** * This algorithm estimates the beat positions given an input signal. It computes 'complex spectral difference' onset detection function and utilizes the beat tracking algorithm (TempoTapDegara) to extract beats [1]. The algorithm works with the optimized settings of 2048/1024 frame/hop size for the computation of the detection function, with its posterior x2 resampling.) While it has a lower accuracy than BeatTrackerMultifeature (see the evaluation results in [2]), its computational speed is significantly higher, which makes reasonable to apply this algorithm for batch processings of large amounts of audio signals. Check https://essentia.upf.edu/reference/std_BeatTrackerDegara.html for more details. * @method * @param {VectorFloat} signal the audio input signal * @param {number} [maxTempo=208] the fastest tempo to detect [bpm] * @param {number} [minTempo=40] the slowest tempo to detect [bpm] * @returns {object} {ticks: ' the estimated tick locations [s]'} * @memberof Essentia */ Essentia.prototype.BeatTrackerDegara = function (signal, maxTempo, minTempo) { if (maxTempo === void 0) { maxTempo = 208; } if (minTempo === void 0) { minTempo = 40; } return this.algorithms.BeatTrackerDegara(signal, maxTempo, minTempo); }; /** * This algorithm estimates the beat positions given an input signal. It computes a number of onset detection functions and estimates beat location candidates from them using TempoTapDegara algorithm. Thereafter the best candidates are selected using TempoTapMaxAgreement. The employed detection functions, and the optimal frame/hop sizes used for their computation are: - complex spectral difference (see 'complex' method in OnsetDetection algorithm, 2048/1024 with posterior x2 upsample or the detection function) - energy flux (see 'rms' method in OnsetDetection algorithm, the same settings) - spectral flux in Mel-frequency bands (see 'melflux' method in OnsetDetection algorithm, the same settings) - beat emphasis function (see 'beat_emphasis' method in OnsetDetectionGlobal algorithm, 2048/512) - spectral flux between histogrammed spectrum frames, measured by the modified information gain (see 'infogain' method in OnsetDetectionGlobal algorithm, 2048/512) Check https://essentia.upf.edu/reference/std_BeatTrackerMultiFeature.html for more details. * @method * @param {VectorFloat} signal the audio input signal * @param {number} [maxTempo=208] the fastest tempo to detect [bpm] * @param {number} [minTempo=40] the slowest tempo to detect [bpm] * @returns {object} {ticks: ' the estimated tick locations [s]', confidence: 'confidence of the beat tracker [0, 5.32]'} * @memberof Essentia */ Essentia.prototype.BeatTrackerMultiFeature = function (signal, maxTempo, minTempo) { if (maxTempo === void 0) { maxTempo = 208; } if (minTempo === void 0) { minTempo = 40; } return this.algorithms.BeatTrackerMultiFeature(signal, maxTempo, minTempo); }; /** * This algorithm filters the loudness matrix given by BeatsLoudness algorithm in order to keep only the most salient beat band representation. This algorithm has been found to be useful for estimating time signatures. Check https://essentia.upf.edu/reference/std_Beatogram.html for more details. * @method * @param {VectorFloat} loudness the loudness at each beat * @param {VectorVectorFloat} loudnessBandRatio matrix of loudness ratios at each band and beat * @param {number} [size=16] number of beats for dynamic filtering * @returns {object} {beatogram: 'filtered matrix loudness'} * @memberof Essentia */ Essentia.prototype.Beatogram = function (loudness, loudnessBandRatio, size) { if (size === void 0) { size = 16; } return this.algorithms.Beatogram(loudness, loudnessBandRatio, size); }; /** * This algorithm computes the spectrum energy of beats in an audio signal given their positions. The energy is computed both on the whole frequency range and for each of the specified frequency bands. See the SingleBeatLoudness algorithm for a more detailed explanation. Check https://essentia.upf.edu/reference/std_BeatsLoudness.html for more details. * @method * @param {VectorFloat} signal the input audio signal * @param {number} [beatDuration=0.05] the duration of the window in which the beat will be restricted [s] * @param {number} [beatWindowDuration=0.1] the duration of the window in which to look for the beginning of the beat (centered around the positions in 'beats') [s] * @param {any[]} [beats=[]] the list of beat positions (each position is in seconds) * @param {any[]} [frequencyBands=[20, 150, 400, 3200, 7000, 22000]] the list of bands to compute energy ratios [Hz * @param {number} [sampleRate=44100] the audio sampling rate [Hz] * @returns {object} {loudness: 'the beat's energy in the whole spectrum', loudnessBandRatio: 'the ratio of the beat's energy on each frequency band'} * @memberof Essentia */ Essentia.prototype.BeatsLoudness = function (signal, beatDuration, beatWindowDuration, beats, frequencyBands, sampleRate) { if (beatDuration === void 0) { beatDuration = 0.05; } if (beatWindowDuration === void 0) { beatWindowDuration = 0.1; } if (beats === void 0) { beats = []; } if (frequencyBands === void 0) { frequencyBands = [20, 150, 400, 3200, 7000, 22000]; } if (sampleRate === void 0) { sampleRate = 44100; } var vecbeats = new this.module.VectorFloat(); for (var i = 0; i < vecbeats.size(); i++) { vecbeats.push_back(beats[i]); } var vecfrequencyBands = new this.module.VectorFloat(); for (var i = 0; i < vecfrequencyBands.size(); i++) { vecfrequencyBands.push_back(frequencyBands[i]); } return this.algorithms.BeatsLoudness(signal, beatDuration, beatWindowDuration, vecbeats, vecfrequencyBands, sampleRate); }; /** * This algorithm performs basic arithmetical operations element by element given two arrays. Note: - using this algorithm in streaming mode can cause diamond shape graphs which have not been tested with the current scheduler. There is NO GUARANTEE of its correct work for diamond shape graphs. - for y<0, x/y is invalid Check https://essentia.upf.edu/reference/std_BinaryOperator.html for more details. * @method * @param {VectorFloat} array1 the first operand input array * @param {VectorFloat} array2 the second operand input array * @param {string} [type=add] the type of the binary operator to apply to the input arrays * @returns {object} {array: 'the array containing the result of binary operation'} * @memberof Essentia */ Essentia.prototype.BinaryOperator = function (array1, array2, type) { if (type === void 0) { type = 'add'; } return this.algorithms.BinaryOperator(array1, array2, type); }; /** * This algorithm performs basic arithmetical operations element by element given two arrays. Note: - using this algorithm in streaming mode can cause diamond shape graphs which have not been tested with the current scheduler. There is NO GUARANTEE of its correct work for diamond shape graphs. - for y<0, x/y is invalid Check https://essentia.upf.edu/reference/std_BinaryOperatorStream.html for more details. * @method * @param {VectorFloat} array1 the first operand input array * @param {VectorFloat} array2 the second operand input array * @param {string} [type=add] the type of the binary operator to apply to the input arrays * @returns {object} {array: 'the array containing the result of binary operation'} * @memberof Essentia */ Essentia.prototype.BinaryOperatorStream = function (array1, array2, type) { if (type === void 0) { type = 'add'; } return this.algorithms.BinaryOperatorStream(array1, array2, type); }; /** * This algorithm computes beats per minute histogram and its statistics for the highest and second highest peak. Note: histogram vector contains occurance frequency for each bpm value, 0-th element corresponds to 0 bpm value. Check https://essentia.upf.edu/reference/std_BpmHistogramDescriptors.html for more details. * @method * @param {VectorFloat} bpmIntervals the list of bpm intervals [s] * @returns {object} {firstPeakBPM: 'value for the highest peak [bpm]', firstPeakWeight: 'weight of the highest peak', firstPeakSpread: 'spread of the highest peak', secondPeakBPM: 'value for the second highest peak [bpm]', secondPeakWeight: 'weight of the second highest peak', secondPeakSpread: 'spread of the second highest peak', histogram: 'bpm histogram [bpm]'} * @memberof Essentia */ Essentia.prototype.BpmHistogramDescriptors = function (bpmIntervals) { return this.algorithms.BpmHistogramDescriptors(bpmIntervals); }; /** * This algorithm extracts the locations of large tempo changes from a list of beat ticks. Check https://essentia.upf.edu/reference/std_BpmRubato.html for more details. * @method * @param {VectorFloat} beats list of detected beat ticks [s] * @param {number} [longRegionsPruningTime=20] time for the longest constant tempo region inside a rubato region [s] * @param {number} [shortRegionsMergingTime=4] time for the shortest constant tempo region from one tempo region to another [s] * @param {number} [tolerance=0.08] minimum tempo deviation to look for * @returns {object} {rubatoStart: 'list of timestamps where the start of a rubato region was detected [s]', rubatoStop: 'list of timestamps where the end of a rubato region was detected [s]', rubatoNumber: 'number of detected rubato regions'} * @memberof Essentia */ Essentia.prototype.BpmRubato = function (beats, longRegionsPruningTime, shortRegionsMergingTime, tolerance) { if (longRegionsPruningTime === void 0) { longRegionsPruningTime = 20; } if (shortRegionsMergingTime === void 0) { shortRegionsMergingTime = 4; } if (tolerance === void 0) { tolerance = 0.08; } return this.algorithms.BpmRubato(beats, longRegionsPruningTime, shortRegionsMergingTime, tolerance); }; /** * This algorithm extracts the 0th, 1st, 2nd, 3rd and 4th central moments of an array. It returns a 5-tuple in which the index corresponds to the order of the moment. Check https://essentia.upf.edu/reference/std_CentralMoments.html for more details. * @method * @param {VectorFloat} array the input array * @param {string} [mode=pdf] compute central moments considering array values as a probability density function over array index or as sample points of a distribution * @param {number} [range=1] the range of the input array, used for normalizing the results in the 'pdf' mode * @returns {object} {centralMoments: 'the central moments of the input array'} * @memberof Essentia */ Essentia.prototype.CentralMoments = function (array, mode, range) { if (mode === void 0) { mode = 'pdf'; } if (range === void 0) { range = 1; } return this.algorithms.CentralMoments(array, mode, range); }; /** * This algorithm computes the centroid of an array. The centroid is normalized to a specified range. This algorithm can be used to compute spectral centroid or temporal centroid. Check https://essentia.upf.edu/reference/std_Centroid.html for more details. * @method * @param {VectorFloat} array the input array * @param {number} [range=1] the range of the input array, used for normalizing the results * @returns {object} {centroid: 'the centroid of the array'} * @memberof Essentia */ Essentia.prototype.Centroid = function (array, range) { if (range === void 0) { range = 1; } return this.algorithms.Centroid(array, range); }; /** * Given a chord progression this algorithm describes it by means of key, scale, histogram, and rate of change. Note: - chordsHistogram indexes follow the circle of fifths order, while being shifted to the input key and scale - key and scale are taken from the most frequent chord. In the case where multiple chords are equally frequent, the chord is hierarchically chosen from the circle of fifths. - chords should follow this name convention `<A-G>[<#/b><m>]` (i.e. C, C# or C#m are valid chords). Chord names not fitting this convention will throw an exception. Check https://essentia.upf.edu/reference/std_ChordsDescriptors.html for more details. * @method * @param {VectorString} chords the chord progression * @param {string} key the key of the whole song, from A to G * @param {string} scale the scale of the whole song (major or minor) * @returns {object} {chordsHistogram: 'the normalized histogram of chords', chordsNumberRate: 'the ratio of different chords from the total number of chords in the progression', chordsChangesRate: 'the rate at which chords change in the progression', chordsKey: 'the most frequent chord of the progression', chordsScale: 'the scale of the most frequent chord of the progression (either 'major' or 'minor')'} * @memberof Essentia */ Essentia.prototype.ChordsDescriptors = function (chords, key, scale) { return this.algorithms.ChordsDescriptors(chords, key, scale); }; /** * This algorithm estimates chords given an input sequence of harmonic pitch class profiles (HPCPs). It finds the best matching major or minor triad and outputs the result as a string (e.g. A#, Bm, G#m, C). This algorithm uses the Sharp versions of each Flatted note (i.e. Bb -> A#). Check https://essentia.upf.edu/reference/std_ChordsDetection.html for more details. * @method * @param {VectorVectorFloat} pcp the pitch class profile from which to detect the chord * @param {number} [hopSize=2048] the hop size with which the input PCPs were computed * @param {number} [sampleRate=44100] the sampling rate of the audio signal [Hz] * @param {number} [windowSize=2] the size of the window on which to estimate the chords [s] * @returns {object} {chords: 'the resulting chords, from A to G', strength: 'the strength of the chord'} * @memberof Essentia */ Essentia.prototype.ChordsDetection = function (pcp, hopSize, sampleRate, windowSize) { if (hopSize === void 0) { hopSize = 2048; } if (sampleRate === void 0) { sampleRate = 44100; } if (windowSize === void 0) { windowSize = 2; } return this.algorithms.ChordsDetection(pcp, hopSize, sampleRate, windowSize); }; /** * This algorithm estimates chords using pitch profile classes on segments between beats. It is similar to ChordsDetection algorithm, but the chords are estimated on audio segments between each pair of consecutive beats. For each segment the estimation is done based on a chroma (HPCP) vector characterizing it, which can be computed by two methods: - 'interbeat_median', each resulting chroma vector component is a median of all the component values in the segment - 'starting_beat', chroma vector is sampled from the start of the segment (that is, its starting beat position) using its first frame. It makes sense if chroma is preliminary smoothed. Check https://essentia.upf.edu/reference/std_ChordsDetectionBeats.html for more details. * @method * @param {VectorVectorFloat} pcp the pitch class profile from which to detect the chord * @param {VectorFloat} ticks the list of beat positions (in seconds) * @param {string} [chromaPick=interbeat_median] method of calculating singleton chroma for interbeat interval * @param {number} [hopSize=2048] the hop size with which the input PCPs were computed * @param {number} [sampleRate=44100] the sampling rate of the audio signal [Hz] * @returns {object} {chords: 'the resulting chords, from A to G', strength: 'the strength of the chords'} * @memberof Essentia */ Essentia.prototype.ChordsDetectionBeats = function (pcp, ticks, chromaPick, hopSize, sampleRate) { if (chromaPick === void 0) { chromaPick = 'interbeat_median'; } if (hopSize === void 0) { hopSize = 2048; } if (sampleRate === void 0) { sampleRate = 44100; } return this.algorithms.ChordsDetectionBeats(pcp, ticks, chromaPick, hopSize, sampleRate); }; /** * This algorithm computes a binary cross similarity matrix from two chromagam feature vectors of a query and reference song. Check https://essentia.upf.edu/reference/std_ChromaCrossSimilarity.html for more details. * @method * @param {VectorVectorFloat} queryFeature frame-wise chromagram of the query song (e.g., a HPCP) * @param {VectorVectorFloat} referenceFeature frame-wise chromagram of the reference song (e.g., a HPCP) * @param {number} [binarizePercentile=0.095] maximum percent of distance values to consider as similar in each row and each column * @param {number} [frameStackSize=9] number of input frames to stack together and treat as a feature vector for similarity computation. Choose 'frameStackSize=1' to use the original input frames without stacking * @param {number} [frameStackStride=1] stride size to form a stack of frames (e.g., 'frameStackStride'=1 to use consecutive frames; 'frameStackStride'=2 for using every second frame) * @param {number} [noti=12] number of circular shifts to be checked for Optimal Transposition Index [1] * @param {boolean} [oti=true] whether to transpose the key of the reference song to the query song by Optimal Transposition Index [1] * @param {boolean} [otiBinary=false] whether to use the OTI-based chroma binary similarity method [3] * @param {boolean} [streaming=false] whether to accumulate the input 'queryFeature' in the euclidean similarity matrix calculation on each compute() method call * @returns {object} {csm: '2D binary cross-similarity matrix of the query and reference features'} * @memberof Essentia */ Essentia.prototype.ChromaCrossSimilarity = function (queryFeature, referenceFeature, binarizePercentile, frameStackSize, frameStackStride, noti, oti, otiBinary, streaming) { if (binarizePercentile === void 0) { binarizePercentile = 0.095; } if (frameStackSize === void 0) { frameStackSize = 9; } if (frameStackStride === void 0) { frameStackStride = 1; } if (noti === void 0) { noti = 12; } if (oti === void 0) { oti = true; } if (otiBinary === void 0) { otiBinary = false; } if (streaming === void 0) { streaming = false; } return this.algorithms.ChromaCrossSimilarity(queryFeature, referenceFeature, binarizePercentile, frameStackSize, frameStackStride, noti, oti, otiBinary, streaming); }; /** * This algorithm computes the Constant-Q chromagram using FFT. See ConstantQ algorithm for more details. Check https://essentia.upf.edu/reference/std_Chromagram.html for more details. * @method * @param {VectorFloat} frame the input audio frame * @param {number} [binsPerOctave=12] number of bins per octave * @param {number} [minFrequency=32.7] minimum frequency [Hz] * @param {number} [minimumKernelSize=4] minimum size allowed for frequency kernels * @param {string} [normalizeType=unit_max] normalize type * @param {number} [numberBins=84] number of frequency bins, starting at minFrequency * @param {number} [sampleRate=44100] FFT sampling rate [Hz] * @param {number} [scale=1] filters scale. Larger values use longer windows * @param {number} [threshold=0.01] bins whose magnitude is below this quantile are discarded * @param {string} [windowType=hann] the window type, which can be 'hamming', 'hann', 'triangular', 'square' or 'blackmanharrisXX' * @param {boolean} [zeroPhase=true] a boolean value that enables zero-phase windowing. Input audio frames should be windowed with the same phase mode * @returns {object} {chromagram: 'the magnitude constant-Q chromagram'} * @memberof Essentia */ Essentia.prototype.Chromagram = function (frame, binsPerOctave, minFrequency, minimumKernelSize, normalizeType, numberBins, sampleRate, scale, threshold, windowType, zeroPhase) { if (binsPerOctave === void 0) { binsPerOctave = 12; } if (minFrequency === void 0) { minFrequency = 32.7; } if (minimumKernelSize === void 0) { minimumKernelSize = 4; } if (normalizeType === void 0) { normalizeType = 'unit_max'; } if (numberBins === void 0) { numberBins = 84; } if (sampleRate === void 0) { sampleRate = 44100; } if (scale === void 0) { scale = 1; } if (threshold === void 0) { threshold = 0.01; } if (windowType === void 0) { windowType = 'hann'; } if (zeroPhase === void 0) { zeroPhase = true; } return this.algorithms.Chromagram(frame, binsPerOctave, minFrequency, minimumKernelSize, normalizeType, numberBins, sampleRate, scale, threshold, windowType, zeroPhase); }; /** * This algorithm detects the locations of impulsive noises (clicks and pops) on the input audio frame. It relies on LPC coefficients to inverse-filter the audio in order to attenuate the stationary part and enhance the prediction error (or excitation noise)[1]. After this, a matched filter is used to further enhance the impulsive peaks. The detection threshold is obtained from a robust estimate of the excitation noise power [2] plus a parametric gain value. Check https://essentia.upf.edu/reference/std_ClickDetector.html for more details. * @method * @param {VectorFloat} frame the input frame (must be non-empty) * @param {number} [detectionThreshold=30] 'detectionThreshold' the threshold is based on the instant power of the noisy excitation signal plus detectionThreshold dBs * @param {number} [frameSize=512] the expected size of the input audio signal (this is an optional parameter to optimize memory allocation) * @param {number} [hopSize=256] hop size used for the analysis. This parameter must be set correctly as it cannot be obtained from the input data * @param {number} [order=12] scalar giving the number of LPCs to use * @param {number} [powerEstimationThreshold=10] the noisy excitation is clipped to 'powerEstimationThreshold' times its median. * @param {number} [sampleRate=44100] sample rate used for the analysis * @param {number} [silenceThreshold=-50] threshold to skip silent frames * @returns {object} {starts: 'starting indexes of the clicks', ends: 'ending indexes of the clicks'} * @memberof Essentia */ Essentia.prototype.ClickDetector = function (frame, detectionThreshold, frameSize, hopSize, order, powerEstimationThreshold, sampleRate, silenceThreshold) { if (detectionThreshold === void 0) { detectionThreshold = 30; } if (frameSize === void 0) { frameSize = 512; } if (hopSize === void 0) { hopSize = 256; } if (order === void 0) { order = 12; } if (powerEstimationThreshold === void 0) { powerEstimationThreshold = 10; } if (sampleRate === void 0) { sampleRate = 44100; } if (silenceThreshold === void 0) { silenceThreshold = -50; } return this.algorithms.ClickDetector(frame, detectionThreshold, frameSize, hopSize, order, powerEstimationThreshold, sampleRate, silenceThreshold); }; /** * This algorithm clips the input signal to fit its values into a specified interval. Check https://essentia.upf.edu/reference/std_Clipper.html for more details. * @method * @param {VectorFloat} signal the input signal * @param {number} [max=1] the maximum value above which the signal will be clipped * @param {number} [min=-1] the minimum value below which the signal will be clipped * @returns {object} {signal: 'the output signal with the added noise'} * @memberof Essentia */ Essentia.prototype.Clipper = function (signal, max, min) { if (max === void 0) { max = 1; } if (min === void 0) { min = -1; } return this.algorithms.Clipper(signal, max