public static int Results(float[] fftOutput, float[] result, float decibelOffset) { float max = float.MinValue; int peak = -1; int y = 0; for (int x = 0; x < fftOutput.Length; x += 2) { // calculate magnitude of a FFT bin (L2 norm) // divide magnitudes by FFT input length (so that they aren't dependent in the input length) // multiply by 2 since the FFT result only contains half of the energy (the second half are the negative frequencies of the "full" FFT result) // calculate dB scale value // http://www.mathworks.de/support/tech-notes/1700/1702.html result[y] = (float)VolumeUtil.LinearToDecibel( CalculateMagnitude(fftOutput[x], fftOutput[x + 1]) / fftOutput.Length * 2) + decibelOffset; if (result[y] > max) { max = result[y]; peak = y; } if (float.IsNegativeInfinity(result[y])) { result[y] = float.MinValue; } y++; } return(peak); }
/// <summary> /// Normalizes the vertical-axis scale of a FFT result and transforms it to a logarithmic dB /// scale for a better visualization. The resulting dB values aren't absolute, but relative to the /// main peak (highest peak). /// See: Windowing Functions Improve FFT Results, Part II (http://www.tmworld.com/article/325630-Windowing_Functions_Improve_FFT_Results_Part_II.php) /// </summary> /// <param name="fftOutput">the output of a FFT function (interleaved complex numbers)</param> /// <param name="normalizedResult">the normalized result for visualization</param> public static void NormalizeResults(float[] fftOutput, float[] normalizedResult) { float max = float.MinValue; int y = 0; for (int x = 0; x < fftOutput.Length; x += 2) { // calculate magnitude of a FFT bin (L2 norm) normalizedResult[y] = CalculateMagnitude(fftOutput[x], fftOutput[x + 1]); // find out max value for normalization if (normalizedResult[y] > max) { max = normalizedResult[y]; } y++; } for (int x = 0; x < normalizedResult.Length; x++) { // normalize by max value & calculate dB scale value normalizedResult[x] = (float)VolumeUtil.LinearToDecibel(normalizedResult[x] / max); } }