public string ToStomp(WaxPacket packet)
        {
            Hashtable sourceData = new Hashtable();

            object[] samples = new object[packet.Samples.Length];
            for (int i = 0; i < packet.Samples.Length; i++)
            {
                WaxSample sample      = packet.Samples[i];
                object[]  sampleArray = new object[5];
                sampleArray[0] = sample.Timestamp.ToBinary();
                sampleArray[1] = sample.Index;
                sampleArray[2] = sample[0];
                sampleArray[3] = sample[1];
                sampleArray[4] = sample[2];
                samples[i]     = sampleArray;
            }

            sourceData.Add("Timestamp", packet.Timestamp.ToBinary());
            sourceData.Add("DeviceId", packet.DeviceId);
            sourceData.Add("Version", packet.Version);
            sourceData.Add("Battery", packet.Battery);
            sourceData.Add("AdcSample", packet.AdcSample);
            sourceData.Add("SequenceId", packet.SequenceId);
            sourceData.Add("Format", packet.Format);
            sourceData.Add("SampleCount", packet.SampleCount);
            sourceData.Add("Samples", samples);

            string json = Json.JsonEncode(sourceData);

            return(json);
        }
Example #2
0
        public void AddSamples(WaxSample[] samples)
        {
            UpdateTime = DateTime.UtcNow;

            if (samples == null || samples.Length == 0) { return; }

            // If the last index of the new samples is the same as the last index seen -- duplicate packet (ignore)
            if ((int)samples[samples.Length - 1].Index == LastIndex && LastIndex != 0)
            {
                Console.WriteLine("WARNING: Duplicate packet detected (last index: " + LastIndex + ") - ignoring.");
                return;
            }

            // If not a duplicate, and the first index of the new samples is earlier than the last index seen -- must be restart
            if ((int)samples[0].Index < LastIndex && LastIndex != 0)
            {
                // Must have re-started broadcast, clear history
            //if (LastIndex - (int)samples[0].Index > 20)
                Clear();
                LastIndex = (int)samples[0].Index - 1;
            }

            // Calculate number of missed packets
            int numMissed = (int)(samples[0].Index - LastIndex - 1);
            if (numMissed < 0) { numMissed = 0; }
            if (numMissed > 1000) { numMissed = 1000; }

            if (numMissed > 0)
            {
                Console.WriteLine("WARNING: Dropped packet(s) detected, missing samples: " + numMissed);
            }

            // Add any missing samples
            WaxSample[] missedSamples = new WaxSample[numMissed];
            for (int i = 0; i < missedSamples.Length; i++)
            {
                missedSamples[i] = new WaxSample((uint)++LastIndex);
            }
            Samples.AddRange(missedSamples);

            // Add samples
            int firstIndex = Samples.Count;
            int length = samples.Length;
            Samples.AddRange(samples);

            // Update last index
            LastIndex = (int)(Samples[Samples.Count - 1].Index);

            // Trim to maximum samples range
            if (Samples.Count > MaxHistory)
            {
                firstIndex -= Samples.Count - MaxHistory;
                if (firstIndex < 0) { length += firstIndex; firstIndex = 0; }
                Samples.RemoveRange(0, Samples.Count - MaxHistory);
            }
        }
