示例#1
0
        public void GenerateAllSamples()
        {
            // determine how to read sample values
            ReadSampleDataValueDelegate readSampleDataValue = GetSampleDataRerader();

            // load data
            _data            = new byte[Header.DataChunkSize];
            _stream.Position = Header.DataStartPosition;
            _stream.Read(_data, 0, _data.Length);

            // read sample values
            DataMinValue = int.MaxValue;
            DataMaxValue = int.MinValue;
            AllSamples   = new List <int>();
            int index = 0;

            while (index + Header.NumberOfChannels < Header.DataChunkSize)
            {
                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;
                }
                AllSamples.Add(value);
            }
        }
示例#2
0
        /// <summary>
        /// Generate peaks (samples with some interval) for an uncompressed wave file
        /// </summary>
        /// <param name="peaksPerSecond">Sampeles per second / sample rate</param>
        /// <param name="delayInMilliseconds">Delay in milliseconds (normally zero)</param>
        public void GeneratePeakSamples(int peaksPerSecond, int delayInMilliseconds)
        {
            PeaksPerSecond = peaksPerSecond;

            ReadSampleDataValueDelegate readSampleDataValue = GetSampleDataRerader();

            DataMinValue = int.MaxValue;
            DataMaxValue = int.MinValue;
            PeakSamples  = new List <int>();

            if (delayInMilliseconds > 0)
            {
                for (int i = 0; i < peaksPerSecond * delayInMilliseconds / 1000; i++)
                {
                    PeakSamples.Add(0);
                }
            }

            int bytesInterval = (int)Header.BytesPerSecond / PeaksPerSecond;

            _data            = new byte[Header.BytesPerSecond];
            _stream.Position = Header.DataStartPosition;
            int bytesRead = _stream.Read(_data, 0, _data.Length);

            while (bytesRead == Header.BytesPerSecond)
            {
                for (int i = 0; i < Header.BytesPerSecond; i += bytesInterval)
                {
                    int index = i;
                    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;
                    }
                    PeakSamples.Add(value);
                }
                bytesRead = _stream.Read(_data, 0, _data.Length);
            }
        }
示例#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);
        }
示例#4
0
        //////////////////////////////////////// SPECTRUM ///////////////////////////////////////////////////////////

        public List <Bitmap> GenerateFourierData(int NFFT, string spectrogramDirectory)
        {
            List <Bitmap> bitmaps = new List <Bitmap>();

            // setup fourier transformation
            Fourier 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
            Color[] 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 * 1024; // 1024 = bitmap width
            int  count        = 0;
            long totalSamples = 0;

            // 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;
                        }
                        Bitmap bmp = DrawSpectrogram(NFFT, samplesAsReal, f, palette);
                        bmp.Save(Path.Combine(spectrogramDirectory, count + ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
                        bitmaps.Add(bmp); // save serialized gif instead????
                        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;
                }
                Bitmap bmp = DrawSpectrogram(NFFT, samplesAsReal, f, palette);
                bmp.Save(Path.Combine(spectrogramDirectory, count + ".gif"), System.Drawing.Imaging.ImageFormat.Gif);
                bitmaps.Add(bmp); // save serialized gif instead????
            }

            XmlDocument doc = new XmlDocument();

            doc.LoadXml("<SpectrogramInfo><SampleDuration/><TotalDuration/></SpectrogramInfo>");
            double sampleDuration = Header.LengthInSeconds / (totalSamples / NFFT);
            double totalDuration  = Header.LengthInSeconds;

            doc.DocumentElement.SelectSingleNode("SampleDuration").InnerText = sampleDuration.ToString();
            doc.DocumentElement.SelectSingleNode("TotalDuration").InnerText  = totalDuration.ToString();
            doc.Save(System.IO.Path.Combine(spectrogramDirectory, "Info.xml"));

            return(bitmaps);
        }
