Skip to content
Tim Sharii edited this page Jul 29, 2019 · 2 revisions

All extension methods and classes, discussed in this document, are placed in NWaves.Utils namespace.

Memory utils

The following extension methods simply provide shorter way to call standard .NET BlockCopy() method (both for float[] and double[] arrays):

// create new array with copied samples

var copy = samples.FastCopy();


// copy array to existing array
// (in this case: copy 100 samples from the beginning of 'samples' array to 
//                'copy' array starting from position of 20th sample

samples.FastCopyTo(copy, 100, 0, 20);


// copy array to existing array
// (in this case: copy 100 samples from 10th sample in 'samples' array to 
//                'copy' array starting from its beginning

samples.FastCopyTo(copy, 100, 10);


// create new array of length 512, padded with zeros in the end
// (or as a truncated array to length 512)

var padded = samples.PadZeros(512);

There are also methods for switching between float[] and double[] arrays:

var floats = doubles.ToFloats();
var doubs = floats.ToDoubles();

Math utils

var sinc = MathUtils.Sinc(0.25);       // sinc(0.25) = sin(0.25*pi) / (0.25*pi)

var n = MathUtils.NextPowerOfTwo(512); // n = 512
var m = MathUtils.NextPowerOfTwo(257); // m = 512

var gcd = MathUtils.Gcd(60, 24);       // gcd = 12

// Modulo function that works correctly with negative numbers (as numpy.mod)
var mod = MathUtils.Mod(7, 4);         // mod = 3

// Inverse sinh(x)
var asinh = MathUtils.Asinh(x);

// Factorial
var fact = MathUtils.Factorial(5);     // 120

// Binomial coefficient C_n_k = n! / ((n-k)! k!):
var binCoeff = MathUtils.BinomialCoefficient(2, 5);  // C_5_2 = 10

// Diff signal (1st order derivative)
// 'diff' array must be not shorter than 'samples' array
MathUtils.Diff(samples, diff);

// Linear interpolation (as numpy.interp) for arg:
float[] interpolated = MathUtils.InterpolateLinear(x, y, arg);

// Bilinear transform (in-place):
MathUtils.BilinearTransform(re, im);

// Unwrap (phase)
var unwrapped = MathUtils.Unwrap(phase, tolerance: Math.PI);

// Wrap (phase)
var wrapped = MathUtils.Wrap(unwrapped, tolerance: Math.PI);

// Nth order statistics
var nth = MathUtils.FindNth(arr, n, 0, arr.Length - 1);

// Modified Bessel function of the 1st kind
// (Taylor series, OK method, but not very precise)
double b = MathUtils.I0(x);

// Method for finding complex roots of polynomials (Durand-Kerner algorithm).
// Works for polynomials of order up to approx. 45. 
// <param name="a">Polynomial coefficients</param>
Complex[] roots = MathUtils.PolynomialRoots(a);

// Evaluate polynomial
EvaluatePolynomial(coeffs, x);

// Divide polynomials:
var res = DividePolynomial(dividend, divisor);

Converting between scales

public static class Scale
{
        /// <summary>
        /// Method converts magnitude value to dB level
        /// </summary>
        /// <param name="value">Magnitude</param>
        /// <param name="valueReference">Reference magnitude</param>
        /// <returns>Decibel level</returns>
        public static double ToDecibel(double value, double valueReference = 1.0);

        /// <summary>
        /// Method converts power to dB level
        /// </summary>
        /// <param name="value">Power</param>
        /// <param name="valueReference">Reference power</param>
        /// <returns>Decibel level</returns>
        public static double ToDecibelPower(double value, double valueReference = 1.0);

        /// <summary>
        /// Method converts dB level to magnitude value
        /// </summary>
        /// <param name="level">dB level</param>
        /// <param name="valueReference">Reference magnitude</param>
        /// <returns>Magnitude value</returns>
        public static double FromDecibel(double level, double valueReference = 1.0);

        /// <summary>
        /// Method converts dB level to power
        /// </summary>
        /// <param name="level">dB level</param>
        /// <param name="valueReference">Reference power</param>
        /// <returns>Power</returns>
        public static double FromDecibelPower(double level, double valueReference = 1.0);

        /// <summary>
        /// Method converts MIDI pitch to frequency
        /// </summary>
        /// <param name="pitch">MIDI pitch</param>
        /// <returns>Frequency</returns>
        public static double PitchToFreq(int pitch);

        /// <summary>
        /// Method converts frequency to MIDI pitch
        /// </summary>
        /// <param name="freq">Frequency</param>
        /// <returns>MIDI pitch</returns>
        public static int FreqToPitch(double freq);

        /// <summary>
        /// Method converts herz frequency to corresponding mel frequency
        /// </summary>
        /// <param name="herz">Herz frequency</param>
        /// <returns>Mel frequency</returns>
        public static double HerzToMel(double herz);

        /// <summary>
        /// Method converts mel frequency to corresponding herz frequency
        /// </summary>
        /// <param name="mel">Mel frequency</param>
        /// <returns>Herz frequency</returns>
        public static double MelToHerz(double mel);

        /// <summary>
        /// Method converts herz frequency to mel frequency (suggested by M.Slaney)
        /// </summary>
        /// <param name="herz">Herz frequency</param>
        /// <returns>Mel frequency</returns>
        public static double HerzToMelSlaney(double herz);

        /// <summary>
        /// Method converts mel frequency to herz frequency (suggested by M.Slaney)
        /// </summary>
        /// <param name="mel">Mel frequency</param>
        /// <returns>Herz frequency</returns>
        public static double MelToHerzSlaney(double mel);

        /// <summary>
        /// Method converts herz frequency to corresponding bark frequency
        /// (according to Traunmüller (1990))
        /// </summary>
        /// <param name="herz">Herz frequency</param>
        /// <returns>Bark frequency</returns>
        public static double HerzToBark(double herz);

        /// <summary>
        /// Method converts bark frequency to corresponding herz frequency
        /// (according to Traunmüller (1990))
        /// </summary>
        /// <param name="bark">Bark frequency</param>
        /// <returns>Herz frequency</returns>
        public static double BarkToHerz(double bark);

        /// <summary>
        /// Method #2 converts herz frequency to corresponding bark frequency
        /// (according to Wang (1992)); used in M.Slaney's auditory toolbox
        /// </summary>
        /// <param name="herz">Herz frequency</param>
        /// <returns>Bark frequency</returns>
        public static double HerzToBarkSlaney(double herz);

        /// <summary>
        /// Method #2 converts bark frequency to corresponding herz frequency
        /// (according to Wang (1992)); used in M.Slaney's auditory toolbox
        /// </summary>
        /// <param name="bark">Bark frequency</param>
        /// <returns>Herz frequency</returns>
        public static double BarkToHerzSlaney(double bark);

        /// <summary>
        /// Method converts herz frequency to corresponding ERB frequency
        /// </summary>
        /// <param name="herz">Herz frequency</param>
        /// <returns>ERB frequency</returns>
        public static double HerzToErb(double herz);

        /// <summary>
        /// Method converts ERB frequency to corresponding herz frequency
        /// </summary>
        /// <param name="erb">ERB frequency</param>
        /// <returns>Herz frequency</returns>
        public static double ErbToHerz(double erb);

        /// <summary>
        /// Method for obtaining a perceptual loudness weight
        /// </summary>
        /// <param name="freq">Frequency</param>
        /// <param name="weightingType">Weighting type (A, B, C)</param>
        /// <returns>Weight value in dB</returns>
        public static double LoudnessWeighting(double freq, string weightingType = "A");
}
Clone this wiki locally