Example #3
0
 // Construct a WaxPacket
 public WaxPacket(DateTime timestamp, ushort deviceId, byte version, byte battery, ushort adcSample, ushort sequenceId, byte format, byte sampleCount, WaxSample[] samples)
 {
     Timestamp = timestamp;
     DeviceId = deviceId;
     Version = version;
     Battery = battery;
     AdcSample = adcSample;
     SequenceId = sequenceId;
     Format = format;
     SampleCount = sampleCount;
     Samples = samples;
 }
        public WaxPacket FromOscBundle(OscBundle oscBundle, string topic)
        {
            List <WaxSample> sampleData = new List <WaxSample>();
            ushort           deviceId   = 0xffff;
            ulong            timestamp  = oscBundle.Timestamp;

            foreach (OscData oscData in oscBundle.Parts)
            {
                OscMessage oscMessage = oscData as OscMessage;
                if (oscMessage == null)
                {
                    continue;
                }

                string t = (topic == null ? "/wax" : topic);
                if (oscMessage.Address != t)
                {
                    continue;
                }
                if (oscMessage.Arguments.Length < 5)
                {
                    continue;
                }

                uint  index;
                short x, y, z;
                deviceId = (ushort)(int)oscMessage.Arguments[0];
                index    = (uint)(int)oscMessage.Arguments[1];
                x        = (short)((float)oscMessage.Arguments[2] * 256.0f);
                y        = (short)((float)oscMessage.Arguments[3] * 256.0f);
                z        = (short)((float)oscMessage.Arguments[4] * 256.0f);

                WaxSample waxSample = new WaxSample(OscMessage.DateTimeFromTimestamp(timestamp), index, x, y, z);
                Console.WriteLine(waxSample.ToString());
                sampleData.Add(waxSample);
            }

            byte   version     = 0;
            byte   battery     = 0;
            ushort adcSample   = 0;
            ushort sequenceId  = 0xffff;    // TODO: Fix this to something sensible
            byte   format      = 0;
            byte   sampleCount = (byte)sampleData.Count;

            return(new WaxPacket(OscMessage.DateTimeFromTimestamp(timestamp), deviceId, version, battery, adcSample, sequenceId, format, sampleCount, sampleData.ToArray()));
        }
        // Factory method to return a WaxPacket, or null if invalid byte array
        public WaxPacket FromBinary(byte[] buffer, DateTime timestamp)
        {
            WaxPacket waxPacket = null;

            // USER_REPORT_TYPE
            if (buffer != null && buffer.Length > 0)
            {
//Console.WriteLine("FromBinary():");
//Console.WriteLine(Slip.HexDump(buffer));

                if (buffer.Length >= 2 && buffer[0] == 0x12 && buffer[1] == 0x78 && buffer.Length >= 12)           // New WAX hardware (ASCII 'x')
                {
                    /*
                     *  unsigned char  reportType;		// [1] = 0x12 (USER_REPORT_TYPE)
                     *  unsigned char  reportId;	    // [1] = 0x78 (ASCII 'x')
                     *  unsigned short deviceId;		// [2] = Device identifier (16-bit)
                     *  unsigned char  status;			// [1] = Device status (bit 0 is battery warning, top 7 bits reserved)
                     *  unsigned short sample;			// [2] = Analogue sample (top 6 bits indicate measurement information, lower 10 bits are the value)
                     *  unsigned char  format;			// [1] = Accelerometer data format 0xE9 (+/-2g, 2-bytes, 100Hz); Top two bits is g-range, next two bits is format [0=3x10+2 bits, 2=signed 16-bit] (2); lowest four bits is the rate code: frequency = 3200 / (1 << (15-(n & 0x0f)))
                     *  unsigned short sequenceId;		// [2] = Sequence number of first accelerometer reading in this packet (16-bit sample index -- will wrap or be reset if device sleeps and resumes)
                     *  unsigned char  outstanding;		// [1] = Number of samples remaining on device after this packet (0xff: >= 255)
                     *  unsigned char  sampleCount;		// [1] = Number of samples in this packet. 0x0c = 13 samples (number of accelerometer samples)
                     *  signed short   sampleData[BUFFER_PACKET_MAX_SAMPLES * 3];	// [sampleCount * numAxes * bytesPerSample = 78 -- would be 102 with 17 samples] (sample data)
                     */

                    ushort      deviceId    = (ushort)(buffer[2] | (((ushort)buffer[3]) << 8));
                    byte        status      = buffer[4];
                    ushort      adcSample   = (ushort)(buffer[5] | (((ushort)buffer[6]) << 8));
                    byte        format      = buffer[7];
                    ushort      sequenceId  = (ushort)(buffer[8] | (((ushort)buffer[9]) << 8));
                    byte        outstanding = buffer[10];
                    byte        sampleCount = buffer[11];
                    WaxSample[] sampleData  = new WaxSample[sampleCount];

                    // Format: 0xE0 | AccelCurrentRate()
                    // [1] = Accelerometer data format 0xEA (3-axis, 2-bytes, 100Hz); Top two bits is number of axes (3), next two bits is format [1=unsigned 8-bit,2=signed 16-bit] (2); lowest four bits is the rate code: frequency = 3200 / (1 << (15-(n & 0x0f)))
                    int bytesPerSample = 0;
                    if (((format >> 4) & 0x03) == 2)
                    {
                        bytesPerSample = 6;
                    }                                                           // 3*16-bit
                    else if (((format >> 4) & 0x03) == 0)
                    {
                        bytesPerSample = 4;
                    }                                                                // 3*10-bit + 2

                    int expectedLength = 12 + sampleCount * bytesPerSample;
                    if (buffer.Length < expectedLength)
                    {
                        Console.WriteLine("WARNING: Ignoring truncated- or unknown-format data packet (received " + buffer.Length + " expected " + expectedLength + ").");
                    }
                    else
                    {
                        if (buffer.Length > expectedLength)
                        {
                            Console.WriteLine("WARNING: Data packet was larger than expected, ignoring additional samples");
                        }

                        int frequency = 3200 / (1 << (15 - (format & 0x0f)));

                        StringBuilder sampleDataString = new StringBuilder();

                        for (int i = 0; i < sampleCount; i++)
                        {
                            int samplesAgo = sampleCount + outstanding - 1 - i;

                            short x = 0, y = 0, z = 0;
                            if (bytesPerSample == 6)
                            {
                                x = (short)((ushort)(buffer[12 + i * 6] | (((ushort)buffer[13 + i * 6]) << 8)));
                                y = (short)((ushort)(buffer[14 + i * 6] | (((ushort)buffer[15 + i * 6]) << 8)));
                                z = (short)((ushort)(buffer[16 + i * 6] | (((ushort)buffer[17 + i * 6]) << 8)));
                            }
                            else if (bytesPerSample == 4)
                            {
                                uint value = (uint)buffer[12 + i * 4] | ((uint)buffer[13 + i * 4] << 8) | ((uint)buffer[14 + i * 4] << 16) | ((uint)buffer[15 + i * 4] << 24);
                                x = (short)((short)((ushort)0xffc0 & (ushort)(value << 6)) >> (6 - ((byte)(value >> 30))));             // Sign-extend 10-bit value, adjust for exponent
                                y = (short)((short)((ushort)0xffc0 & (ushort)(value >> 4)) >> (6 - ((byte)(value >> 30))));             // Sign-extend 10-bit value, adjust for exponent
                                z = (short)((short)((ushort)0xffc0 & (ushort)(value >> 14)) >> (6 - ((byte)(value >> 30))));            // Sign-extend 10-bit value, adjust for exponent
                            }
                            uint index = (uint)sequenceId + (uint)i;

                            DateTime t = timestamp - TimeSpan.FromMilliseconds(samplesAgo * 1000 / frequency);

                            sampleData[i] = new WaxSample(t, index, x, y, z);
                        }

                        //Console.WriteLine(line);
                        waxPacket = new WaxPacket(timestamp, deviceId, 1, 0, adcSample, sequenceId, format, sampleCount, sampleData);
                    }
                }
                else if (buffer.Length >= 2 && buffer[0] == 0x12 && buffer[1] == 0x58 && buffer.Length >= 12)           // Old WAX hardware (ASCII 'X')
                {
                    if (buffer.Length > 0 && buffer.Length != 90)
                    {
                        Console.WriteLine("Unexpected packet length: " + buffer.Length + "");
                    }

                    // "$ADXL,deviceId,version,battery,adcsample,sequenceId,format,sampleCount,X/Y/Z,X/Y/Z,..."

                    /*
                     * @0  byte   reportType;		// [1] = 0x12 (USER_REPORT_TYPE)
                     * @1  byte   reportId;	    // [1] = 0x58 (ASCII 'X')
                     * @2  ushort deviceId;		// [2] (16-bit device identifier, 0 = unknown)
                     * @4  byte   version;			// [1] = Packet version
                     * @5  byte   battery;			// [1] = Battery value
                     * @6  ushort adcSample;		// [1] = Analogue Sample
                     * @8  ushort sequenceId;		// [2] (16-bit sequence counter, each packet has a new number -- reset if restarted)
                     * @10 byte   format;			// [1] = 0xEA (3-axis, 2-bytes, 100Hz); Top two bits is number of axes (3), next two bits is number of bytes (2); lowest four bits is the rate code: frequency = 3200 / (1 << (15-(n & 0x0f)))
                     * @11 byte   sampleCount;		// [1] = 0x11 = 17 samples (number of accelerometer samples)
                     * @12+i*6 short[,] sampleData[BUFFER_SAMPLE_COUNT, 3];	// [sampleCount * numAxes * bytesPerSample = 78 -- would be 102 with 17 samples] (sample data)
                     */
                    ushort      deviceId    = (ushort)(buffer[2] | (((ushort)buffer[3]) << 8));
                    byte        version     = buffer[4];
                    byte        battery     = buffer[5];
                    ushort      adcSample   = (ushort)(buffer[6] | (((ushort)buffer[7]) << 8));
                    ushort      sequenceId  = (ushort)(buffer[8] | (((ushort)buffer[9]) << 8));
                    byte        format      = buffer[10];
                    byte        sampleCount = buffer[11];
                    WaxSample[] sampleData  = new WaxSample[sampleCount];

                    int expectedLength = 12 + sampleCount * 6;
                    if (buffer.Length < expectedLength)
                    {
                        Console.WriteLine("WARNING: Ignoring truncated data packet (received " + buffer.Length + " expected " + expectedLength + ").");
                    }
                    else
                    {
                        if (buffer.Length > expectedLength)
                        {
                            Console.WriteLine("WARNING: Data packet was larger than expected.");
                        }

                        StringBuilder sampleDataString = new StringBuilder();
                        for (int i = 0; i < sampleCount; i++)
                        {
                            short x     = (short)((ushort)(buffer[12 + i * 6] | (((ushort)buffer[13 + i * 6]) << 8)));
                            short y     = (short)((ushort)(buffer[14 + i * 6] | (((ushort)buffer[15 + i * 6]) << 8)));
                            short z     = (short)((ushort)(buffer[16 + i * 6] | (((ushort)buffer[17 + i * 6]) << 8)));
                            uint  index = (uint)sequenceId * sampleCount + (uint)i;
                            sampleData[i] = new WaxSample(timestamp, index, x, y, z);
                        }

                        //Console.WriteLine(line);
                        waxPacket = new WaxPacket(timestamp, deviceId, version, battery, adcSample, sequenceId, format, sampleCount, sampleData);
                    }
                }
                else if (buffer.Length >= 5 && buffer[0] == 0x12 && buffer[1] == 0x54)           // Old TEDDI (ASCII 'T'), packet 'V2'
                {
                    /*
                     * unsigned char  reportType;			// @0  [1] = 0x12 (USER_REPORT_TYPE)
                     * unsigned char  reportId;		    // @1  [1] = 0x54 (ASCII 'T')
                     * unsigned short deviceId;			// @2  [2] = Short device identifier (16-bit) [doesn't have to be part of the payload, but this format is the same as the WAX]
                     * unsigned char version;				// @4  [1] = (0x02 = format [seq/temp/ldr/audio/pir : short])
                     */
                    ushort deviceId = (ushort)(buffer[2] | (((ushort)buffer[3]) << 8));
                    byte   version  = buffer[4];

                    if (version == 2)
                    {
                        /*
                         * unsigned char  reportType;			// @0  [1] = 0x12 (USER_REPORT_TYPE)
                         * unsigned char  reportId;		    // @1  [1] = 0x54 (ASCII 'T')
                         * unsigned short deviceId;			// @2  [2] = Short device identifier (16-bit) [doesn't have to be part of the payload, but this format is the same as the WAX]
                         * unsigned char version;				// @4  [1] = (0x02 = format [seq/temp/ldr/audio/pir : short])
                         * unsigned short sequence;			// @5  [2] = Sequence number
                         * signed short temp;					// @7  [2] = Temperature
                         * signed short ldr;					// @9  [2] = Light
                         * unsigned short audioDC;				// @11 [2] = Microphone DC value
                         * unsigned long  audioVariance;		// @13 [4] = Amplitude variance
                         * unsigned short audioMean;			// @17 [2] = Amplitude mean
                         * unsigned short audioMin;			// @19 [2] = Amplitude min
                         * unsigned short audioMax;			// @21 [2] = Amplitude max
                         * signed short pir[PIR_UPDATES_PER_WINDOW];	// [4*2 = 8] = PIR
                         */
                        byte     sampleCount   = 4;
                        ushort   sequence      = (ushort)(buffer[5] | (((ushort)buffer[6]) << 8));
                        ushort   temp          = (ushort)(buffer[7] | (((ushort)buffer[8]) << 8));
                        ushort   ldr           = (ushort)(buffer[9] | (((ushort)buffer[10]) << 8));
                        ushort   audioDC       = (ushort)(buffer[11] | (((ushort)buffer[12]) << 8));
                        uint     audioVariance = (uint)buffer[13] | ((uint)buffer[14] << 8) | ((uint)buffer[15] << 16) | ((uint)buffer[16] << 24);
                        ushort   audioMean     = (ushort)(buffer[17] | (((ushort)buffer[18]) << 8));
                        ushort   audioMin      = (ushort)(buffer[19] | (((ushort)buffer[20]) << 8));
                        ushort   audioMax      = (ushort)(buffer[21] | (((ushort)buffer[22]) << 8));
                        ushort[] pir           = new ushort[sampleCount];
                        pir[0] = (ushort)(buffer[23] | (((ushort)buffer[24]) << 8));
                        pir[1] = (ushort)(buffer[25] | (((ushort)buffer[26]) << 8));
                        pir[2] = (ushort)(buffer[27] | (((ushort)buffer[28]) << 8));
                        pir[3] = (ushort)(buffer[29] | (((ushort)buffer[30]) << 8));

                        WaxSample[] sampleData = new WaxSample[sampleCount];
                        for (uint i = 0; i < sampleCount; i++)
                        {
                            //sampleData[i] = new WaxSample(timestamp - TimeSpan.FromMilliseconds((sampleCount - 1 - i) * 1000 / sampleCount), (ushort)(sequence * sampleCount) + i, (short)pir[i], (short)temp, (short)ldr, Math.Sqrt(audioVariance));
                            sampleData[i] = new WaxSample(timestamp - TimeSpan.FromMilliseconds((sampleCount - 1 - i) * 1000 / sampleCount), (ushort)(sequence * sampleCount) + i, (short)pir[i], (short)temp, (short)ldr, audioVariance);
                        }
                        waxPacket = new WaxPacket(timestamp, deviceId, 1, 0, 0, (ushort)(sequence * sampleCount), 0, sampleCount, sampleData);
                    }
                    else if ((version & 0x0f) >= 0x03 && buffer.Length >= 18)
                    {
                        ushort sum = WordSum(buffer);

                        if (true) // sum == 0x0000)
                        {
                            /*
                             * unsigned char  reportType;          // @ 0  [1] USER_REPORT_TYPE (0x12)
                             * unsigned char  reportId;            // @ 1  [1] Report identifier (0x54, ASCII 'T')
                             * unsigned short deviceId;            // @ 2  [2] Device identifier (16-bit)
                             * unsigned char  version;             // @ 4  [1] Low nibble = packet version (0x3), high nibble = config (0x0)
                             * unsigned char  sampleCount;         // @ 5  [1] Sample count (default config is at 250 msec interval with an equal number of PIR and audio samples; 20 = 5 seconds)
                             * unsigned short sequence;            // @ 6  [2] Sequence number (16-bit)
                             * unsigned short unsent;              // @ 8  [2] Number of unsent samples (default config is in 250 msec units)
                             * unsigned short temp;                // @10  [2] Temperature (0.2 Hz)
                             * unsigned short light;               // @12  [2] Light (0.2 Hz)
                             * unsigned short battery;             // @14  [2] Battery (0.2 Hz)
                             * unsigned short checksum;            // @16  [2] 16-bit checksum to make packet zero-sum
                             * unsigned char  data[BITPACK10_SIZEOF(DATA_MAX_INTERVAL * 2)];   // @18 [50] PIR and audio energy (4 Hz, 20x 2x 10-bit samples)
                             */
                            byte     config      = (byte)(buffer[4] >> 4);
                            byte     sampleCount = (byte)(buffer[5]);
                            ushort   sequence    = (ushort)(buffer[6] | (((ushort)buffer[7]) << 8));
                            ushort   unsent      = (ushort)(buffer[8] | (((ushort)buffer[9]) << 8));
                            ushort   temp        = (ushort)(buffer[10] | (((ushort)buffer[11]) << 8));
                            ushort   light       = (ushort)(buffer[12] | (((ushort)buffer[13]) << 8));
                            ushort   battery     = (ushort)(buffer[14] | (((ushort)buffer[15]) << 8));
                            ushort   checksum    = (ushort)(buffer[16] | (((ushort)buffer[17]) << 8));
                            ushort[] pir         = new ushort[sampleCount];
                            ushort[] audio       = new ushort[sampleCount];

                            ushort sampleInterval = 250;

                            try
                            {
                                // Unpack PIR
                                for (int i = 0; i < sampleCount; i++)
                                {
                                    pir[i] = BitUnpack_uint10(buffer, i, 18);
                                }

                                // Unpack Audio
                                for (int i = 0; i < sampleCount; i++)
                                {
                                    audio[i] = BitUnpack_uint10(buffer, sampleCount + i, 18);
                                }

                                // Divide temp/light/battery measurement down
                                if (sampleCount > 0)
                                {
                                    temp    /= sampleCount;
                                    light   /= sampleCount;
                                    battery /= sampleCount;
                                }

                                // Create new sample
                                WaxSample[] sampleData = new WaxSample[sampleCount];
                                for (uint i = 0; i < sampleCount; i++)
                                {
                                    sampleData[i] = new WaxSample(timestamp - TimeSpan.FromMilliseconds((unsent + sampleCount - 1 - i) * sampleInterval), (ushort)(sequence * sampleCount) + i, (short)pir[i], (short)temp, (short)light, audio[i]);
                                }
                                waxPacket = new WaxPacket(timestamp - TimeSpan.FromMilliseconds((unsent + sampleCount - 1) * sampleInterval), deviceId, 1, 0, 0, (ushort)(sequence * sampleCount), 0, sampleCount, sampleData);
                            }
                            catch (IndexOutOfRangeException ex)
                            {
                                Console.Error.Write("EXCEPTION: " + ex + " while parsing packet.");
                            }
                        }
                        else
                        {
                            Console.Error.Write("[T3-checksum]");
                        }
                    }
                    else
                    {
                        Console.Error.Write("[T?]");
                    }
                }
                else
                {
                    Console.Error.Write("[?]");
                }
            }

            return(waxPacket);
        }
        public WaxPacket FromStomp(string value)
        {
            long   timestampLong = 0;
            ushort deviceId      = 0;
            byte   version       = 0;
            byte   battery       = 0;
            ushort adcSample     = 0;
            ushort sequenceId    = 0;
            byte   format        = 0;
            byte   sampleCount   = 0;

            short[][]   sampleData = new short[0][];
            WaxSample[] samples    = new WaxSample[0];

            Hashtable data = (Hashtable)Json.JsonDecode(value);

            if (data != null)
            {
                if (data.ContainsKey("Timestamp"))
                {
                    timestampLong = (long)(double)data["Timestamp"];
                }
                if (data.ContainsKey("DeviceId"))
                {
                    deviceId = (ushort)(double)data["DeviceId"];
                }
                if (data.ContainsKey("Version"))
                {
                    version = (byte)(double)data["Version"];
                }
                if (data.ContainsKey("Battery"))
                {
                    battery = (byte)(double)data["Battery"];
                }
                if (data.ContainsKey("AdcSample"))
                {
                    adcSample = (ushort)(double)data["AdcSample"];
                }
                if (data.ContainsKey("SequenceId"))
                {
                    sequenceId = (ushort)(double)data["SequenceId"];
                }
                if (data.ContainsKey("Format"))
                {
                    format = (byte)(double)data["Format"];
                }
                if (data.ContainsKey("SampleCount"))
                {
                    sampleCount = (byte)(double)data["SampleCount"];
                }
                if (data.ContainsKey("Samples") && data["Samples"] is ArrayList)
                {
                    ArrayList sampleList = (ArrayList)data["Samples"];
                    samples = new WaxSample[sampleList.Count];
                    for (int i = 0; i < sampleList.Count; i++)
                    {
                        if (sampleList[i] is ArrayList && ((ArrayList)sampleList[i]).Count >= 5)
                        {
                            ArrayList al = (ArrayList)sampleList[i];

                            long  ts = 0;
                            uint  idx = 0;
                            short x = 0, y = 0, z = 0;

                            ts  = (long)(double)al[0];
                            idx = (uint)(double)al[1];
                            x   = (short)(double)al[2];
                            y   = (short)(double)al[3];
                            z   = (short)(double)al[4];

                            samples[i] = new WaxSample(DateTime.FromBinary(ts), idx, x, y, z);
                        }
                    }
                }
            }
            else
            {
                Console.Error.Write("[STOMP:null]");
            }

            return(new WaxPacket(DateTime.FromBinary(timestampLong), deviceId, version, battery, adcSample, sequenceId, format, sampleCount, samples));
        }
