Exemple #1
0
        private static Bitmap DrawSpectrogram(int nfft, double[] samples, Fourier f, Color[] palette)
        {
            const int overlap      = 0;
            int       numSamples   = samples.Length;
            int       colIncrement = nfft * (1 - overlap);

            int numcols = numSamples / colIncrement;

            // make sure we don't step beyond the end of the recording
            while ((numcols - 1) * colIncrement + nfft > numSamples)
            {
                numcols--;
            }

            double[] real      = new double[nfft];
            double[] imag      = new double[nfft];
            double[] magnitude = new double[nfft / 2];
            var      bmp       = new Bitmap(numcols, nfft / 2);

            for (int col = 0; col <= numcols - 1; col++)
            {
                // read a segment of the recorded signal
                for (int c = 0; c <= nfft - 1; c++)
                {
                    imag[c] = 0;
                    real[c] = samples[col * colIncrement + c] * Fourier.Hanning(nfft, c);
                }

                // transform to the frequency domain
                f.FourierTransform(real, imag);

                // and compute the magnitude spectrum
                f.MagnitudeSpectrum(real, imag, Fourier.W0Hanning, magnitude);

                // Draw
                for (int newY = 0; newY < nfft / 2 - 1; newY++)
                {
                    int colorIndex = MapToPixelIndex(magnitude[newY], 100, 255);
                    bmp.SetPixel(col, (nfft / 2 - 1) - newY, palette[colorIndex]);
                }
            }
            return(bmp);
        }
        private static Bitmap DrawSpectrogram(int nfft, double[] samples, Fourier f, Color[] palette)
        {
            const int overlap = 0;
            int numSamples = samples.Length;
            int colIncrement = nfft * (1 - overlap);

            int numcols = numSamples / colIncrement;
            // make sure we don't step beyond the end of the recording
            while ((numcols - 1) * colIncrement + nfft > numSamples)
                numcols--;

            double[] real = new double[nfft];
            double[] imag = new double[nfft];
            double[] magnitude = new double[nfft / 2];
            var bmp = new Bitmap(numcols, nfft / 2);
            for (int col = 0; col <= numcols - 1; col++)
            {
                // read a segment of the recorded signal
                for (int c = 0; c <= nfft - 1; c++)
                {
                    imag[c] = 0;
                    real[c] = samples[col * colIncrement + c] * Fourier.Hanning(nfft, c);
                }

                // transform to the frequency domain
                f.FourierTransform(real, imag);

                // and compute the magnitude spectrum
                f.MagnitudeSpectrum(real, imag, Fourier.W0Hanning, magnitude);

                // Draw
                for (int newY = 0; newY < nfft / 2 - 1; newY++)
                {
                    int colorIndex = MapToPixelIndex(magnitude[newY], 100, 255);
                    bmp.SetPixel(col, (nfft / 2 - 1) - newY, palette[colorIndex]);
                }
            }
            return bmp;
        }
