Example #1
0
        //line = N/2.56
        /// <summary>
        /// range of f : -Line*df ~ Line*df   where df = Fs/length
        /// </summary>
        /// <param name="f">frequency 배열. length: 2*line + 1</param>
        /// <param name="y">스펙트럼값 배열. length: 2*line + 1</param>
        /// <param name="Fs"></param>
        public static void FullSpectrum_RMS(data_type[] x1, data_type[] x2, double[] f, double[] y, double Fs, Unit2Type Unit2Type, WindowFunction windowFunc)//length = 2^m, the length of h and x = length, the length of f and y = length/2
        {
            int    length = x1.Length;
            int    i;
            double sum, rms;
            int    k1, k2, N, half_length;
            var    XH = new Complex[65536];
            double scale_rms_vec;
            int    line, count;
            var    h = GetWindow(windowFunc, length);

            line = (int)Math.Round((double)length / 2.56);

            if (length != length_saved)
            {
                df = Fs / ((double)length);

                scale = 0.0;
                for (i = 0; i < length; i++)
                {
                    scale = scale + h[i] * h[i];
                }

                scale        = ((double)length) * scale;
                scale        = 1.0 / scale;
                length_saved = length;
            }
            //		k1 = floor(f1/df) - 1;
            //		k2 = ceil(f2/df) + 1;

            half_length = length >> 1;

            //		if(k1 < 0)
            //			k1 = 0;
            //		else if(k1 > half_length)
            //			k1 = half_length;
            //
            //		if(k2 < 0)
            //			k2 = 0;
            //		else if(k2 > half_length)
            //			k2 = half_length;

            for (i = 0; i < length; i++)
            {
                XH[i].Real = (data_type)(h[i] * x1[i]);
                XH[i].Imag = (data_type)(h[i] * x2[i]);
            }

            N = (int)Math.Round(Math.Log10((double)length) / Math.Log10(2.0));
            FFT(XH, N);

            //RMS scalar generation
            //		sum = 0.0;
            //		for(i = k1; i <= k2; i++)
            //		{
            //			sum = sum + XH[i].real*XH[i].real + XH[i].imag*XH[i].imag;
            //		}
            //
            //		rms = sqrt(scale*2.0*sum);
            //RMS vector generation
            scale = 0.0;
            for (i = 0; i < length; i++)
            {
                scale = scale + h[i];
            }

            scale = 1.0 / 1.414214 / (scale);

            switch (Unit2Type)
            {
            case Unit2Type.pk: scale = scale * 1.414213; break;

            case Unit2Type.pp: scale = scale * 2.828427; break;

            default: break;
            }

            count = 0;
            for (i = -line; i <= line; i++)
            {
                f[count] = df * ((double)i);
                count++;
            }

            count = 0;
            for (i = length - line; i <= length - 1; i++)
            {
                y[count] = scale * Math.Sqrt(XH[i].Real * XH[i].Real + XH[i].Imag * XH[i].Imag);
                count++;
            }
            for (i = 0; i <= line; i++)
            {
                y[count] = scale * Math.Sqrt(XH[i].Real * XH[i].Real + XH[i].Imag * XH[i].Imag);
                count++;
            }
        }
Example #2
0
        internal static double GetBandpass(float[] timeData, double maxFrequency, WindowFunction windowType, Unit2Type unitType /*무시*/, double bandLow, double bandHigh, RobinIntegralType integralType)
        {
            double result   = 0.0f;
            int    dataSize = timeData.Length;

            // Sampling Rate와 데이터 개수 계산
            float maxFreq = (float)maxFrequency;
            float srate   = (float)(maxFreq * 2.56);
            int   _size   = dataSize;

            // Time 데이터 버퍼
            var fftdata = new double[_size];

            for (int index = 0; index < _size; index++)
            {
                fftdata[index] = timeData[index];
            }

            // FFT 결과 데이터 버퍼
            var fftresult = new double[_size];

            double deltaf = srate / _size;

            // DSP의 autospectrum_d 함수 호출
#if false // nadamath 알고리즘
            result = nadaMath.autospectrum_d(ref fftdata[0],
                                             (int)(Math.Log(_size, 2)),
                                             ref fftresult[0],
                                             (int)(windowType),
                                             (int)Unit2Type.rms,            // (int)unitType,    rms가 default임
                                             bandLow,
                                             bandHigh,
                                             deltaf,
                                             0,
                                             0);
#else //CXII 알고리즘
            //result = CmsMath.autospectrum_d(fftdata,
            //                            (int)(Math.Log(_size, 2)),
            //                            fftresult,
            //                            windowType,
            //                            Unit2Type.rms,     // (int)unitType,    rms가 default임
            //                            bandLow,
            //                            bandHigh,
            //                            deltaf,
            //                            0,
            //                            0);
            result = CmsMath.autospectrum_cxii(fftdata,
                                               (int)(Math.Log(_size, 2)),
                                               fftresult,
                                               (int)(windowType),
                                               (int)Unit2Type.rms, // (int)unitType,    rms가 default임
                                               bandLow,
                                               bandHigh,
                                               deltaf,
                                               0,
                                               0,
                                               srate);
#endif
            if (integralType != RobinIntegralType.None)
            {
                double[] window = new double[_size];
                double   factor = 8.0 * Math.Atan(1.0) / (_size - 1);

                for (int i = 0; i < _size; i++)
                {
                    window[i] = 0.5 - 0.5 * Math.Cos(factor * i);
                }

                double WinScale = 0;
                for (int i = 0; i < _size; i++)
                {
                    WinScale += window[i];
                }

                double WinScale2 = 0;
                for (int i = 0; i < _size; i++)
                {
                    WinScale2 += (window[i] * window[i]);
                }

                double rms = 0.0;
                int    length = (int)(_size / 2.56);
                double freq, omega, tempResult;
                for (int i = 0; i < length; i++)
                {
                    freq  = i * deltaf;
                    omega = 2 * 4 * Math.Atan(1) * freq;

                    if (0 == i)
                    {
                        fftresult[i] = 0;
                    }
                    else
                    {
                        fftresult[i] = (float)(fftresult[i] * 9.80665f * 1000.0f / omega);
                    }

                    if (integralType == RobinIntegralType.Double)
                    {
                        if (0 == i)
                        {
                            fftresult[i] = 0;
                        }
                        else
                        {
                            fftresult[i] = (float)(fftresult[i] * 1000.0f / omega);
                            /// [김보근]
                            /// 변위인 경우 rms --> peak --> peak to peak로 변환하기 위해서 fft 결과 데이터에 루트 2로 나누고 2를 곱해줌
                            /// fftresult[i] = fftresult[i] / sqrt(2.0) * 2.0
                            fftresult[i] = (float)(fftresult[i] / Math.Sqrt(2.0) * 2.0);
                            ////////////////////////////////////////////////////////////////////////////////////////////////////////////
                        }
                    }

                    if ((bandLow <= freq) && (freq <= bandHigh))
                    {
                        tempResult  = fftresult[i] * fftresult[i];
                        tempResult *= (WinScale * WinScale) / (_size * WinScale2);
                        rms        += tempResult;
                    }
                }
                result = Math.Sqrt(rms);
            }
            return(result);
        }
