Beispiel #1
0
        /// <summary>
        /// Decoder statistics thread method
        /// </summary>
        static void DecoderLoop()
        {
            string logsrc = "DECODER";

            Program.Log(logsrc, "START");

            Socket s = new Socket(SocketType.Stream, ProtocolType.Tcp);

            Program.Log(logsrc, "Socket created");

            try
            {
                // Connect socket
                s.Connect(IP.ToString(), DecoderPort);
                Program.Log(logsrc, string.Format("Connected to {0}:{1}", IP, DecoderPort.ToString()));

                // Send nanomsg init message
                s.Send(nninit);

                // Check nanomsg response
                byte[] res      = new byte[8];
                int    bytesRec = s.Receive(res);
                if (res.SequenceEqual(nnires))
                {
                    Program.Log(logsrc, "nanomsg OK");
                }
                else
                {
                    string resHex = BitConverter.ToString(res);
                    Program.Log(logsrc, string.Format("nanomsg error: {0} (Expected: {1})", resHex, BitConverter.ToString(nnires)));
                }
            }
            catch (Exception e)
            {
                Program.Log(logsrc, "Failed to connect");
                return;
            }

            byte[]  dres = new byte[256];
            int     num;
            JObject json;

            // Signal quality
            float sigQ    = 0f;
            float vitLow  = 30f;
            float vitHigh = 1000f;

            // Averaging
            long       timeAvg = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            List <int> vitAvg  = new List <int>();
            List <int> rsAvg   = new List <int>();

            // Continually receive data
            while (true)
            {
                // Receive nanomsg header
                num = s.Receive(dres, 8, SocketFlags.None);

                // Kill thread if no data received
                if (num == 0)
                {
                    Program.Log(logsrc, "Connection lost/no data, killing thread");
                    return;
                }

                // Get message length
                int msglen = dres[7];

                // Receive message content
                num = s.Receive(dres, msglen, SocketFlags.None);

                // Log message bytes
                //Program.Log(logsrc, BitConverter.ToString(dres).Replace("-", ""));

                // Kill thread if no data received
                if (num == 0)
                {
                    Program.Log(logsrc, "Connection lost/no data, killing thread");
                    return;
                }

                // Convert message bytes to ASCII
                string data = Encoding.ASCII.GetString(dres);

                // Trim message length and remove trailing new line
                data = data.Substring(0, msglen);
                data = data.TrimEnd('\n');

                // Parse JSON object
                try
                {
                    json = JObject.Parse(data);
                    Program.Log(logsrc, string.Format("OK: {0}", data));
                }
                catch (Newtonsoft.Json.JsonReaderException e)
                {
                    Program.Log(logsrc, string.Format("Error parsing JSON: {0}", data));
                    Program.Log(logsrc, e.ToString());
                    continue;
                }

                // Signal lock indicator
                bool locked = (json["ok"] != null) ? ((int)json["ok"] != 0) : false;

                // Viterbi errors
                int vit = (int)json["viterbi_errors"];

                // Reed-Solomon errors
                int rs = (int)json["reed_solomon_errors"];
                rs = (rs > 0) ? rs : 0;

                // Write parsed data to log
                Program.Log(logsrc, string.Format("LOCK: {0}    VITERBI: {1}    RS: {2}", locked, vit, rs));

                // Add values to average lists
                vitAvg.Add(vit);
                rsAvg.Add(rs);

                // Calculate signal quality (capped at 100)
                sigQ = 100 - (((vit - vitLow) / (vitHigh - vitLow)) * 100);
                sigQ = (sigQ > 100) ? 100 : sigQ;
                sigQ = (sigQ < 0) ? 0 : sigQ;

                // Update stats plot UI
                if (Program.PlotWindow.Visible && Program.PlotWindow.ReadyForData)
                {
                    Program.PlotWindow.Update(vit, (int)rsAvg.Average());
                }

                // Calculate average every second
                if (DateTimeOffset.Now.ToUnixTimeMilliseconds() - timeAvg > 1000)
                {
                    Program.Log(logsrc, string.Format("AVERAGE QUALITY: {0}%    AVERAGE VITERBI: {1}    AVERAGE RS: {2}", sigQ, (int)vitAvg.Average(), (int)rsAvg.Average()));

                    // Update main UI
                    Program.MainWindow.SignalLock    = locked;
                    Program.MainWindow.SignalQuality = (int)sigQ;
                    Program.MainWindow.ViterbiErrors = (int)vitAvg.Average();
                    Program.MainWindow.RSErrors      = (int)rsAvg.Average();

                    // Update large stats UI
                    if (Program.BigWindow.Visible)
                    {
                        Program.BigWindow.SignalLock    = locked;
                        Program.BigWindow.SignalQuality = (int)sigQ;
                        Program.BigWindow.ViterbiErrors = (int)vitAvg.Average();
                        Program.BigWindow.RSErrors      = (int)rsAvg.Average();
                    }

                    // Reset average time
                    vitAvg.Clear();
                    rsAvg.Clear();
                    timeAvg = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Decoder statistics thread method
        /// </summary>
        static void DecoderLoop()
        {
            Console.WriteLine("[DECODER] Started");

            Socket s = new Socket(SocketType.Stream, ProtocolType.Tcp);

            try
            {
                // Connect socket
                s.Connect(IP.ToString(), DecoderPort);
                Console.WriteLine("[DECODER] Connected to {0}:{1}", IP, DecoderPort.ToString());

                // Send nanomsg init message
                s.Send(nninit);

                // Check nanomsg response
                byte[] res      = new byte[8];
                int    bytesRec = s.Receive(res);
                if (res.SequenceEqual(nnires))
                {
                    Console.WriteLine("[DECODER] Nanomsg OK");
                }
                else
                {
                    string resHex = BitConverter.ToString(res);
                    Console.WriteLine("[DECODER] Nanomsg error: {0} (Expected: {1})", resHex, BitConverter.ToString(nnires));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("[DECODER] Failed to connect");
                return;
            }

            // Continually receive data
            while (true)
            {
                byte[] dres     = new byte[1024];
                int    numbytes = s.Receive(dres);

                // Kill thread if no data received
                if (numbytes == 0)
                {
                    Console.WriteLine("[DECODER] No data");
                    return;
                }

                // Convert to string and trim
                string data = Encoding.ASCII.GetString(dres).TrimEnd('\0').TrimEnd('\n');

                int  vitErr;
                int  rsErr = 0;
                bool locked;
                try
                {
                    // Get Virerbi error count
                    string vitStr = data.Substring(data.IndexOf("viterbi_errors") + 17);
                    vitStr = vitStr.Substring(0, vitStr.IndexOf(','));
                    vitErr = int.Parse(vitStr);

                    // Get lock state
                    string lockStr = data.Substring(data.IndexOf("ok") + 5, 1);
                    if (lockStr == "1")
                    {
                        locked = true;
                    }
                    else
                    {
                        locked = false;
                    }

                    // Split data into lines
                    rsErr = 0;
                    string[] lines = data.Split('\n');
                    foreach (string l in lines)
                    {
                        // Parse Line
                        string rsStr = l.Substring(l.IndexOf("reed_solomon_errors") + 22);
                        rsStr = rsStr.Substring(0, rsStr.IndexOf(','));

                        if (rsStr != "-1")
                        {
                            int.TryParse(rsStr, out rsErr);
                        }
                    }
                }
                catch (ArgumentOutOfRangeException e)
                {
                    Console.WriteLine("[DEMOD] Substring error");
                    continue;
                }

                // Cap viterbi in range for signal quality
                float vitErrQ  = vitErr;
                float vitLower = 30f;
                float vitUpper = 1000f;
                if (vitErr < vitLower)
                {
                    vitErrQ = vitLower;
                }
                else if (vitErr > vitUpper)
                {
                    vitErrQ = vitUpper;
                }

                // Calculate signal quality
                float sigQ = 100 - (((vitErrQ - vitLower) / (vitUpper - vitLower)) * 100);

                // Update UI
                Program.MainWindow.SignalLock    = locked;
                Program.MainWindow.SignalQuality = (int)sigQ;
                Program.MainWindow.ViterbiErrors = vitErr;
                Program.MainWindow.RSErrors      = rsErr;

                Thread.Sleep(500);
            }
        }