Example #7
0
        public void AddSamples(WaxSample[] samples)
        {
            UpdateTime = DateTime.UtcNow;

            if (samples == null || samples.Length == 0)
            {
                return;
            }

            // If the last index of the new samples is the same as the last index seen -- duplicate packet (ignore)
            if ((int)samples[samples.Length - 1].Index == LastIndex && LastIndex != 0)
            {
                Console.WriteLine("WARNING: Duplicate packet detected (last index: " + LastIndex + ") - ignoring.");
                return;
            }

            // If not a duplicate, and the first index of the new samples is earlier than the last index seen -- must be restart
            if ((int)samples[0].Index < LastIndex && LastIndex != 0)
            {
                // Must have re-started broadcast, clear history
//if (LastIndex - (int)samples[0].Index > 20)
                Clear();
                LastIndex = (int)samples[0].Index - 1;
            }

            // Calculate number of missed packets
            int numMissed = (int)(samples[0].Index - LastIndex - 1);

            if (numMissed < 0)
            {
                numMissed = 0;
            }
            if (numMissed > 1000)
            {
                numMissed = 1000;
            }

            if (numMissed > 0)
            {
                Console.WriteLine("WARNING: Dropped packet(s) detected, missing samples: " + numMissed);
            }

            // Add any missing samples
            WaxSample[] missedSamples = new WaxSample[numMissed];
            for (int i = 0; i < missedSamples.Length; i++)
            {
                missedSamples[i] = new WaxSample((uint)++LastIndex);
            }
            Samples.AddRange(missedSamples);

            // Add samples
            int firstIndex = Samples.Count;
            int length     = samples.Length;

            Samples.AddRange(samples);

            // Update last index
            LastIndex = (int)(Samples[Samples.Count - 1].Index);

            // Trim to maximum samples range
            if (Samples.Count > MaxHistory)
            {
                firstIndex -= Samples.Count - MaxHistory;
                if (firstIndex < 0)
                {
                    length += firstIndex; firstIndex = 0;
                }
                Samples.RemoveRange(0, Samples.Count - MaxHistory);
            }
        }