示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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;
        }
示例#4
0
        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);
        }
示例#5
0
        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)");
            }
        }