我当前正在创建一个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/