2017-04-21 21 views
0

입력 신호가 있고 FFT를 계산했습니다. 그 후, 모든 스펙트럼이 아닌 주파수 대역에서 RMS 만 계산해야합니다.각 주파수에서 RMS를 받으십시오.

나는 Parseval의 정리를 적용하여 전체 스펙트럼의 RMS 계산을 해결했지만이 RMS를 "선택적"으로 계산하는 방법은 무엇입니까? 관심있는 세 가지 frecuencies (F0, FC, F1)를 얻으려면 올바르게 계산 된 인덱스가 있지만이 대역폭에 RMS를 적용하면 Parseval의 정리가 유지되지 않습니다.

고유 한 10KHz 주파수를 수신하면 FFT 총 스펙트럼의 RMS가 정확하지만 10KHz 주파수에서 RMS가 선택되면 RMS 올바른 것으로부터 -0.4V의 잘못된 결과를 얻을 수 있으며 거의 ​​동일한 결과를 얻을 수 있습니다. 결과는 스펙트럼에서 하나의 frecuency를 얻었 기 때문입니다.

public static double RMSSelectiveCalculation(double[] trama, double samplingFreq, double F0, double Fc, double F1) 
    { 
    //Frequency of interest   
     double fs = samplingFreq; // Sampling frequency 
     double t1 = 1/fs;   // Sample time 
     int l = trama.Length;  // Length of signal 
     double rmsSelective = 0; 
     double ParsevalB = 0; 
     double scalingFactor = fs; 
     double dt = 1/fs; 

     // We just use half of the data as the other half is simetric. The middle is found in NFFT/2 + 1 
     int nFFT = (int)Math.Pow(2, NextPow2(l)); 
     double df = fs/nFFT; 
     if (nFFT > 655600) 
     { } 

     // Create complex array for FFT transformation. Use 0s for imaginary part 
     Complex[] samples = new Complex[nFFT]; 
     Complex[] reverseSamples = new Complex[nFFT]; 
     double[] frecuencies = new double[nFFT]; 
     for (int i = 0; i < nFFT; i++) 
     { 
      frecuencies[i] = i * (fs/nFFT); 

      if (i >= trama.Length) 
      { 
       samples[i] = new MathNet.Numerics.Complex(0, 0); 
      } 
      else 
      { 
       samples[i] = new MathNet.Numerics.Complex(trama[i], 0); 
      } 
     } 

     ComplexFourierTransformation fft = new ComplexFourierTransformation(TransformationConvention.Matlab); 
     fft.TransformForward(samples); 
     ComplexVector s = new ComplexVector(samples); 
     //The indexes will get the index of each frecuency 
     int f0Index, fcIndex, f1Index; 
     double k = nFFT/fs; 
     f0Index = (int)Math.Floor(k * F0); 
     fcIndex = (int)Math.Floor(k * Fc); 
     f1Index = (int)Math.Ceiling(k * F1); 

     for (int i = f0Index; i <= f1Index; i++) 
     { 
      ParsevalB += Math.Pow(Math.Abs(s[i].Modulus/scalingFactor), 2.0); 
     } 

     ParsevalB = ParsevalB * df; 

     double ownSF = fs/l; //This is a own scale factor used to take the square root after 

     rmsSelective = Math.Sqrt(ParsevalB * ownSF); 

     samples = null; 
     s = null; 

     return rmsSelective; 

    } 
+0

이 아닌 여러 번 전에이 같은 질문을 가지고 예를 들어, [FFT에서 RMS 가져 오기] (http://stackoverflow.com/questions/43452138/getting-rms-from-fft) 및 [FFT에서 RMS 가져 오기] (http://stackoverflow.com/questions/43363860/get-rms -from-fft)? –

답변

0

전력 스펙트럼 밀도 PSD의 추정은 FFT의 크기의 제곱에 의해 주어진다 : 여기 당신은 내 RMS를 선택적 계산을 볼 수 있습니다.

특정 대역폭을 가진 섹션의 RMS는 해당 섹션의 PSD 영역의 루트입니다.

실제적으로, 낮은 주파수와 높은 주파수 사이에서 FFT의 절대 값을 통합하십시오.

MATLAB example

+0

제 대답을 참조하십시오. –