コード例 #1
0
        public Sample<float>[] FilterData(Sample<float>[] input)
        {
            if (input == null)
                return null;

            Sample<float>[] output = new Sample<float>[input.Length];

            // Get values and duration of the values
            Sample<float>[] values = new Sample<float>[input.Length];
            for (int i = 0; i < input.Length; i++)
            {

                TimeSpan startTime;
                if (i == 0)
                    startTime = input[i].Time - halfWindowWidth;
                else
                    startTime = TimeSpan.FromSeconds((input[i - 1].Time + input[i].Time).TotalSeconds / 2f);

                values[i] = new Sample<float>(new Sample<float>(startTime, input[i].Value));
            }

            /*
            for (int i = 0; i < input.Length; i++)
            {

                float value = input[i].Value;
                TimeSpan startTime;
                TimeSpan endTime;

                if (i == 0)
                {
                    startTime = input[i].Time - windowWidth;
                    endTime = (input[i].Time + input[i + 1].Time).TotalSeconds / 2f;
                }
                else if (i == input.Length - 1)
                {
                    startTime = TimeSpan.FromSeconds((input[i - 1].Time + input[i].Time).TotalSeconds / 2f);
                    TimeSpan endTime = input[i].Time + windowWidth;
                    duration = (float)(endTime - startTime).TotalSeconds;
                }
                else
                {
                    startTime = TimeSpan.FromSeconds((input[i - 1].Time.TotalSeconds + input[i].Time.TotalSeconds) / 2f);
                    double endTime = (input[i].Time + input[i + 1].Time).TotalSeconds / 2f;
                    duration = (float)(endTime - startTime.TotalSeconds);
                }

                values[i] = new Pair<Sample<float>,TimeSpan>(new Sample<float>(startTime, value), duration);
            }
            */

            // Filter data
            int kernelStart = 0; // Points to first sample in kernel
            int kernelEnd = 0;  // Points to next sample that will be put into kernel
            for (int i = 0; i < input.Length; i++)
            {
                Sample<float> inputSample = input[i];
                TimeSpan windowStart = input[i].Time - halfWindowWidth;
                TimeSpan windowEnd = input[i].Time + halfWindowWidth;

                // Remove old samples from kernel
                while(kernelStart < input.Length - 1 && values[kernelStart+1].Time <= windowStart)
                {
                    kernelStart++;
                }

                // Add new samples to kernel
                while (kernelEnd < input.Length && values[kernelEnd].Time < windowEnd)
                {
                    kernelEnd++;
                }

                // Calculate weights for each sample
                float[] weights = new float[kernelEnd - kernelStart];
                for (int j = 0; j < weights.Length; j++)
                {
                    double startTime = values[kernelStart + j].Time.TotalSeconds;
                    double endTime;
                    if(kernelStart + j == values.Length - 1)
                        endTime = windowEnd.TotalSeconds;
                    else
                        endTime = values[kernelStart + 1 + j].Time.TotalSeconds;

                    double intersectStart = Math.Max(startTime, windowStart.TotalSeconds);
                    double intersectEnd = Math.Min(endTime, windowEnd.TotalSeconds);

                    weights[j] = (float)((intersectEnd - intersectStart) / windowWidth.TotalSeconds);
                }
                //weights[0] = (float)((values[kernelStart+1].Time - windowStart).TotalSeconds / windowWidth.TotalSeconds);
                //weights[weights.Length-1] = (float)((values[kernelEnd].Time - windowEnd).TotalSeconds / windowWidth.TotalSeconds);

                // Apply kernel
                float result = input.Skip(kernelStart).Take(kernelEnd - kernelStart).Zip(weights, (x,y) => x.Value * y).Sum();

                // Set output
                output[i] = new Sample<float>(input[i].Time, result);
            }

            return output;
        }
コード例 #2
0
ファイル: InterpolatingFilter.cs プロジェクト: Faham/emophiz
 public static float GetMinimumSamplesPerSecond(Sample<float>[] data)
 {
     // Find minimum time between samples
     TimeSpan minTime = data.Skip(1).Zip(data, (x, y) => x.Time - y.Time).Min();
     return (float)(1.0f / minTime.TotalSeconds);
 }