FFTW3计算相同信号中的互相关

时间:2018-06-13 12:45:30

标签: c++ c signal-processing fft correlation

我目前正在创建一个C代码,它将wav文件(特别是原始wav文件的一个通道)作为输入,并执行短时傅立叶变换。 代码的主要部分是这一个:

stft_data = (fftw_complex*)(fftw_malloc(sizeof(fftw_complex)*windowSize));

fft_result= (fftw_complex*)(fftw_malloc(sizeof(fftw_complex)*windowSize));

storage = (fftw_complex*)(fftw_malloc(sizeof(fftw_complex)*storage_capacity));

//define the fftw plane
fftw_plan plan_forward;
plan_forward = fftw_plan_dft_1d(windowSize, stft_data, fft_result, FFTW_FORWARD, FFTW_ESTIMATE);

//integer indexes
int i,counter ;
counter = 0 ;
//create a Hamming window
double hamming_result[windowSize];
hamming(windowSize, hamming_result);

//implement the stft position indexes
int chunkPosition = 0; //actual chunk position
int readIndex ; //read the index of the wav file

while (chunkPosition < wav_length ){
    //read the window
    for(i=0; i<windowSize; i++){

      readIndex = chunkPosition + i;

      if (readIndex < wav_length){
        stft_data[i] = wav_data[readIndex]*hamming_result[i]*_Complex_I  + 0.0*I;
      }
      else{
        //if we are beyond the wav_length
        stft_data[i] = 0.0*_Complex_I + 0.0*I;//padding
        break;
      }
    }
    //compute the fft
    fftw_execute(plan_forward);
    //store the stft in a data structure
    for (i=0; i<windowSize;i++)
    {
      //printf("RE: %.2f  IM: %.2f\n", creal(fft_result[i]),cimag(fft_result[i]));
      storage[counter] = creal(fft_result[i]) + cimag(fft_result[i]);
      counter+=1;
    }

    //update indexes
    chunkPosition += hop_size;
    printf("Chunk Position %d\n", chunkPosition);
    printf("Counter position %d\n", counter);
    printf("Fourier transform done\n");

}  

将FFT计算到所选窗口后,我将FFT实部和虚部存储到storage变量中。

之后,我想计算最终N个窗口中每个窗口中数据点之间的互相关性。 作为示例,我想计算第一个窗口的第一个数据点(storage[0])与第二个窗口的第一个元素(storage[windowSize+1])之间的相关性。 但是,我遇到了一些问题,而且我没有合理的价值观。根据我所研究的,傅里叶空间中的相关性只是两个傅立叶项之间的复数乘法。从而, 我正在做的是:

correlation = storage[0]*conj(storage[windowSize+1]);

但是,我得到了非常巨大的值,这让我想知道我是否真的在计算相关性。

我哪里错了? 我应该如何扩展我的相关结果? 我应该如何计算与傅立叶值的相关性? 然后,我应该如何绘制FFTW3计算中的傅立叶值?我应该转移所有值还是已经转移了?

非常感谢

1 个答案:

答案 0 :(得分:1)

storage[counter] = creal(fft_result[i]) + cimag(fft_result[i]);使存储纯粹是真实的。由于计算correlation = storage[0]*conj(storage[windowSize+1]);是计算互相关的下一步,因此存在问题。实际上,结合实数是没有意义的。

尝试storage[counter] = fft_result[i];可以部分解决问题。 此外,correlation = storage[0]*conj(storage[windowSize+1]);应修改为correlation = storage[0]*conj(storage[windowSize]);

通过执行correlation = storage[0]*conj(storage[windowSize]);,获得相关性的DFT的索引[0]的大小。实际上,storage[0]对应于第一帧的平均值,而storage[windowSize]对应于第二帧的平均值。它不等于平均值​​,但更大,因为它是按帧windowSize的长度缩放的。

要计算两个信号之间的相关性,下一步应该是:

for (i=0; i<windowSize;i++)
{
    dftofcorrelation[i]=storage[i]*conj(storage[i+windowSize]
}

然后,必须将反DFT应用于数组dftofcorrelation以获得作为数组的相关性。必须记住,FFTW的前向和后向DFT都不包括任何缩放,请参阅what FFTW really computes

fftw_execute(plan_backward);

如果要保留此相关数组的两个标量,则它是最大值(如果信号类似于延迟,则为高)和最大值的索引,即两个信号之间的估计时间偏移。

FFTW引起的整体缩放是windowSize(windowSize ^ 3?)的幂。可以通过计算均匀信号的自相关(均匀)来检查它。