我当前正在创建一个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])之间的相关性。
但是,我面临一些问题,我没有合理的值(value)。根据我的研究,傅立叶空间中的相关性只是两个傅立叶项之间的复数乘法。从而,
我在做什么就像:
correlation = storage[0]*conj(storage[windowSize+1]);

但是,我有非常大的值(value),这使我想知道我是否真的在计算相关性。

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

非常感谢

最佳答案

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?)的幂。可以通过计算均匀信号(均匀)的自相关来检查。

关于c++ - FFTW3计算同一信号中的互相关,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50837658/

10-12 20:09