2015-09-03 3 views
0

Я пытаюсь создать спектрограмму синусоидального сигнала с C++. Для создания спектрограммы:Spectrogram with C++

  1. Я разделил реальный синусоидальный сигнал в B блоки
  2. окно Прикладной Ханнинги к каждому блоку (я предположил, что нет перекрытия). Это должно дать мне данные для fft.
  3. Применяет FFT к каждому блоку, и вычислил величину от частотных коэффициентов u[i][0] и u[i][1] и положить его в v[k][i] где к есть число блоков и I образцы каждого окна
  4. Подготовленное время tt[k] против v[k][i]

Это дает мне следующий сюжет:

enter image description here

Однако этот сюжет делает п Посмотрите правильно.

Любые предложения, чтобы заставить его работать? Вот мой код:

#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 
#include <fftw3.h> 
#include <iostream> 
#include <cmath> 
#include <fstream> 
using namespace std; 
int main() 
{ 
    int i; 
    int N=500;//Number of points acquired inside the window 
    double Fs=200;//sampling frequency 
    int windowsize=100;//Number of samples in each block 
    double T=1/Fs;//sample time 
    double f=50;//frequency(Hz) 
    double *in; 
    fftw_complex *out; 
    double t[N];//time vector 
    double tt[5]; 
    double v [5][249]; 
    fftw_plan plan_forward; 
    in = (double*) fftw_malloc(sizeof(double) * N); 
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (N/2 + 1)); 

    for (int i=0; i<= N;i++) 
    { 
    t[i]=i*T; 

    in[i] =0.7 *sin(2*M_PI*f*t[i]);// generate sine waveform 
    } 

    plan_forward = fftw_plan_dft_r2c_1d (windowsize, in, out, FFTW_ESTIMATE); 

    for (int k=0; k< 5;k++){ 
    for (int i = 0; i<windowsize; i++){ 
     double multiplier = 0.5 * (1 - cos(2*M_PI*i/(windowsize-1)));//Hanning Window 
     in[i] = multiplier * in[i+k*windowsize]; 
     fftw_execute (plan_forward); 
     v[k][i]=(20*log10(sqrt(out[i][0]*out[i][0]+ out[i][1]*out[i][1])))/N;//The magnitude in dB 
    } 
    } 

    for (int k=0; k< 5;k++){//Center time for each block 

    tt[k]=(2*k+1)*T*(windowsize/2); 

    } 

    fstream myfile; 
    myfile.open("example2.txt",fstream::out); 

    myfile << "plot '-' using 1:2" << std::endl; 

    for (int k=0; k< 5;k++){ 
    myfile << v[k][i]<< " " << tt[k]<< std::endl; 
    } 
    myfile.close(); 
    fftw_destroy_plan (plan_forward); 
    fftw_free (in); 
    fftw_free (out); 
    return 0; 
} 
+0

Что вы имеете в виду "выглядит не так"? – CinCout

+0

Я попытаюсь опубликовать более полный ответ позже, но быстро самая очевидная проблема заключается в том, что вы только записываете 'tt' (а не время и данные) в файл, а затем пытаетесь построить его как ax vs. y (тогда как у вас действительно есть 2D-данные как функция времени, поэтому вам понадобится 3D-график). Кроме того, 'fftw_execute' следует вызывать на каждом блоке данных, а не для каждого отдельного образца, поданного в ваш буфер ввода. – SleuthEye

+0

Это была опечатка. Я попытался увидеть результаты tt и забыл вернуть его в tt vs v, но сюжет для myfile << v [k] [i] << "" << tt [k] << std :: endl; – Jack

ответ

2

enter image description here

#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 
#include <fftw3.h> 
#include <iostream> 
#include <cmath> 
#include <fstream> 
using namespace std; 

int main() 
{ 
int i; 
int N=500; 
double Fs=200;//sampling frequency 
int windowsize=100;//Number of points acquired inside the window 
double dF=Fs/N; 
double T=1/Fs;//sample time 
double f=50;//frequency 
double *in; 
fftw_complex *out; 
double t[N];//time vector 
double ff[N]; 
double tt[5]; 
double v [5][249]; 
fftw_plan plan_forward; 
in = (double*) fftw_malloc(sizeof(double) * N); 
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * (N/2 + 1)); 

for (int i=0; i<= N;i++) 
{ t[i]=i*T; 
in[i] =0.7 *sin(2*M_PI*f*t[i]);// generate sine waveform 
} 

plan_forward = fftw_plan_dft_r2c_1d (windowsize, in, out, FFTW_ESTIMATE); 

for (int k=0; k< 5;k++){ 
    for (int i = 0; i<windowsize; i++){ 
    double multiplier = 0.5 * (1 - cos(2*M_PI*i/(windowsize-1)));//Hanning Window 
in[i] = multiplier * in[i+k*windowsize]; 
            } 
fftw_execute(plan_forward); 
for (int j = 0; j <= ((windowsize/2)-1); j++){ 
v[k][j] = 2*(out[j][0] * out[j][0] + out[j][1] * out[j][1])/(N*N); 
v[k][0] *= 0.5; 
v[k][N/2] *= 0.5; 

for (int j = 0; j <= windowsize/2; j++){ 
    v[k][j] = 10 * log10(v[k][j] + 1e-5); 
             } 
        } 

for (int j = 0; j <= ((windowsize/2)-1); j++) 
    {ff[j]=Fs*j/windowsize; 
    } 

//Center time for each block 

for (int k=0; k< 5;k++){ 

tt[k]=(2*k+1)*T*(windowsize/2); 
         } 

double b[6]; 
fstream myfile; 

myfile.open("data.txt",fstream::out); 

myfile << "plot '-' using 1:2" << std::endl; 

for (int k=0; k< 6;k++) { 
        b[0]=5; 
        b[k+1]=tt[k]; 
        myfile <<b[k] << "\t"; 
        } 
myfile<< std::endl; 

for (int j = 0; j <= windowsize/2; j++){ myfile << ff[j]<< "\t"; 

    for (int k=0; k< 5;k++){ myfile << v[k][j]<< "\t"; 

          } 
myfile<< std::endl; 
            } 
myfile.close(); 

fftw_destroy_plan (plan_forward); 
fftw_free (in); 
fftw_free (out); 
return 0; 
}