public static WavePeakData GenerateEmptyPeaks(string peakFileName, int totalSeconds) { int peaksPerSecond = Configuration.Settings.VideoControls.WaveformMinimumSampleRate; var peaks = new List <WavePeak> { new WavePeak(1000, -1000) }; var totalPeaks = peaksPerSecond * totalSeconds; for (int i = 0; i < totalPeaks; i++) { peaks.Add(new WavePeak(1, -1)); } peaks.Add(new WavePeak(1000, -1000)); // save results to file using (var stream = File.Create(peakFileName)) { WaveHeader.WriteHeader(stream, peaksPerSecond, 2, 16, peaks.Count); byte[] buffer = new byte[4]; foreach (var peak in peaks) { WriteValue16Bit(buffer, 0, peak.Max); WriteValue16Bit(buffer, 2, peak.Min); stream.Write(buffer, 0, 4); } } return(new WavePeakData(peaksPerSecond, peaks)); }
public static void WriteWaveformData(Stream stream, int sampleRate, List <WavePeak> peaks) { WaveHeader.WriteHeader(stream, sampleRate, 2, 16, peaks.Count); var buffer = new byte[4]; foreach (var peak in peaks) { WriteValue16Bit(buffer, 0, peak.Max); WriteValue16Bit(buffer, 2, peak.Min); stream.Write(buffer, 0, 4); } }
/// <summary> /// Generates peaks and saves them to disk. /// </summary> /// <param name="delayInMilliseconds">Delay in milliseconds (normally zero)</param> /// <param name="peakFileName">Path of the output file</param> public WavePeakData GeneratePeaks(int delayInMilliseconds, string peakFileName) { int peaksPerSecond = Math.Min(Configuration.Settings.VideoControls.WaveformMinimumSampleRate, _header.SampleRate); // ensure that peaks per second is a factor of the sample rate while (_header.SampleRate % peaksPerSecond != 0) { peaksPerSecond++; } int delaySampleCount = (int)(_header.SampleRate * (delayInMilliseconds / TimeCode.BaseUnit)); // ignore negative delays for now (pretty sure it can't happen in mkv and some places pass in -1 by mistake) delaySampleCount = Math.Max(delaySampleCount, 0); var peaks = new List <WavePeak>(); var readSampleDataValue = GetSampleDataReader(); float sampleAndChannelScale = (float)GetSampleAndChannelScale(); long fileSampleCount = _header.LengthInSamples; long fileSampleOffset = -delaySampleCount; int chunkSampleCount = _header.SampleRate / peaksPerSecond; byte[] data = new byte[chunkSampleCount * _header.BlockAlign]; float[] chunkSamples = new float[chunkSampleCount * 2]; _stream.Seek(_header.DataStartPosition, SeekOrigin.Begin); // for negative delays, skip samples at the beginning if (fileSampleOffset > 0) { _stream.Seek(fileSampleOffset * _header.BlockAlign, SeekOrigin.Current); } while (fileSampleOffset < fileSampleCount) { // calculate how many samples to skip at the beginning (for positive delays) int startSkipSampleCount = 0; if (fileSampleOffset < 0) { startSkipSampleCount = (int)Math.Min(-fileSampleOffset, chunkSampleCount); fileSampleOffset += startSkipSampleCount; } // calculate how many samples to read from the file long fileSamplesRemaining = fileSampleCount - Math.Max(fileSampleOffset, 0); int fileReadSampleCount = (int)Math.Min(fileSamplesRemaining, chunkSampleCount - startSkipSampleCount); // read samples from the file if (fileReadSampleCount > 0) { int fileReadByteCount = fileReadSampleCount * _header.BlockAlign; _stream.Read(data, 0, fileReadByteCount); fileSampleOffset += fileReadSampleCount; int chunkSampleOffset = 0; int dataByteOffset = 0; while (dataByteOffset < fileReadByteCount) { float valuePositive = 0F; float valueNegative = -0F; for (int iChannel = 0; iChannel < _header.NumberOfChannels; iChannel++) { var v = readSampleDataValue(data, ref dataByteOffset); if (v < 0) { valueNegative += v; } else { valuePositive += v; } } chunkSamples[chunkSampleOffset] = valueNegative * sampleAndChannelScale; chunkSampleOffset++; chunkSamples[chunkSampleOffset] = valuePositive * sampleAndChannelScale; chunkSampleOffset++; } } // calculate peaks peaks.Add(CalculatePeak(chunkSamples, fileReadSampleCount * 2)); } // save results to file using (var stream = File.Create(peakFileName)) { WaveHeader.WriteHeader(stream, peaksPerSecond, 2, 16, peaks.Count); byte[] buffer = new byte[4]; foreach (var peak in peaks) { WriteValue16Bit(buffer, 0, peak.Max); WriteValue16Bit(buffer, 2, peak.Min); stream.Write(buffer, 0, 4); } } return(new WavePeakData(peaksPerSecond, peaks)); }
/// <summary> /// Constructor /// </summary> /// <param name="stream">Stream of a wave file</param> public WavePeakGenerator(Stream stream) { _stream = stream; _header = new WaveHeader(_stream); }