public void AnalyzeSignal_KnownSignal_ReturnsExpectedValues() { var audioStream = new MemoryStream(); var audioGenerator = new AudioGenerator(audioStream); var fskAudioGenerator = new FskAudioGenerator(audioGenerator); fskAudioGenerator.GenerateAudio(_binaryFskAnalyzerSettings.BaudRate, _binaryFskAnalyzerSettings.SpaceFrequency, _binaryFskAnalyzerSettings.MarkFrequency, _bitManipulator.StringToBits(Resources.LoremIpsumTestString)); var audioAnalyzer = new AudioAnalyzer(audioStream, audioGenerator); var binaryFskAnalyzer = (IBinaryFskAnalyzer) new BinaryFskAnalyzer(audioAnalyzer, new ZeroCrossingsFrequencyDetector(), _binaryFskAnalyzerSettings); var results = binaryFskAnalyzer.AnalyzeSignal(); var result = binaryFskAnalyzer.AnalyzeSignal(); var bits = new List <bool>(); foreach (var frame in result.AnalysisFrames) { if (frame.Bit.HasValue == true) { bits.Add(frame.Bit.Value); } } var ascii = BitManipulator.BitsToString(bits); Assert.AreEqual(Resources.LoremIpsumTestString, ascii); }
public AnalysisResult AnalyzeSignal(string testString = null) { var baudRateIncrementMicroseconds = 1.0 / _settings.BaudRate * Math.Pow(10, 6); var windowPositionEndMicroseconds = _audioAnalyzer.FileLengthInMicroseconds; var frequencyDifferences = new List <int>(); int numberOfZeroFrequencies = 0; var analysisFrames = new List <AnalysisFrame>(); var i = 0; for (var currentWindowPositionMicroseconds = 0.0; currentWindowPositionMicroseconds < windowPositionEndMicroseconds; currentWindowPositionMicroseconds += baudRateIncrementMicroseconds) { // Debug.WriteLine($"Current pos: {currentWindowPositionMicroseconds:N1}, increment: {baudRateIncrementMicroseconds:N1}, end: {windowPositionEndMicroseconds :N1}"); i++; var samplingResult = _audioAnalyzer.GetSamples(currentWindowPositionMicroseconds, currentWindowPositionMicroseconds + baudRateIncrementMicroseconds); // TODO: How to set this threshold? var targetNumberOfSamples = _audioAnalyzer.SampleRate / Math.Pow(10, 6) * baudRateIncrementMicroseconds; var sampleThreshold = 0.9; if (samplingResult.Samples.Count() < (targetNumberOfSamples * sampleThreshold)) { continue; } var frequency = _frequencyDetector.DetectFrequency(samplingResult.Samples); var frequencyDifference = FrequencyDifference(frequency, _settings.SpaceFrequency, _settings.MarkFrequency); var markOrSpace = MarkOrSpace(frequency, _settings.SpaceFrequency, _settings.MarkFrequency); if (frequency <= 0) { numberOfZeroFrequencies++; } if (frequencyDifference > _settings.FrequencyDeviationTolerance) { Debug.WriteLine($"WARN: @ {currentWindowPositionMicroseconds / Math.Pow(10, 6):N3} seconds (Baud rate {_settings.BaudRate}) [{i}] outside of tolerance (frequency {frequency} Hz, difference {frequencyDifference} Hz, tolerance {_settings.FrequencyDeviationTolerance} Hz)"); frequencyDifferences.Add(frequencyDifference); } // Debug.WriteLine($"[{currentWindowStart:N3} us to {currentWindowStart + currentWindowLength:N3} us ({(currentWindowStart + currentWindowLength) - currentWindowStart:N3} us)] {frequency:N0} Hz average (+/- {frequencyDifference:N0} Hz) [Want {_settings.MarkFrequency:N0} Hz / {_settings.SpaceFrequency:N0} Hz] -> bit {bits.Count}: {markOrSpace}"); analysisFrames.Add( new AnalysisFrame { Bit = (frequency > 0 && frequencyDifference <= _settings.FrequencyDeviationTolerance) ? (markOrSpace == 0 ? false : true) : (bool?)null, Frequency = frequency, DecodeFailure = frequency > _settings.FrequencyDeviationTolerance ? true : false, DifferenceFromExpectedFrequencies = frequencyDifference, TimeOffsetMicroseconds = currentWindowPositionMicroseconds } ); } var analysisResult = new AnalysisResult { AnalysisFrames = analysisFrames, NumberOfFrequencyDifferences = frequencyDifferences.Count(), NumberOfZeroFrequencies = numberOfZeroFrequencies, MinimumFrequencyDifference = frequencyDifferences.Count() > 0 ? frequencyDifferences.Min() : 0, MaximumFrequencyDifference = frequencyDifferences.Count() > 0 ? frequencyDifferences.Max() : 0, AverageFrequencyDifference = frequencyDifferences.Count() > 0 ? frequencyDifferences.Average() : 0 }; bool? match = null; string resultingString = null; if (testString != null) { var bits = new List <bool>(); analysisFrames.Where(x => x.Bit.HasValue == true).Select(x => x).ForEach(x => bits.Add(x.Bit.Value)); resultingString = BitManipulator.BitsToString(bits); match = false; if (resultingString == testString) { match = true; } } // Debug.WriteLine($"Boost freq.: {_audioAnalyzer.BoostFrequencyAmount} Hz, avg. freq. diff.: {averageFrequencyDifference}, # missed freqs.: {missedFrequencies}"); AnalysisComplete((int)_settings.BaudRate, _audioAnalyzer.BoostFrequencyAmount, analysisResult, resultingString, match); return(analysisResult); }