示例#5
0
        //////////////////////////////////////// SPECTRUM ///////////////////////////////////////////////////////////

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

            List <Bitmap>               bitmaps             = new List <Bitmap>();
            SpectrogramDrawer           drawer              = new SpectrogramDrawer(nfft);
            ReadSampleDataValueDelegate readSampleDataValue = GetSampleDataReader();
            double sampleScale = 1.0 / (Math.Pow(2.0, Header.BitsPerSample - 1) * Header.NumberOfChannels);

            int delaySampleCount = (int)(Header.SampleRate * (delayInMilliseconds / TimeCode.BaseUnit));

            // other code (e.g. generating peaks) doesn't handle negative delays, so we'll do the same for now
            delaySampleCount = Math.Max(delaySampleCount, 0);

            long fileSampleCount  = Header.LengthInSamples;
            long fileSampleOffset = -delaySampleCount;
            int  chunkSampleCount = nfft * bitmapWidth;
            int  chunkCount       = (int)Math.Ceiling((double)(fileSampleCount + delaySampleCount) / chunkSampleCount);

            double[] chunkSamples = new double[chunkSampleCount];

            _data = new byte[chunkSampleCount * Header.BlockAlign];
            _stream.Seek(Header.DataStartPosition, SeekOrigin.Begin);

            // for negative delays, skip samples at the beginning
            if (fileSampleOffset > 0)
            {
                _stream.Seek(fileSampleOffset * Header.BlockAlign, SeekOrigin.Current);
            }

            for (int iChunk = 0; iChunk < chunkCount; iChunk++)
            {
                // calculate padding at the beginning (for positive delays)
                int startPaddingSampleCount = 0;
                if (fileSampleOffset < 0)
                {
                    startPaddingSampleCount = (int)Math.Min(-fileSampleOffset, chunkSampleCount);
                    fileSampleOffset       += startPaddingSampleCount;
                }

                // calculate how many samples to read from the file
                long fileSamplesRemaining = fileSampleCount - Math.Max(fileSampleOffset, 0);
                int  fileReadSampleCount  = (int)Math.Min(fileSamplesRemaining, chunkSampleCount - startPaddingSampleCount);

                // calculate padding at the end (when the data isn't an even multiple of our chunk size)
                int endPaddingSampleCount = chunkSampleCount - startPaddingSampleCount - fileReadSampleCount;

                int chunkSampleOffset = 0;

                // add padding at the beginning
                if (startPaddingSampleCount > 0)
                {
                    Array.Clear(chunkSamples, chunkSampleOffset, startPaddingSampleCount);
                    chunkSampleOffset += startPaddingSampleCount;
                }

                // read samples from the file
                if (fileReadSampleCount > 0)
                {
                    int fileReadByteCount = fileReadSampleCount * Header.BlockAlign;
                    _stream.Read(_data, 0, fileReadByteCount);
                    fileSampleOffset += fileReadSampleCount;

                    int dataByteOffset = 0;
                    while (dataByteOffset < fileReadByteCount)
                    {
                        int value = 0;
                        for (int iChannel = 0; iChannel < Header.NumberOfChannels; iChannel++)
                        {
                            value += readSampleDataValue(ref dataByteOffset);
                        }
                        chunkSamples[chunkSampleOffset] = value * sampleScale;
                        chunkSampleOffset += 1;
                    }
                }

                // add padding at the end
                if (endPaddingSampleCount > 0)
                {
                    Array.Clear(chunkSamples, chunkSampleOffset, endPaddingSampleCount);
                    chunkSampleOffset += endPaddingSampleCount;
                }

                // generate spectrogram for this chunk
                Bitmap bmp = drawer.Draw(chunkSamples);
                bmp.Save(Path.Combine(spectrogramDirectory, iChunk + ".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>");
            doc.DocumentElement.SelectSingleNode("SampleDuration").InnerText  = ((double)nfft / Header.SampleRate).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)chunkSampleCount / 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);
        }