コード例 #1
0
        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))));
            }
        }
コード例 #2
0
        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)}");
            }
        }
コード例 #3
0
        public static IEnumerable <string> CompareFrameSizes()
        {
            const float filterFrequency = 150;
            var         frameSizesInS   = new float[] { 0.1f, 0.5f };
            var         sampleRate      = 48000;
            var         hammings        = frameSizesInS.Select(fs => FFTWindowBuilder.Hamming((int)(fs * sampleRate))).ToArray();
            var         responses       = new float[frameSizesInS.Length];

            for (int i = 1; i < 300; i++)
            {
                for (int j = 0; j < frameSizesInS.Length; j++)
                {
                    var signal = SignalGenerator.Sinus(sampleRate, frameSizesInS[j], i).ToArray();
                    responses[j] = GoertzelMag(signal, sampleRate, filterFrequency, hammings[j], out _);
                }

                yield return($"{i};" + string.Join(";", responses.Select(r => r.ToString(CultureInfo.InvariantCulture))));
            }
        }
コード例 #4
0
        public static IEnumerable <string> CompareSamplingRates()
        {
            const float filterFrequency = 150;
            const float frameSizeInS    = 0.1f;
            var         sampleRates     = new[] { 600, 8000, 48000 };
            var         hammings        = sampleRates.Select(sr => FFTWindowBuilder.Hamming((int)(sr * frameSizeInS))).ToArray();
            var         responses       = new float[sampleRates.Length];

            for (int i = 1; i < 300; i++)
            {
                for (int j = 0; j < sampleRates.Length; j++)
                {
                    var signal = SignalGenerator.Sinus(sampleRates[j], frameSizeInS, i).ToArray();
                    responses[j] = GoertzelMag(signal, sampleRates[j], filterFrequency, hammings[j], out _);
                }

                yield return($"{i};" + string.Join(";", responses.Select(r => r.ToString(CultureInfo.InvariantCulture))));
            }
        }
コード例 #5
0
        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));
        }