Ejemplo n.º 1
0
        public static void Main(string[] args)
        {
            const int   sampleRate = 48000;
            const float tone       = 69.3f;

            var decoder = CTCSSDecoder.Create(tone, sampleRate);

            using (var udpClient = new UdpClient(7355))
            {
                var buffer      = new CircularBuffer.CircularBuffer <float>(decoder.FrameSize, new float[0]);
                var ctcssPrev   = false;
                int debounce    = 0;
                int debounceMax = 3;
                var slicer      = new Slicer <float>(48000 / 50);
                var sw          = System.Diagnostics.Stopwatch.StartNew();
                while (true)
                {
                    IPEndPoint recievedFrom = new IPEndPoint(IPAddress.Any, 0);
                    var        data         = udpClient.Receive(ref recievedFrom);
                    //Console.WriteLine(data.Length);
                    foreach (var slice in slicer.GetSlices(ToFloats(data)))
                    {
                        foreach (var sample in slice)
                        {
                            buffer.PushBack(sample);
                        }

                        if (!buffer.IsFull)
                        {
                            continue;
                        }

                        var ctcss = decoder.HasCTCSS(buffer.ToArray(), out var level, out var ratio);
                        if (ctcss)
                        {
                            debounce = Math.Min(debounce + 1, debounceMax);
                        }
                        else
                        {
                            debounce = Math.Max(debounce - 1, 0);
                        }

                        Console.Clear();
                        Console.WriteLine($"{debounce >= debounceMax} {level} {ratio}");
                    }
                }
            }

            //int positive = 0;
            //int negative = 0;
            //var noiseThreshold = 0f;
            //for (int i = 0; i < 100; i++)
            //{
            //    var noise = i / 100f;
            //    var signal = SignalGenerator.Sinus(sampleRate, decoder.FrameSize, 67)
            //    .Select(f => f * 0.15f)
            //    .AddNoise(noise).ToArray();

            //    if (decoder.HasCTCSS(signal))
            //    {
            //        positive++;
            //        if(negative == 0)
            //             noiseThreshold = noise;
            //    }
            //    else
            //    {
            //        negative++;
            //    }

            //    Console.Clear();
            //    Console.WriteLine($"Positive {positive}");
            //    Console.WriteLine($"Negative {negative}");
            //}

            //Console.WriteLine(noiseThreshold);



            //float frequencyOfInterest = 67;
            //float binWidthInHz = 4f;
            //float numberOfSamplesForRequiredBinWidth = sampleRate / binWidthInHz;
            //float samplesRequiredForOnePEriod = sampleRate / frequencyOfInterest;
            //int framesSize = (int)Math.Round(numberOfSamplesForRequiredBinWidth + (numberOfSamplesForRequiredBinWidth % samplesRequiredForOnePEriod));

            //var signal = SignalGenerator.Sinus(sampleRate, framesSize, 69.3f).Select(f => f * 0.15f)/*.AddNoise(0.9f)*/.ToArray();
            //var frequenciesOfInterest = new[] { frequencyOfInterest - binWidthInHz, frequencyOfInterest, frequencyOfInterest + binWidthInHz };

            //var goertzel = Goertzel.Create(signal.Length, sampleRate, FFTWindowBuilder.Hann(signal.Length), frequenciesOfInterest);
            //var responses = goertzel.Evaluate(signal).ToArray();

            //foreach (var response in responses)
            //{
            //    Console.WriteLine(response);
            //}

            //Console.WriteLine("=============================");

            //var bla = (responses[0] + responses[2]) / 2f;
            //bla = responses[1] / bla;
            //Console.WriteLine(bla);

            //var file = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/test.csv";

            //if (File.Exists(file))
            //    File.Delete(file);

            //File.WriteAllLines(file, CompareFilterWindowsPhaseResponse());


            //const float frequency = 67;
            //var signal = SignalGenerator.GenerateNoise((int)(((1f / frequency) * 10f) * 48000f) + 1).ToArray();
            //var max = signal.Max();
            //var min = signal.Min();

            //var amp1f = GoertzelMag(signal, 48000, frequency);
            //var amp2f = GoertzelMag(signal, 48000, frequency * 2);
            //var amp4f = GoertzelMag(signal, 48000, frequency * 4);

            //Console.WriteLine(amp1f);
            //Console.WriteLine(amp2f);
            //Console.WriteLine(amp4f);
        }
