public void Calibrate()
        {
            double[] envelopeAverage = null;

            // create the envelope for each signal
            for (int i = 0; i < m_rawSignals.Count; i++)
            {
                Signal signal = Signal.FromArray(m_rawSignals[i],
                                                 EchoTubeSensor.SampleRate, SampleFormat.Format32BitIeeeFloat);

                LowPassFilter lowPassFilter = new LowPassFilter(100.0, EchoTubeSensor.SampleRate)
                {
                    Alpha = 0.05f
                };
                Signal filteredSignal = lowPassFilter.Apply(signal);

                // this is the filtered signal (and a single baseline)
                float[] filteredRawSData = filteredSignal.ToFloat();
                float[] processedData    = new float[filteredRawSData.Length];

                // now, shift and rectify the raw data
                Parallel.For(0, processedData.Length, j =>
                {
                    // shift & rectify
                    processedData[j] = Math.Abs(m_rawSignals[i][j] - filteredRawSData[j]);
                });

                Signal processedSignal = Signal.FromArray(processedData,
                                                          EchoTubeSensor.SampleRate, SampleFormat.Format32BitIeeeFloat);

                // now, we can create the calibration envelope
                EnvelopeFilter filter          = new EnvelopeFilter(Sensor.EnvelopeAlpha);
                Signal         envelopedSignal = filter.Apply(processedSignal);

                float[] envelopedData = envelopedSignal.ToFloat();
                if (envelopeAverage == null)
                {
                    envelopeAverage = new double[envelopedData.Length];
                }

                Parallel.For(0, envelopedData.Length, j =>
                {
                    envelopeAverage[j] += envelopedData[j];
                });
            }

            // now, we need to average over the envelope
            if (m_rawSignals.Count > 0)
            {
                Parallel.For(0, envelopeAverage.Length, i =>
                {
                    envelopeAverage[i] /= m_rawSignals.Count;
                });

                m_envelopedAvg = envelopeAverage.Select(x => (float)x).ToArray();
                IsValid        = true;
            }
        }
        public float[] GetCalibratedSignal(float[] data)
        {
            Signal signal = Signal.FromArray(data, EchoTubeSensor.SampleRate, SampleFormat.Format32BitIeeeFloat);

            EnvelopeFilter filter          = new EnvelopeFilter(Sensor.EnvelopeAlpha);
            Signal         envelopedSignal = filter.Apply(signal);

            float[] envelopedData = envelopedSignal.ToFloat();
            if (IsValid)
            {
                Parallel.For(0, envelopedData.Length, i =>
                {
                    /* if (Math.Abs(envelopedData[i] - m_envelopedAvg[i]) >= 200)
                     *  Debug.WriteLine(envelopedData[i] + " :: " + m_envelopedAvg[i] + " :: " + i); */

                    // envelopedData[i] = Math.Abs(envelopedData[i] - m_envelopedAvg[i]);
                    envelopedData[i] = Math.Max(0.0f, envelopedData[i] - m_envelopedAvg[i]);
                    // envelopedData[i] = envelopedData[i] - m_envelopedAvg[i];
                });
            }
            return(envelopedData);
        }
Beispiel #3
0
        private float[] PreprocessSignal(float[] rawData, bool amplify)
        {
            // preprocess the peaks
            for (int i = 0; i < rawData.Length; i++)
            {
                if (i <= Sensor.StartCutOff)
                {
                    rawData[i] *= i / (float)Sensor.StartCutOff;
                }
                else if (i >= rawData.Length - Sensor.EndCutOff)
                {
                    rawData[i] *= (rawData.Length - i + 1) / (float)Sensor.EndCutOff;
                }

                // amplify the data
                if (amplify)
                {
                    // double factor = 2.0 * Math.Pow(Sensor.GetDistance(i), 3.0) + 1.0;
                    double factor = 4.0 * Math.Pow(Sensor.GetDistance(i), 2.0) + 1.0;
                    // rawData[i] *= 4.0f;
                    // factor *= 4.0;
                    rawData[i] *= (float)factor;
                }
            }

            Signal signal = Signal.FromArray(rawData, EchoTubeSensor.SampleRate, SampleFormat.Format32BitIeeeFloat);

            EnvelopeFilter filter          = new EnvelopeFilter(Sensor.EnvelopeAlpha);
            Signal         envelopedSignal = filter.Apply(signal);

            float[] currData = envelopedSignal.ToFloat();

            /* float avg = currData.Average();
             * rawData = rawData.Select(x => x - avg).ToArray();
             * currData = currData.Select(x => x - avg).ToArray(); */

            /* if (m_previousData == null)
             * {
             *  m_previousData = new float[currData.Length];
             * }
             * else
             * {
             *  if (checkPrevious)
             *  {
             *      double absDifference = 0.0;
             *      for (int i = 0; i < currData.Length; i++)
             *      {
             *          absDifference += Math.Abs(currData[i] - m_previousData[i]);
             *      }
             *      absDifference /= currData.Length;
             *
             *      // Debug.WriteLine(absDifference);
             *      if (absDifference >= ErrorDetectionThreshold && false)
             *      {
             *          // this is a wrong signal
             *          // throw it away
             *          return null;
             *      }
             *      else
             *      {
             *          // signal was good, store the current as previous
             *          Array.Copy(currData, m_previousData, currData.Length);
             *      }
             *  }
             * } */

            return(currData);
        }