public void Test_SFF_Mel() { (double[] audio, int sampleRate) = AudioFile.ReadWAV("../../../../../data/cant-do-that-44100.wav"); int fftSize = 1 << 12; var spec = new SpectrogramGenerator(sampleRate, fftSize, stepSize: 700); var window = new FftSharp.Windows.Hanning(); spec.SetWindow(window.Create(fftSize / 3)); // sharper window than typical spec.Add(audio); Bitmap bmp = spec.GetBitmapMel(250); bmp.Save("../../../../../dev/sff/halMel.png", System.Drawing.Imaging.ImageFormat.Png); spec.SaveData("../../../../../dev/sff/halMel.sff", melBinCount: 250); var spec2 = new SFF("../../../../../dev/sff/halMel.sff"); Assert.AreEqual(spec.SampleRate, spec2.SampleRate); Assert.AreEqual(spec.StepSize, spec2.StepSize); Assert.AreEqual(spec.Width, spec2.Width); Assert.AreEqual(spec.FftSize, spec2.FftSize); Assert.AreEqual(spec.NextColumnIndex, spec2.FftFirstIndex); Assert.AreEqual(spec.Height, spec2.Height); Assert.AreEqual(spec.OffsetHz, spec2.OffsetHz); }
private double[] SubtractMovingWindow(double[] input, int windowSizePx = 100) { // return a copy of the input array with the moving window subtracted var hanningWindow = new FftSharp.Windows.Hanning(); double[] window = hanningWindow.Create(windowSizePx); double windowSum = window.Sum(); double[] windowed = new double[input.Length]; double[] normalized = new double[input.Length]; for (int i = 0; i < input.Length - window.Length; i++) { double windowedInputSum = 0; for (int j = 0; j < window.Length; j++) { windowedInputSum += input[i + j] * window[j]; } windowed[i + window.Length / 2] = windowedInputSum / windowSum; } for (int i = 0; i < input.Length; i++) { normalized[i] = Math.Max(input[i] - windowed[i], 0); } return(normalized); }
public Settings(int sampleRate, int fftSize, int stepSize, double minFreq, double maxFreq, int offsetHz) { if (FftSharp.Transform.IsPowerOfTwo(fftSize) == false) { throw new ArgumentException("FFT size must be a power of 2"); } // FFT info SampleRate = sampleRate; FftSize = fftSize; StepSize = stepSize; FftLengthSec = (double)fftSize / sampleRate; // vertical minFreq = Math.Max(minFreq, 0); FreqNyquist = sampleRate / 2; HzPerPixel = (double)sampleRate / fftSize; PxPerHz = (double)fftSize / sampleRate; FftIndex1 = (minFreq == 0) ? 0 : (int)(minFreq / HzPerPixel); FftIndex2 = (maxFreq >= FreqNyquist) ? fftSize / 2 : (int)(maxFreq / HzPerPixel); Height = FftIndex2 - FftIndex1; FreqMin = FftIndex1 * HzPerPixel; FreqMax = FftIndex2 * HzPerPixel; FreqSpan = FreqMax - FreqMin; OffsetHz = offsetHz; // horizontal StepLengthSec = (double)StepSize / sampleRate; var window = new FftSharp.Windows.Hanning(); Window = window.Create(fftSize); StepOverlapSec = FftLengthSec - StepLengthSec; StepOverlapFrac = StepOverlapSec / FftLengthSec; }
public void Test_SFF_Linear() { (double[] audio, int sampleRate) = AudioFile.ReadWAV("../../../../../data/cant-do-that-44100.wav"); int fftSize = 1 << 12; var spec = new SpectrogramGenerator(sampleRate, fftSize, stepSize: 700, maxFreq: 2000); var window = new FftSharp.Windows.Hanning(); spec.SetWindow(window.Create(fftSize / 3)); // sharper window than typical spec.Add(audio); spec.SaveData("../../../../../dev/sff/hal.sff"); var spec2 = new SFF("../../../../../dev/sff/hal.sff"); Assert.AreEqual(spec.SampleRate, spec2.SampleRate); Assert.AreEqual(spec.StepSize, spec2.StepSize); Assert.AreEqual(spec.Width, spec2.Width); Assert.AreEqual(spec.FftSize, spec2.FftSize); Assert.AreEqual(spec.NextColumnIndex, spec2.FftFirstIndex); Assert.AreEqual(spec.Height, spec2.Height); Assert.AreEqual(spec.OffsetHz, spec2.OffsetHz); }
public void Test_Make_CommonColormaps() { (double[] audio, int sampleRate) = AudioFile.ReadWAV("../../../../../data/cant-do-that-44100.wav"); int fftSize = 1 << 12; var spec = new SpectrogramGenerator(sampleRate, fftSize, stepSize: 700, maxFreq: 2000); var window = new FftSharp.Windows.Hanning(); spec.SetWindow(window.Create(fftSize / 3)); // sharper window than typical spec.Add(audio); // delete old colormap files foreach (var filePath in System.IO.Directory.GetFiles("../../../../../dev/graphics/", "hal-*.png")) { System.IO.File.Delete(filePath); } foreach (var cmap in Colormap.GetColormaps()) { spec.Colormap = cmap; spec.SaveImage($"../../../../../dev/graphics/hal-{cmap.Name}.png"); Debug.WriteLine($"![](dev/graphics/hal-{cmap.Name}.png)"); } }