我目前正在创建一个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计算中的傅立叶值?我应该转移所有值还是已经转移了?
非常感谢
答案 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?)的幂。可以通过计算均匀信号的自相关(均匀)来检查它。