سؤال

أنا محير بسبب النتائج التي أحصل عليها من FFT وسأقدر أي مساعدة.

أنا أستخدم FFTW 3.2.2 ولكن حصلت على نتائج مماثلة مع تطبيقات FFT الأخرى (في Java). عندما آخذ FFT من موجة جيبية ، يعتمد تحجيم النتيجة على تواتر (هرتز) للموجة-على وجه التحديد ، سواء كان ذلك قريبًا من عدد كامل أم لا. يتم تحجيم القيم الناتجة حقًا عندما يكون التردد بالقرب من عدد كامل ، وهي أوامر ذات حجم أكبر عندما يكون التردد بين الأرقام الكاملة. هذا الرسم البياني يوضح حجم الارتفاع في نتيجة FFT المقابلة لتردد الموجة ، لترددات مختلفة. هل هذا صحيح؟؟

لقد راجعت أن FFT العكسي لـ FFT يساوي أوقات الموجة الجيبية الأصلية لعدد العينات ، وهو كذلك. يبدو أن شكل FFT صحيح أيضًا.

لن يكون الأمر سيئًا للغاية إذا كنت أقوم بتحليل موجات الجيب الفردي ، لأنني يمكن أن أبحث عن ارتفاع في FFT بغض النظر عن ارتفاعه. المشكلة هي أنني أريد تحليل مبالغ موجات الجيب. إذا كنت أقوم بتحليل مجموع موجات الجيب في ، على سبيل المثال ، 440 هرتز و 523.25 هرتز ، فإن الارتفاع فقط للواحد عند 523.25 هرتز يظهر. الارتفاع للآخر صغير جدًا لدرجة أنه يبدو وكأنه ضوضاء. يجب أن يكون هناك طريقة لإنجاز هذا العمل لأنه في Matlab يعمل-أحصل على طفرات متشابهة الحجم في كلا الترددات. كيف يمكنني تغيير الكود أدناه لتحديد التحجيم لترددات مختلفة؟

#include <cstdlib>
#include <cstring>
#include <cmath> 
#include <fftw3.h>
#include <cstdio>
using namespace std; 

const double PI = 3.141592;

/* Samples from 1-second sine wave with given frequency (Hz) */
void sineWave(double a[], double frequency, int samplesPerSecond, double ampFactor); 

int main(int argc, char** argv) {

 /* Args: frequency (Hz), samplesPerSecond, ampFactor */
 if (argc != 4)  return -1; 
 double frequency  = atof(argv[1]); 
 int samplesPerSecond = atoi(argv[2]); 
 double ampFactor  = atof(argv[3]); 

 /* Init FFT input and output arrays. */
 double * wave = new double[samplesPerSecond]; 
 sineWave(wave, frequency, samplesPerSecond, ampFactor); 
 double * fftHalfComplex = new double[samplesPerSecond]; 
 int fftLen = samplesPerSecond/2 + 1; 
 double * fft = new double[fftLen]; 
 double * ifft = new double[samplesPerSecond]; 

 /* Do the FFT. */
 fftw_plan plan = fftw_plan_r2r_1d(samplesPerSecond, wave, fftHalfComplex, FFTW_R2HC, FFTW_ESTIMATE);
 fftw_execute(plan); 
 memcpy(fft, fftHalfComplex, sizeof(double) * fftLen); 
 fftw_destroy_plan(plan);

 /* Do the IFFT. */
 fftw_plan iplan = fftw_plan_r2r_1d(samplesPerSecond, fftHalfComplex, ifft, FFTW_HC2R, FFTW_ESTIMATE); 
 fftw_execute(iplan); 
 fftw_destroy_plan(iplan);

 printf("%s,%s,%s", argv[1], argv[2], argv[3]); 
 for (int i = 0; i < samplesPerSecond; i++) {
  printf("\t%.6f", wave[i]); 
 }
 printf("\n"); 
 printf("%s,%s,%s", argv[1], argv[2], argv[3]); 
 for (int i = 0; i < fftLen; i++) {
  printf("\t%.9f", fft[i]); 
 }
 printf("\n"); 
 printf("\n"); 
 printf("%s,%s,%s", argv[1], argv[2], argv[3]); 
 for (int i = 0; i < samplesPerSecond; i++) {
  printf("\t%.6f (%.6f)", ifft[i], samplesPerSecond * wave[i]);  // actual and expected result
 }

 delete[] wave; 
 delete[] fftHalfComplex; 
 delete[] fft; 
 delete[] ifft; 
}

void sineWave(double a[], double frequency, int samplesPerSecond, double ampFactor) {
 for (int i = 0; i < samplesPerSecond; i++) {
  double time = i / (double) samplesPerSecond; 
  a[i] = ampFactor * sin(2 * PI * frequency * time); 
 }
}
هل كانت مفيدة؟

المحلول

يتم تحجيم القيم الناتجة حقًا عندما يكون التردد بالقرب من عدد كامل ، وهي أوامر ذات حجم أكبر عندما يكون التردد بين الأرقام الكاملة.

ذلك لأن تحويل فورييه السريع يفترض أن المدخلات دورية ويتكرر بلا حدود. إذا كان لديك عدد غير هجاء من موجات الجيب ، وقمت بتكرار هذا الشكل الموجي ، فهي ليست موجة جيبية مثالية. هذا يسبب نتيجة FFT التي تعاني من "تسرب طيفي"

تفحص وظائف النافذة. هذه تخفف من المدخلات في البداية والنهاية ، بحيث يتضاءل التسرب الطيفي.

ملاحظة: إذا كنت ترغب في الحصول على محتوى تردد دقيق حول الأساسيات ، فالتقاط الكثير من دورات الموجة ولا تحتاج إلى التقاط الكثير من النقاط لكل دورة (ربما تكون 32 أو 64 نقطة لكل دورة كثيرة). إذا كنت ترغب في الحصول على محتوى تردد دقيق في التوافقيات العليا ، فالتقاط عدد أقل من الدورات ، والمزيد من النقاط لكل دورة.

نصائح أخرى

لا يمكنني إلا أن أوصي بأن تنظر إلى رمز راديو GNU. الملف الذي يمكن أن يكون ذا أهمية خاصة بالنسبة لك هو usrp_fft.py.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top