/// <summary> /// Calculates the modal noise value for each freq bin. /// Does so using a series of overlapped matrices. /// TODO!!!! COULD SIMPLY THIS METHOD. JUST CALCULATE MODE FOR EACH FREQ BIN WITHOUT OVERLAP .... /// .... AND THEN APPLY MORE SEVERE SMOOTHING TO THE MODAL NOISE PROFILE IN PREVIOUS METHOD. /// /// COMPARE THIS METHOD WITH SNR.SubtractModalNoise(). /// </summary> /// <param name="matrix">Audio sample matrix.</param> /// <returns>Modal noise values.</returns> private static double[] CalculateModalNoise(double[,] matrix) { //set parameters for noise histograms based on overlapping bands. //******************************************************************************************************************* int bandWidth = 3; // should be an odd number int binCount = 64; // number of pixel intensity bins double upperLimitForMode = 0.666; // sets upper limit to modal noise bin. Higher values = more severe noise removal. int binLimit = (int)(binCount * upperLimitForMode); //******************************************************************************************************************* DoubleSquareArrayExtensions.MinMax(matrix, out var minIntensity, out var maxIntensity); double binWidth = (maxIntensity - minIntensity) / binCount; // width of an intensity bin // LoggedConsole.WriteLine("minIntensity=" + minIntensity + " maxIntensity=" + maxIntensity + " binWidth=" + binWidth); int rowCount = matrix.GetLength(0); int colCount = matrix.GetLength(1); if (bandWidth > colCount) { bandWidth = colCount - 1; } int halfWidth = bandWidth / 2; // init matrix from which histogram derived double[,] submatrix = Submatrix(matrix, 0, 0, rowCount - 1, bandWidth); double[] modalNoise = new double[colCount]; // for all cols i.e. freq bins for (int col = 0; col < colCount; col++) { // construct new submatrix to calculate modal noise int start = col - halfWidth; //extend range of submatrix below col for smoother changes if (start < 0) { start = 0; } int stop = col + halfWidth; if (stop >= colCount) { stop = colCount - 1; } submatrix = Submatrix(matrix, 0, start, rowCount - 1, stop); int[] histo = Histo(submatrix, binCount, minIntensity, maxIntensity, binWidth); //DataTools.writeBarGraph(histo); double[] smoothHisto = FilterMovingAverage(histo, 7); GetMaxIndex(smoothHisto, out var maxindex); //this is mode of histogram if (maxindex > binLimit) { maxindex = binLimit; } modalNoise[col] = minIntensity + (maxindex * binWidth); //LoggedConsole.WriteLine(" modal index=" + maxindex + " modalIntensity=" + modalIntensity.ToString("F3")); } return(modalNoise); }