/*
* This file is part of AUX.
*
* AUX is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* AUX 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 GNU General
* Public License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
/* jshint -W018 */
/**
* AudioMath provides transformations commonly used when handling
* audio related units.
*
* @module utils/audiomath
*/
const log = Math.log;
const pow = Math.pow;
const MAX = Math.max;
const LN2 = Math.LN2;
const LN10 = Math.LN10;
function log2(value) {
value = +value;
return +log(value) / LN2;
}
function log10(value) {
value = +value;
return +log(value) / LN10;
}
/**
* Calculates 10^(value / factor).
* Transforms a dBFS value to the corresponding gain.
*
* @function dBToGain
*
* @param {number} value - A decibel value in dBFS.
* @param {number} [factor=20] - The factor.
*/
export function dBToGain(value, factor) {
value = +value;
factor = +factor;
if (!(factor >= 0.0)) factor = 20.0;
value = +(value / factor);
value = +pow(10.0, value);
return value;
}
/**
* Calculates factor * log10(value).
* Transforms a gain value to the corresponding dBFS value.
*
* @function gainToDB
*
* @param {number} value - A gain factor.
* @param {number} [factor=20] - The factor.
*/
export function gainToDB(value, factor) {
value = +value;
factor = +factor;
if (!(factor >= 0.0)) factor = 20.0;
value = factor * +log10(value);
return value;
}
/**
* Calculates a linear value between 0.0 and 1.0
* from a value and its lower and upper boundaries in decibels.
*
* @function dBToCoef
*
* @param {number} value - The value in decibels.
* @param {number} min - The minimum value in decibels.
* @param {number} max - The maximum value in decibels.
* @param {boolean} reverse - If the scale is reversed.
* @param {number} factor - Changes the deflection of the logarithm if other than 1.0.
*
* @returns {number} A value between 0.0 (min) and 1.0 (max).
*/
export function dBToCoef(value, min, max, reverse, factor) {
value = +value;
min = +min;
max = +max;
reverse = reverse | 0;
factor = +factor;
let logfac = 1.0;
if (factor === 0.0) factor = 1.0;
else logfac = +MAX(1.0, +pow(2.0, factor) - 1.0);
if (reverse) value = max - (value - min);
value = +log2(1.0 + ((value - min) / (max - min)) * logfac) / factor;
if (reverse) value = -value + 1.0;
return value;
}
/**
* Calculates a value in decibels from a value
* between 0.0 and 1.0 and some lower and upper boundaries in decibels.
*
* @function coefToDB
*
* @param {number} coef - A value between 0.0 and 1.0.
* @param {number} min - The minimum value in decibels.
* @param {number} max - The maximum value in decibels.
* @param {boolean} reverse - If the scale is reversed.
* @param {number} factor - Changes the deflection of the logarithm if other than 1.0.
*
* @returns {number} The result in decibels.
*/
export function coefToDB(coef, min, max, reverse, factor) {
coef = +coef;
min = +min;
max = +max;
reverse = reverse | 0;
factor = +factor;
let logfac = 1.0;
if (factor === 0.0) factor = 1.0;
else logfac = +MAX(1.0, +pow(2.0, factor) - 1.0);
if (reverse) coef = -coef + 1.0;
coef = ((+pow(2.0, coef * factor) - 1.0) / logfac) * (max - min) + min;
if (reverse) coef = max - coef + min;
return coef;
}
/**
* Calculates a linear value between 0.0 and scale.
* from a value and its lower and upper boundaries in decibels.
*
* @function dBToScale
*
* @param {number} value - The value in decibels.
* @param {number} min - The minimum value in decibels.
* @param {number} max - The maximum value in decibels.
* @param {boolean} reverse - If the scale is reversed.
* @param {number} factor - Changes the deflection of the logarithm if other than 1.0.
*
* @returns {number} A value between 0.0 and scale.
*/
export function dBToScale(value, min, max, scale, reverse, factor) {
value = +value;
min = +min;
max = +max;
scale = +scale;
reverse = reverse | 0;
factor = +factor;
let logfac = 1.0;
if (factor === 0.0) factor = 1.0;
else logfac = +MAX(1.0, +pow(2.0, factor) - 1.0);
if (reverse) value = max - (value - min);
value = +log2(1.0 + ((value - min) / (max - min)) * logfac) / factor;
if (reverse) value = -value + 1.0;
return value * scale;
}
/**
* Calculates a value in decibels from a value
* between 0.0 and scale and some lower and upper boundaries in decibels.
*
* @function scaleToDB
*
* @param {number} value - A value between 0.0 and scale.
* @param {number} min - The minimum value in decibels.
* @param {number} max - The maximum value in decibels.
* @param {boolean} reverse - If the scale is reversed.
* @param {number} factor - Changes the deflection of the logarithm if other than 1.0.
*
* @returns {number} The result in decibels.
*/
export function scaleToDB(value, min, max, scale, reverse, factor) {
value = +value;
min = +min;
max = +max;
scale = +scale;
reverse = reverse | 0;
factor = +factor;
let logfac = 1.0;
if (factor === 0.0) factor = 1.0;
else logfac = +MAX(1.0, +pow(2.0, factor) - 1.0);
value = value / scale;
if (reverse) value = -value + 1.0;
value = ((+pow(2.0, value * factor) - 1.0) / logfac) * (max - min) + min;
if (reverse) value = max - value + min;
return value;
}
/**
* Calculates a linear value between 0.0 and 1.0
* from a value and its lower and upper boundaries in hertz.
*
* @function freqToCoef
*
* @param {number} value - The value in hertz.
* @param {number} min - The minimum value in hertz.
* @param {number} max - The maximum value in hertz.
* @param {boolean} reverse - If the scale is reversed.
*
* @returns {number} A value between 0.0 (min) and 1.0 (max).
*/
export function freqToCoef(value, min, max, reverse /*, prescaled, factor*/) {
value = +value;
min = +min;
max = +max;
reverse = reverse | 0;
// FIXME: unused
if (reverse) value = max - (value - min);
min = +log10(min);
max = +log10(max);
value = (+log10(value) - min) / (max - min);
if (reverse) value = -value + 1.0;
return value;
}
/**
* Calculates a value in hertz from a value
* between 0.0 and 1.0 and some lower and upper boundaries in hertz.
*
* @function coefToFreq
*
* @param {number} coef - A value between 0.0 and 1.0.
* @param {number} min - The minimum value in hertz.
* @param {number} max - The maximum value in hertz.
* @param {boolean} reverse - If the scale is reversed.
* @param {number} factor - Changes the deflection of the logarithm if other than 1.0.
*
* @returns {number} The result in hertz.
*/
export function coefToFreq(coef, min, max, reverse) {
coef = +coef;
min = +min;
max = +max;
reverse = reverse | 0;
if (reverse) coef = -coef + 1.0;
min = +log10(min);
max = +log10(max);
coef = +pow(10.0, coef * (max - min) + min);
if (reverse) coef = max - coef + min;
return coef;
}
/**
* Calculates a linear value between 0.0 and scale
* from a value and its lower and upper boundaries in hertz.
*
* @function freqToScale
*
* @param {number} value - The value in hertz.
* @param {number} min - The minimum value in hertz.
* @param {number} max - The maximum value in hertz.
* @param {boolean} reverse - If the scale is reversed.
*
* @returns {number} A value between 0.0 and scale.
*/
export function freqToScale(value, min, max, scale, reverse) {
value = +value;
min = +min;
max = +max;
scale = +scale;
reverse = reverse | 0;
if (reverse) value = max - (value - min);
min = +log10(min);
max = +log10(max);
value = (+log10(value) - min) / (max - min);
if (reverse) value = -value + 1.0;
return value * scale;
}
/**
* Calculates a value in hertz from a value
* between 0.0 and scale and some lower and upper boundaries in hertz.
*
* @function scaleToFreq
*
* @param {number} value - A value between 0.0 and scale.
* @param {number} min - The minimum value in hertz.
* @param {number} max - The maximum value in hertz.
* @param {boolean} reverse - If the scale is reversed.
* @param {number} factor - Changes the deflection of the logarithm if other than 1.0.
*
* @returns {number} The result in hertz.
*/
export function scaleToFreq(value, min, max, scale, reverse) {
value = +value;
min = +min;
max = +max;
scale = +scale;
reverse = reverse | 0;
value = value / scale;
if (reverse) value = -value + 1.0;
min = +log10(min);
max = +log10(max);
value = pow(10.0, value * (max - min) + min);
if (reverse) value = max - value + min;
return value;
}