UNPKG

audio-2.0.0

Version:

Class for high-level audio manipulations

122 lines (85 loc) 2.62 kB
/** * Extend audio with playback functionality * * @module audio/src/metrics */ 'use strict' const ft = require('fourier-transform') //TODO: make external package const loudness = { rms: require('compute-qmean') } let {parseArgs} = require('./util') let Audio = require('../') //get amplitudes range for the interval Audio.prototype.limits = function (time, duration, options) { options = parseArgs(this, time, duration, options) if (this.stats) { //TODO: implement fast bounds search, extremum-based } let max = -1, min = 1 //search across channels this.buffer.map((buf, idx, offset) => { for (let c = 0, l = buf.length; c < options.channels.length; c++) { let channel = options.channels[c] let data = buf.getChannelData(channel) for (let i = 0; i < l; i++) { if (data[i] > max) max = data[i] if (data[i] < min) min = data[i] } } }, options.start, options.end) return [min, max] } Audio.prototype.spectrum = function (start, options) { if (typeof start !== 'number') { options = start } options = options || {} start = start || 0 if (!options.size) options.size = 1024; if (!bit.isPow2(options.size)) throw Error('Size must be a power of 2') if (options.channel == null) options.channel = 0; let buf = this.readRaw(start * this.buffer.sampleRate, options.size); let waveform = buf.getChannelData(options.channel); let magnitudes = ft(waveform); if (options.db) { magnitudes = magnitudes.map(value => db.fromGain(value)) } return magnitudes; } Audio.prototype.cepstrum = function () { } Audio.prototype.stats = function () { } //calculate loudness by provided method/interval Audio.prototype.loudness = function (time, duration, options) { if (typeof options === 'string') options = {method: options} options = parseArgs(this, time, duration, options) if (options.type) options.method = options.type let calc = loudness[options.method] || loudness.rms let result = [] let mean2 = [] if (this.stats) { for (let c = 0; c < options.channels.length; c++) { let channel = options.channels[c] mean2.push(this.stats.mean2[channel]) } } else { //TODO: compute-qmean has faster rms calculation, utilize it's method for (let c = 0; c < options.channels.length; c++) { let channel = options.channels[c] let data = this.getChannelData(channel, options.from, options.duration) let sum2 = 0 for (let i = 0, l = data.length; i < l; i++) { // sum2 += } // result.push(val) } } return options.channels.length === 1 ? result[0] : result } Audio.prototype.size = function size () { return this; }