public static IEnumerable <string> CompareFilterWindowsPhaseResponse() { const float filterFrequency = 150; const float frameSizeInS = (1f / filterFrequency) * 15; const int sampleRate = 48000; int windoSize = (int)(frameSizeInS * sampleRate); var windows = new[] { FFTWindowBuilder.Blackmann(windoSize), FFTWindowBuilder.Hamming(windoSize), FFTWindowBuilder.Hann(windoSize), FFTWindowBuilder.Door(windoSize) }; var phases = new float[windows.Length]; for (int i = 1; i < 300; i++) { var signal = SignalGenerator.Sinus(sampleRate, frameSizeInS, i, (float)(Math.PI / 2f)).ToArray(); for (int j = 0; j < windows.Length; j++) { GoertzelMag(signal, sampleRate, filterFrequency, windows[j], out phases[j]); } yield return($"{i};" + string.Join(";", phases.Select(r => r.ToString(CultureInfo.InvariantCulture)))); } }
public static IEnumerable <string> CompareResponseWithNoiseLevel() { const float filterFrequency = 150; const float frameSizeInS = 0.1f; const int sampleRate = 48000; var signal = SignalGenerator.Sinus(sampleRate, frameSizeInS, filterFrequency).ToArray(); var window = FFTWindowBuilder.Hann(signal.Length); for (int i = 0; i <= 100; i++) { var noisedSignal = signal.AddNoise(i / 100f).ToArray(); var response = GoertzelMag(noisedSignal, sampleRate, filterFrequency, window, out _); yield return($"{i};{response.ToString(CultureInfo.InvariantCulture)}"); } }
public static CTCSSDecoder Create(float tone, int sampleRate) { if (!ValidTones.Contains(tone)) { throw new ArgumentOutOfRangeException(nameof(tone), @"is not a valid CTCSS tone"); } if (sampleRate <= 0) { throw new ArgumentOutOfRangeException(nameof(sampleRate), @"value must be greater than 0"); } float binWidthInHz = CalculateBinWidthForTone(tone); float numberOfSamplesForRequiredBinWidth = sampleRate / binWidthInHz; float samplesRequiredForOnePEriod = sampleRate / tone; int frameSize = (int)Math.Round(numberOfSamplesForRequiredBinWidth + (numberOfSamplesForRequiredBinWidth % samplesRequiredForOnePEriod)); var frequenciesOfInterest = new[] { tone - binWidthInHz, tone, tone + binWidthInHz }; var lowPass = new LowPassFilter(sampleRate, tone + 10); var goertzel = Goertzel.Create(frameSize, sampleRate, FFTWindowBuilder.Hann(frameSize), lowPass.Process, frequenciesOfInterest); return(new CTCSSDecoder(goertzel, frameSize, binWidthInHz)); }