Example #3
0
        //static UnmanagedLibrary vibecDll;
        //[UnmanagedFunctionPointer(CallingConvention.Winapi)]
        //delegate Real BPF_RMSFunc(Real[] asyncData, int length, Real[] f, Real[] y, Real f1, Real f2, Real fs);
        //static BPF_RMSFunc pfBPF_RMS;
        //public static double BPF_RMS(data_type[] x, double[] f, double[] y, double f1, double f2, double Fs)//length = 2^m, the length of h and x = length, the length of f and y = length/2
        //{
        //    if (vibecDll == null)
        //    {
        //        vibecDll = new UnmanagedLibrary("VibeC.dll");
        //        pfBPF_RMS = vibecDll.GetUnmanagedFunction<BPF_RMSFunc>("BPF_RMS");
        //    }

        //    var tempf = new data_type[f.Length];
        //    var tempy = new data_type[y.Length];
        //    var result = pfBPF_RMS(x, x.Length, tempf, tempy, (data_type)f1, (data_type)f2, (data_type)Fs);

        //    for (int i = 0; i < f.Length; i++)
        //    {
        //        f[i] = tempf[i];
        //        y[i] = tempy[i];
        //    }

        //    return result;
        //}

//        //x:async데이타 , f:주파수 length/2개 얻음, y 주파수별 rms, f1: band low 주파수 시작점(Hz), f2: band high주파수 시작점(Hz), Fs: 보드 샘플링 레이트
////plot f, y 하면 바로 스펙트럼
        public static double BPF_RMS(data_type[] x, double[] f, double[] y, double f1, double f2, double Fs, Unit2Type Unit2Type, WindowFunction windowFunc)//length = 2^m, the length of h and x = length, the length of f and y = length/2
        {
            int    length = x.Length;
            int    i;
            double df, sum, rms;
            int    k1, k2, N, half_length;
            var    XH = new Complex[65536];
            double scale;
            //var h = Hann(x.Length);
            var h = GetWindow(windowFunc, x.Length);

            df = Fs / ((double)length);
            k1 = (int)Math.Floor(f1 / df) - 1;
            k2 = (int)Math.Ceiling(f2 / df) + 1;

            half_length = length >> 1;

            scale = 0.0;
            for (i = 0; i < length; i++)
            {
                scale = scale + h[i] * h[i];
            }

            scale = ((double)length) * scale;
            scale = 1.0 / scale;

            if (k1 < 0)
            {
                k1 = 0;
            }
            else if (k1 > half_length)
            {
                k1 = half_length;
            }

            if (k2 < 0)
            {
                k2 = 0;
            }
            else if (k2 > half_length)
            {
                k2 = half_length;
            }

            for (i = 0; i < length; i++)
            {
                XH[i].Real = (data_type)(h[i] * x[i]);
                XH[i].Imag = 0.0f;
            }

            N = (int)Math.Round(Math.Log10((double)length) / Math.Log10(2.0));
            FFT(XH, N);

            //RMS scalar generation
            sum = 0.0;
            for (i = k1; i <= k2; i++)
            {
                sum = sum + XH[i].Real * XH[i].Real + XH[i].Imag * XH[i].Imag;
            }

            rms = Math.Sqrt(scale * 2.0 * sum);

            //RMS vector generation
            scale = 0.0;
            for (i = 0; i < length; i++)
            {
                scale = scale + h[i];
            }

            scale = 1.414214 / scale; //*((double)length);

            switch (Unit2Type)
            {
            case Unit2Type.pk: scale = scale * 1.414213; break;

            case Unit2Type.pp: scale = scale * 2.828427; break;

            default: break;
            }


            for (i = 0; i < half_length; i++)
            {
                f[i] = df * ((double)i);
                y[i] = scale * Math.Sqrt(XH[i].Real * XH[i].Real + XH[i].Imag * XH[i].Imag);
            }
            RMS = rms;
            return(rms);
        }