Ejemplo n.º 2
0
        public HighPrecisionTimer(int interval)
        {
            log.Info("Starting HighPrecisionTimer with" + interval.ToString() + " ms interval");

            if (interval < 1)
            {
                throw new ArgumentOutOfRangeException();
            }
            System.Diagnostics.Trace.Assert(interval >= 10, "Not reliable/tested, may use too much CPU");

            cancelSource = new CancellationTokenSource();

            // Used to report timing accuracy for 1 sec, running total
            tickTiming = new CircularBuffer.CircularBuffer <int>(1000 / interval, true);

            var  watch      = System.Diagnostics.Stopwatch.StartNew();
            long durationMs = 0;
            long totalTicks = 0;
            long nextStop   = interval;
            long lastReport = 0;

            var task = new Task(() =>
            {
                while (!this.cancelSource.IsCancellationRequested)
                {
                    long msLeft = nextStop - watch.ElapsedMilliseconds;
                    if (msLeft <= 0)
                    {
                        durationMs = watch.ElapsedMilliseconds;
                        totalTicks = durationMs / interval;

                        tickTiming.Put((int)(durationMs - nextStop));

                        if (durationMs - lastReport >= 1000)
                        {
                            // Report
                            log.Debug(string.Concat("Last second - avg: {0:F1}  best: {1}  worst: {2}",
                                                    tickTiming.Average(), tickTiming.Min(), tickTiming.Max()));

                            lastReport = durationMs;
                        }

                        var handler = Tick;
                        if (handler != null)
                        {
                            handler(this, new TickEventArgs(TimeSpan.FromMilliseconds(durationMs), totalTicks));
                        }

                        // Calculate when the next stop is. If we're too slow on the trigger then we'll skip ticks
                        nextStop = interval * (watch.ElapsedMilliseconds / interval + 1);
                    }
                    else if (msLeft < 16)
                    {
                        System.Threading.SpinWait.SpinUntil(() => watch.ElapsedMilliseconds >= nextStop);
                        continue;
                    }

                    System.Threading.Thread.Sleep(1);
                }
            }, cancelSource.Token, TaskCreationOptions.LongRunning);

            task.Start();
        }
Ejemplo n.º 3
0
        public HighPrecisionTimer(int intervalMs, bool startRunning = true)
        {
            log.Info("Starting HighPrecisionTimer with {0} ms interval", intervalMs);

            if (intervalMs < 1)
                throw new ArgumentOutOfRangeException();
            System.Diagnostics.Trace.Assert(intervalMs >= 10, "Not reliable/tested, may use too much CPU");

            this.IntervalMs = intervalMs;
            this.cancelSource = new CancellationTokenSource();
            this.taskComplete = new ManualResetEvent(false);

            #if PROFILE
            // Used to report timing accuracy for 1 sec, running total
            tickTiming = new CircularBuffer.CircularBuffer<int>(1000 / intervalMs, true);
            execTiming = new CircularBuffer.CircularBuffer<long>(1000 / intervalMs, true);
            #endif

            var watch = System.Diagnostics.Stopwatch.StartNew();
            long durationMs = 0;
            long totalTicks = 0;
            long nextStop = intervalMs;
            #if PROFILE
            long lastReport = 0;
            #endif

            this.task = new Task(() =>
                {
                    var eventArgs = new TickEventArgs();

                    while (!this.cancelSource.IsCancellationRequested)
                    {
                        long msLeft = nextStop - watch.ElapsedMilliseconds;
                        if (msLeft <= 0)
                        {
                            durationMs = watch.ElapsedMilliseconds;
                            totalTicks = durationMs / intervalMs;

            #if PROFILE
                            var execWatch = System.Diagnostics.Stopwatch.StartNew();
            #endif
                            var handler = Tick;
                            if (handler != null)
                            {
                                eventArgs.Duration = TimeSpan.FromMilliseconds(durationMs);
                                eventArgs.TotalTicks = totalTicks;
                                handler(this, eventArgs);
                                if (eventArgs.Cancel)
                                    break;
                            }
            #if PROFILE
                            execWatch.Stop();
                            execTiming.Put(execWatch.ElapsedTicks);
                            tickTiming.Put((int)(durationMs - nextStop));

                            if (durationMs - lastReport >= 1000)
                            {
                                // Report
                                log.Debug("HighPTimer  avg: {0:F1}  best: {1}  worst: {2}   MaxExec: {3:N1}ms",
                                    tickTiming.Average(), tickTiming.Min(), tickTiming.Max(),
                                    TimeSpan.FromTicks(execTiming.Max()).TotalMilliseconds);

                                lastReport = durationMs;
                            }
            #endif

                            // Calculate when the next stop is. If we're too slow on the trigger then we'll skip ticks
                            nextStop = intervalMs * (watch.ElapsedMilliseconds / intervalMs + 1);
                            continue;
                        }
                        else if (msLeft < 16)
                        {
                            System.Threading.SpinWait.SpinUntil(() => watch.ElapsedMilliseconds >= nextStop);
                            continue;
                        }

                        System.Threading.Thread.Sleep(1);
                    }

                    this.taskComplete.Set();
                }, cancelSource.Token, TaskCreationOptions.LongRunning);

            if (startRunning)
                this.task.Start();
        }
