public void AddFrameInfo(Mp3FrameInfo frameInfo) { if (_buffer == null) { _buffer = new Queue <Mp3FrameInfo>(); var frame = frameInfo.Frame; var samplesPerMillisecond = (double)frame.SampleRate / (double)1000; var numSamples = _duration * samplesPerMillisecond; _durationInFrames = Math.Ceiling(numSamples / frame.SampleCount); } if (IsFull()) { _buffer.Dequeue(); var v = _volumes.Dequeue(); _totalVolume -= v; } _buffer.Enqueue(frameInfo); var frameVolume = frameInfo.AverageVolume; _volumes.Enqueue(frameVolume); _totalVolume += frameVolume; _averageVolume = _totalVolume / _volumes.Count; if (_greaterThan) { if (_averageVolume >= _volumeLevel && IsFull()) { _isSet = true; } } else { if (_averageVolume <= _volumeLevel && IsFull()) { _isSet = true; } } }
public void ProcessFrames(IEnumerable <Mp3Frame> frames) { var decompressedData = new byte[1024 * 16]; var bytesDecompressed = 0; var samples = new float[1024 * 4]; var currentTrigger = _startTrigger; var isRecording = false; Stream outputFile = null; string outputFileName = string.Empty; string fullOutputFileName = string.Empty; foreach (var frame in frames) { // find the average volume for the samples in this frame. bytesDecompressed = DecompressFrame(frame, decompressedData); // convert samples to wave _waveProvider.AddSamples(decompressedData, 0, bytesDecompressed); var samplesRead = _sampleProvider.Read(samples, 0, _waveProvider.BufferedBytes); // find average of samples var average = GetSamplesAverage(samples, samplesRead); var frameInfo = new Mp3FrameInfo(frame, average); currentTrigger.AddFrameInfo(frameInfo); if (currentTrigger.IsSet()) { // we need to switch state if (isRecording) { // the end recording trigger was set isRecording = false; _buffer.Clear(); _startTrigger.Clear(); currentTrigger = _startTrigger; outputFile.Flush(); outputFile.Close(); } else { // the start recording trigger was set isRecording = true; _endTrigger.Clear(); currentTrigger = _endTrigger; if (!_buffer.IsFull && !string.IsNullOrEmpty(outputFileName)) { // since we had a previous file and the buffer isn't full yet we'll just append // this recording to the previous one. outputFile = File.OpenWrite(fullOutputFileName); Console.WriteLine($"Appneding clip {outputFileName}"); // the trigger frames should be contained in the buffer along with any // frames since the previous recording stopped. foreach (var fi in _buffer.GetFrames()) { var d = fi.Frame.RawData; outputFile.Write(d, 0, d.Length); } } else { var fileTime = DateTime.Now; outputFileName = fileTime.ToString("yyyy.MM.dd.THH.mm.ss.ffffff") + ".mp3"; fullOutputFileName = Path.Combine(GetFilePath(fileTime), outputFileName); outputFile = File.OpenWrite(fullOutputFileName); Console.WriteLine($"Writing clip {outputFileName}"); // We want to put the frames from the trigger into the output foreach (var fi in _startTrigger.GetFrames()) { var d = fi.Frame.RawData; outputFile.Write(d, 0, d.Length); } } } } if (!isRecording) { _buffer.Enqueue(frameInfo); } else { // write the frame to the file. var data = frameInfo.Frame.RawData; outputFile.Write(data, 0, data.Length); } } }