Exemple #3
0
        //////////////////////////////////////// SPECTRUM ///////////////////////////////////////////////////////////

        public List <Bitmap> GenerateFourierData(int nfft, string spectrogramDirectory, int delayInMilliseconds)
        {
            const int bitmapWidth = 1024;
            var       bitmaps     = new List <Bitmap>();

            // setup fourier transformation
            var    f       = new Fourier(nfft, true);
            double divider = 2.0;

            for (int k = 0; k < Header.BitsPerSample - 2; k++)
            {
                divider *= 2;
            }

            // determine how to read sample values
            ReadSampleDataValueDelegate readSampleDataValue = GetSampleDataRerader();

            // set up one column of the spectrogram
            var palette = new Color[nfft];

            if (Configuration.Settings.VideoControls.SpectrogramAppearance == "Classic")
            {
                for (int colorIndex = 0; colorIndex < nfft; colorIndex++)
                {
                    palette[colorIndex] = PaletteValue(colorIndex, nfft);
                }
            }
            else
            {
                var list = SmoothColors(0, 0, 0, Configuration.Settings.VideoControls.WaveformColor.R,
                                        Configuration.Settings.VideoControls.WaveformColor.G,
                                        Configuration.Settings.VideoControls.WaveformColor.B, nfft);
                for (int i = 0; i < nfft; i++)
                {
                    palette[i] = list[i];
                }
            }

            // read sample values
            DataMinValue = int.MaxValue;
            DataMaxValue = int.MinValue;
            var  samples      = new List <int>();
            int  index        = 0;
            int  sampleSize   = nfft * bitmapWidth;
            int  count        = 0;
            long totalSamples = 0;

            // write delay (if any)
            int delaySampleCount = (int)(Header.SampleRate * (delayInMilliseconds / TimeCode.BaseUnit));

            for (int i = 0; i < delaySampleCount; i++)
            {
                samples.Add(0);
                if (samples.Count == sampleSize)
                {
                    var samplesAsReal = new double[sampleSize];
                    for (int k = 0; k < sampleSize; k++)
                    {
                        samplesAsReal[k] = 0;
                    }
                    var bmp = DrawSpectrogram(nfft, samplesAsReal, f, palette);
                    bmp.Save(Path.Combine(spectrogramDirectory, count + ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
                    bitmaps.Add(bmp);
                    samples = new List <int>();
                    count++;
                }
            }

            // load data in smaller parts
            _data            = new byte[Header.BytesPerSecond];
            _stream.Position = Header.DataStartPosition;
            int bytesRead = _stream.Read(_data, 0, _data.Length);

            while (bytesRead == Header.BytesPerSecond)
            {
                while (index < Header.BytesPerSecond)
                {
                    int value = 0;
                    for (int channelNumber = 0; channelNumber < Header.NumberOfChannels; channelNumber++)
                    {
                        value += readSampleDataValue.Invoke(ref index);
                    }
                    value = value / Header.NumberOfChannels;
                    if (value < DataMinValue)
                    {
                        DataMinValue = value;
                    }
                    if (value > DataMaxValue)
                    {
                        DataMaxValue = value;
                    }
                    samples.Add(value);
                    totalSamples++;

                    if (samples.Count == sampleSize)
                    {
                        var samplesAsReal = new double[sampleSize];
                        for (int k = 0; k < sampleSize; k++)
                        {
                            samplesAsReal[k] = samples[k] / divider;
                        }
                        var bmp = DrawSpectrogram(nfft, samplesAsReal, f, palette);
                        bmp.Save(Path.Combine(spectrogramDirectory, count + ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
                        bitmaps.Add(bmp);
                        samples = new List <int>();
                        count++;
                    }
                }
                bytesRead = _stream.Read(_data, 0, _data.Length);
                index     = 0;
            }

            if (samples.Count > 0)
            {
                var samplesAsReal = new double[sampleSize];
                for (int k = 0; k < sampleSize && k < samples.Count; k++)
                {
                    samplesAsReal[k] = samples[k] / divider;
                }
                var bmp = DrawSpectrogram(nfft, samplesAsReal, f, palette);
                bmp.Save(Path.Combine(spectrogramDirectory, count + ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
                bitmaps.Add(bmp);
            }

            var doc = new XmlDocument();

            doc.LoadXml("<SpectrogramInfo><SampleDuration/><TotalDuration/><AudioFormat /><AudioFormat /><ChunkId /><SecondsPerImage /><ImageWidth /><NFFT /></SpectrogramInfo>");
            double sampleDuration = Header.LengthInSeconds / (totalSamples / Convert.ToDouble(nfft));

            doc.DocumentElement.SelectSingleNode("SampleDuration").InnerText  = sampleDuration.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("TotalDuration").InnerText   = Header.LengthInSeconds.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("AudioFormat").InnerText     = Header.AudioFormat.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("ChunkId").InnerText         = Header.ChunkId.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("SecondsPerImage").InnerText = ((double)(sampleSize / (double)Header.SampleRate)).ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("ImageWidth").InnerText      = bitmapWidth.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("NFFT").InnerText            = nfft.ToString(CultureInfo.InvariantCulture);
            doc.Save(Path.Combine(spectrogramDirectory, "Info.xml"));

            return(bitmaps);
        }
        //////////////////////////////////////// SPECTRUM ///////////////////////////////////////////////////////////
        public List<Bitmap> GenerateFourierData(int nfft, string spectrogramDirectory, int delayInMilliseconds)
        {
            const int bitmapWidth = 1024;
            var bitmaps = new List<Bitmap>();

            // setup fourier transformation
            var f = new Fourier(nfft, true);
            double divider = 2.0;
            for (int k = 0; k < Header.BitsPerSample - 2; k++)
                divider *= 2;

            // determine how to read sample values
            ReadSampleDataValueDelegate readSampleDataValue = GetSampleDataRerader();

            // set up one column of the spectrogram
            var palette = new Color[nfft];
            if (Configuration.Settings.VideoControls.SpectrogramAppearance == "Classic")
            {
                for (int colorIndex = 0; colorIndex < nfft; colorIndex++)
                    palette[colorIndex] = PaletteValue(colorIndex, nfft);
            }
            else
            {
                var list = SmoothColors(0, 0, 0, Configuration.Settings.VideoControls.WaveformColor.R,
                                                 Configuration.Settings.VideoControls.WaveformColor.G,
                                                 Configuration.Settings.VideoControls.WaveformColor.B, nfft);
                for (int i = 0; i < nfft; i++)
                    palette[i] = list[i];
            }

            // read sample values
            DataMinValue = int.MaxValue;
            DataMaxValue = int.MinValue;
            var samples = new List<int>();
            int index = 0;
            int sampleSize = nfft * bitmapWidth;
            int count = 0;
            long totalSamples = 0;

            // write delay (if any)
            int delaySampleCount = (int)(Header.SampleRate * (delayInMilliseconds / TimeCode.BaseUnit));
            for (int i = 0; i < delaySampleCount; i++)
            {
                samples.Add(0);
                if (samples.Count == sampleSize)
                {
                    var samplesAsReal = new double[sampleSize];
                    for (int k = 0; k < sampleSize; k++)
                        samplesAsReal[k] = 0;
                    var bmp = DrawSpectrogram(nfft, samplesAsReal, f, palette);
                    bmp.Save(Path.Combine(spectrogramDirectory, count + ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
                    bitmaps.Add(bmp);
                    samples = new List<int>();
                    count++;
                }
            }

            // load data in smaller parts
            _data = new byte[Header.BytesPerSecond];
            _stream.Position = Header.DataStartPosition;
            int bytesRead = _stream.Read(_data, 0, _data.Length);
            while (bytesRead == Header.BytesPerSecond)
            {
                while (index < Header.BytesPerSecond)
                {
                    int value = 0;
                    for (int channelNumber = 0; channelNumber < Header.NumberOfChannels; channelNumber++)
                    {
                        value += readSampleDataValue.Invoke(ref index);
                    }
                    value = value / Header.NumberOfChannels;
                    if (value < DataMinValue)
                        DataMinValue = value;
                    if (value > DataMaxValue)
                        DataMaxValue = value;
                    samples.Add(value);
                    totalSamples++;

                    if (samples.Count == sampleSize)
                    {
                        var samplesAsReal = new double[sampleSize];
                        for (int k = 0; k < sampleSize; k++)
                            samplesAsReal[k] = samples[k] / divider;
                        var bmp = DrawSpectrogram(nfft, samplesAsReal, f, palette);
                        bmp.Save(Path.Combine(spectrogramDirectory, count + ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
                        bitmaps.Add(bmp);
                        samples = new List<int>();
                        count++;
                    }
                }
                bytesRead = _stream.Read(_data, 0, _data.Length);
                index = 0;
            }

            if (samples.Count > 0)
            {
                var samplesAsReal = new double[sampleSize];
                for (int k = 0; k < sampleSize && k < samples.Count; k++)
                    samplesAsReal[k] = samples[k] / divider;
                var bmp = DrawSpectrogram(nfft, samplesAsReal, f, palette);
                bmp.Save(Path.Combine(spectrogramDirectory, count + ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
                bitmaps.Add(bmp);
            }

            var doc = new XmlDocument();
            doc.LoadXml("<SpectrogramInfo><SampleDuration/><TotalDuration/><AudioFormat /><AudioFormat /><ChunkId /><SecondsPerImage /><ImageWidth /><NFFT /></SpectrogramInfo>");
            double sampleDuration = Header.LengthInSeconds / (totalSamples / Convert.ToDouble(nfft));
            doc.DocumentElement.SelectSingleNode("SampleDuration").InnerText = sampleDuration.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("TotalDuration").InnerText = Header.LengthInSeconds.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("AudioFormat").InnerText = Header.AudioFormat.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("ChunkId").InnerText = Header.ChunkId.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("SecondsPerImage").InnerText = ((double)(sampleSize / (double)Header.SampleRate)).ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("ImageWidth").InnerText = bitmapWidth.ToString(CultureInfo.InvariantCulture);
            doc.DocumentElement.SelectSingleNode("NFFT").InnerText = nfft.ToString(CultureInfo.InvariantCulture);
            doc.Save(Path.Combine(spectrogramDirectory, "Info.xml"));

            return bitmaps;
        }