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); }
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); }