/*
* This file is part of Toolkit.
*
* Toolkit 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.
*
* Toolkit 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
* Lesser 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
*/
"use strict";
/**
* TK.AudioMath provides a couple of functions for turning
* linear values into logarithmic ones and vice versa. If you need
* an easy convertion between dB or Hz and a linear scale mixin
* this class.
*
* @mixin TK.AudioMath
*/
TK.AudioMath = (function() {
var exp = Math.exp;
var log = Math.log;
var pow = Math.pow;
var MAX = Math.max;
var LN2 = Math.LN2;
var LN10 = Math.LN10;
function log2(value) {
value = +value;
return +log(value) / LN2;
}
function log10(value) {
value = +value;
return +log(value) / LN10;
}
function db2gain(value, factor) {
/**
* Calculates 10^(value / factor).
* Transforms a dBFS value to the corresponding gain.
*
* @function TK.AudioMath#db2gain
*
* @param {number} value - A decibel value in dBFS.
* @param {number} [factor=20] - The factor.
*/
value = +value;
factor = +factor;
if (!(factor >= 0.0)) factor = 20.0;
value = +(value / factor);
value = +pow(10.0, value);
return value;
}
function gain2db(value, factor) {
/**
* Calculates factor * log10(value).
* Transforms a gain value to the corresponding dBFS value.
*
* @function TK.AudioMath#gain2db
*
* @param {number} value - A gain factor.
* @param {number} [factor=20] - The factor.
*/
value = +value;
factor = +factor;
if (!(factor >= 0.0)) factor = 20.0;
value = factor * +log10(value);
return value;
}
function db2coef(value, min, max, reverse, factor) {
/**
* Calculates a linear value between 0.0 and 1.0
* from a value and its lower and upper boundaries in decibels.
*
* @function TK.AudioMath#db2coef
*
* @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).
*/
value = +value;
min = +min;
max = +max;
reverse = reverse|0;
factor = +factor;
var 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;
}
function coef2db(coef, min, max, reverse, factor) {
/**
* Calculates a value in decibels from a value
* between 0.0 and 1.0 and some lower and upper boundaries in decibels.
*
* @function TK.AudioMath#coef2db
*
* @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.
*/
coef = +coef;
min = +min;
max = +max;
reverse = reverse|0;
factor = +factor;
var 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;
}
function db2scale(value, min, max, scale, reverse, factor) {
/**
* Calculates a linear value between 0.0 and scale.
* from a value and its lower and upper boundaries in decibels.
*
* @function TK.AudioMath#db2scale
*
* @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.
*/
value = +value;
min = +min;
max = +max;
scale = +scale;
reverse = reverse|0;
factor = +factor;
var 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;
}
function scale2db(value, min, max, scale, reverse, factor) {
/**
* Calculates a value in decibels from a value
* between 0.0 and scale and some lower and upper boundaries in decibels.
*
* @function TK.AudioMath#scale2db
*
* @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.
*/
value = +value;
min = +min;
max = +max;
scale = +scale;
reverse = reverse|0;
factor = +factor;
var 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;
}
function freq2coef(value, min, max, reverse/*, prescaled, factor*/) {
/**
* Calculates a linear value between 0.0 and 1.0
* from a value and its lower and upper boundaries in hertz.
*
* @function TK.AudioMath#freq2coef
*
* @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).
*/
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;
}
function coef2freq(coef, min, max, reverse) {
/**
* Calculates a value in hertz from a value
* between 0.0 and 1.0 and some lower and upper boundaries in hertz.
*
* @function TK.AudioMath#coef2freq
*
* @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.
*/
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;
}
function freq2scale(value, min, max, scale, reverse) {
/**
* Calculates a linear value between 0.0 and scale
* from a value and its lower and upper boundaries in hertz.
*
* @function TK.AudioMath#freq2scale
*
* @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.
*/
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;
}
function scale2freq(value, min, max, scale, reverse) {
/**
* Calculates a value in hertz from a value
* between 0.0 and scale and some lower and upper boundaries in hertz.
*
* @function TK.AudioMath#scale2freq
*
* @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.
*/
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;
}
return {
// DECIBEL CALCULATIONS
db2coef: db2coef,
coef2db: coef2db,
db2scale: db2scale,
scale2db: scale2db,
gain2db: gain2db,
db2gain: db2gain,
// FREQUENCY CALCULATIONS
freq2coef: freq2coef,
coef2freq: coef2freq,
freq2scale: freq2scale,
scale2freq: scale2freq
}
})();