meyda
Version:
Real-time feature extraction for the web audio api
198 lines (197 loc) • 7.92 kB
TypeScript
/**
* This file contains the default export for Meyda, you probably want to check
* out {@link default}
*
* @module Meyda
*/
import { MeydaAnalyzer } from "./meyda-wa";
export interface MeydaFeaturesObject {
amplitudeSpectrum: Float32Array;
buffer: number[];
chroma: number[];
complexSpectrum: {
real: number[];
imag: number[];
};
energy: number;
loudness: {
specific: Float32Array;
total: number;
};
mfcc: number[];
perceptualSharpness: number;
perceptualSpread: number;
powerSpectrum: Float32Array;
rms: number;
spectralCentroid: number;
spectralFlatness: number;
spectralKurtosis: number;
spectralRolloff: number;
spectralSkewness: number;
spectralSlope: number;
spectralSpread: number;
spectralCrest: number;
zcr: number;
}
export type MeydaWindowingFunction = "blackman" | "sine" | "hanning" | "hamming";
export type MeydaAudioFeature = "amplitudeSpectrum" | "chroma" | "complexSpectrum" | "energy" | "loudness" | "mfcc" | "perceptualSharpness" | "perceptualSpread" | "powerSpectrum" | "rms" | "spectralCentroid" | "spectralFlatness" | "spectralFlux" | "spectralKurtosis" | "spectralRolloff" | "spectralSkewness" | "spectralSlope" | "spectralSpread" | "spectralCrest" | "zcr" | "buffer" | "melBands";
/**
* A type representing an audio signal. In general it should be an array of
* numbers that is sliceable. Float32Array is assignable here, and we generally
* expect that most signals will be in this format.
*/
export type MeydaSignal = SliceableArrayLike<number> | Float32Array;
export interface SliceableArrayLike<T> extends ArrayLike<T> {
slice(start: number, end: number): SliceableArrayLike<T>;
}
/**
* Meyda is a library for extracting audio features from an audio signal.
*
* The primary entry points are {@link extract} for audio feature extraction on
* raw signals you have in memory, and {@link createMeydaAnalyzer}, which
* provides a {@link MeydaAnalyzer} object that can be used to extract features
* on a Web Audio API AudioNode. The latter is only supported on web targets,
* though if you're using the Web Audio API in a non-web target, we'd love to
* hear from you.
*
* We also expose {@link listAvailableFeatureExtractors} which returns a list of the
* available feature extractors, and {@link windowing}, which lets you apply
* a windowing function to your signal outside of Meyda.
*
* We existed long before esmodules, so our backwards compatible API may seem
* unusual. We export a default object, with read/write fields that control
* various parameters of the audio feature extraction process. We're working on
* a new interface, check out [#257](https://github.com/meyda/meyda/issues/257)
* for more information.
*/
interface Meyda {
/**
* Meyda stores a reference to the relevant audio context here for use inside
* the Web Audio API.
*/
audioContext: AudioContext | null;
/**
* Meyda keeps an internal ScriptProcessorNode in which it runs audio feature
* extraction. The ScriptProcessorNode is stored in this member variable.
* @hidden
*/
spn: ScriptProcessorNode | null;
/**
* The length of each buffer that Meyda will extract audio on. When recieving
* input via the Web Audio API, the Script Processor Node chunks incoming audio
* into arrays of this length. Longer buffers allow for more precision in the
* frequency domain, but increase the amount of time it takes for Meyda to
* output a set of audio features for the buffer. You can calculate how many
* sets of audio features Meyda will output per second by dividing the
* buffer size by the sample rate. If you're using Meyda for visualisation,
* make sure that you're collecting audio features at a rate that's faster
* than or equal to the video frame rate you expect.
*/
bufferSize: number;
/**
* The number of samples per second of the incoming audio. This affects
* feature extraction outside of the context of the Web Audio API, and must be
* set accurately - otherwise calculations will be off.
*/
sampleRate: number;
/**
* The number of Mel bands to use in the Mel Frequency Cepstral Co-efficients
* feature extractor
*/
melBands: number;
/**
* The number of bands to divide the spectrum into for the Chroma feature
* extractor. 12 is the standard number of semitones per octave in the western
* music tradition, but Meyda can use an arbitrary number of bands, which
* can be useful for microtonal music.
*/
chromaBands: number;
/**
* A function you can provide that will be called for each buffer that Meyda
* receives from its source node
* @hidden
*/
callback: ((features: Partial<MeydaFeaturesObject>) => void | null) | null;
/**
* Specify the windowing function to apply to the buffer before the
* transformation from the time domain to the frequency domain is performed
*
* The default windowing function is the hanning window.
*/
windowingFunction: string;
featureExtractors: any;
/** @hidden */
EXTRACTION_STARTED: boolean;
/**
* The number of MFCC co-efficients that the MFCC feature extractor should return
*/
numberOfMFCCCoefficients: number;
/**
* The number of bark bands that the loudness feature extractor should return
*/
numberOfBarkBands: number;
/** @hidden */
_featuresToExtract: string[];
/**
* Apply a windowing function to a signal
*/
windowing: (signal: MeydaSignal, windowname?: MeydaWindowingFunction) => MeydaSignal;
/** @hidden */
_errors: {
[key: string]: Error;
};
/**
* @summary
* Create a MeydaAnalyzer
*
* A factory function for creating a MeydaAnalyzer, the interface for using
* Meyda in the context of Web Audio.
*
* @example
* ```javascript
* const analyzer = Meyda.createMeydaAnalyzer({
* "audioContext": audioContext,
* "source": source,
* "bufferSize": 512,
* "featureExtractors": ["rms"],
* "inputs": 2,
* "callback": features => {
* levelRangeElement.value = features.rms;
* }
* });
* ```
*/
createMeydaAnalyzer: (MeydaAnalyzerOptions: any) => MeydaAnalyzer;
/**
* List available audio feature extractors. Return format provides the key to
* be used in selecting the extractor in the extract methods
*/
listAvailableFeatureExtractors: () => MeydaAudioFeature[];
/**
* Extract an audio feature from a buffer
*
* Unless `meyda.windowingFunction` is set otherwise, `extract` will
* internally apply a hanning window to the buffer prior to conversion into
* the frequency domain.
*
* @param {(string|Array.<string>)} feature - the feature you want to extract
* @param {Array.<number>} signal
* An array of numbers that represents the signal. It should be of length
* `meyda.bufferSize`
* @param {Array.<number>} [previousSignal] - the previous buffer
* @returns {object} Features
* @example
* ```javascript
* meyda.bufferSize = 2048;
* const features = meyda.extract(['zcr', 'spectralCentroid'], signal);
* ```
*
* Aside: yes, you need to modify the value of a field of the default export
* of the package to change the buffer size. We realise this now seems not
* a good practice. See [this issue](https://github.com/meyda/meyda/issues/257)
* to track our progress on implementing a more modern API.
*/
extract: (feature: MeydaAudioFeature | MeydaAudioFeature[], signal: MeydaSignal, previousSignal?: MeydaSignal) => Partial<MeydaFeaturesObject> | null;
}
declare const Meyda: Meyda;
export default Meyda;