Ejemplo n.º 4
0
        public HighPrecisionTimer2(int intervalMs, bool startRunning = true)
        {
            this.log = Log.Logger;
            this.log.Information("Starting HighPrecisionTimer2 with {0} ms interval", intervalMs);

            this.outputValue = new Subject <long>();

            if (intervalMs < 1)
            {
                throw new ArgumentOutOfRangeException();
            }
            System.Diagnostics.Trace.Assert(intervalMs >= 10, "Not reliable/tested, may use too much CPU");

            this.IntervalMs   = intervalMs;
            this.cancelSource = new CancellationTokenSource();
            this.taskComplete = new ManualResetEvent(false);

#if PROFILE
            // Used to report timing accuracy for 1 sec, running total
            tickTiming = new CircularBuffer.CircularBuffer <int>(1000 / intervalMs, true);
            execTiming = new CircularBuffer.CircularBuffer <long>(1000 / intervalMs, true);
#endif

            watch = System.Diagnostics.Stopwatch.StartNew();
            long durationMs = 0;
            long nextStop   = intervalMs;
#if PROFILE
            long lastReport = 0;
#endif

            this.task = new Task(() =>
            {
                while (!this.cancelSource.IsCancellationRequested)
                {
                    long msLeft = nextStop - watch.ElapsedMilliseconds;
                    if (msLeft <= 0)
                    {
                        durationMs = watch.ElapsedMilliseconds;

#if PROFILE
                        var execWatch = System.Diagnostics.Stopwatch.StartNew();
#endif
                        this.outputValue.OnNext(durationMs);

#if PROFILE
                        execWatch.Stop();
                        execTiming.Put(execWatch.ElapsedTicks);
                        tickTiming.Put((int)(durationMs - nextStop));

                        if (durationMs - lastReport >= 1000)
                        {
                            // Report
                            log.Debug("HighPTimer  avg: {0:F1}  best: {1}  worst: {2}   MaxExec: {3:N1}ms",
                                      tickTiming.Average(), tickTiming.Min(), tickTiming.Max(),
                                      TimeSpan.FromTicks(execTiming.Max()).TotalMilliseconds);

                            lastReport = durationMs;
                        }
#endif

                        // Calculate when the next stop is. If we're too slow on the trigger then we'll skip ticks
                        nextStop = intervalMs * (watch.ElapsedMilliseconds / intervalMs + 1);
                        continue;
                    }
                    else if (msLeft < 16)
                    {
                        System.Threading.SpinWait.SpinUntil(() => watch.ElapsedMilliseconds >= nextStop);
                        continue;
                    }

                    System.Threading.Thread.Sleep(1);
                }

                this.taskComplete.Set();
            }, cancelSource.Token, TaskCreationOptions.LongRunning);

            if (startRunning)
            {
                this.task.Start();
            }
        }