我正在尝试加快 Java 中两个声音文件之间的时间延迟估计算法。我的想法是使用互相关并搜索最高值,这给出了延迟的样本量。
我已经完成了这个并且工作得很好。我创建了一些示例文件,然后计算了时间延迟。结果还不错。问题是,由于运算量很大,该算法需要花费大量时间。
有什么办法可以加快速度吗?
/**
* Input vector for signal x1 (reference).
*/
private double[] x1;
/**
* Input vector for signal x2 (test).
*/
private double[] x2;
/**
* Execute the cross correlation between signal x1 and x2 and calculate the time delay.
*/
public void execCorrelation()
{
// define the size of the resulting correlation field
int corrSize = 2*x1.length;
// create correlation vector
out = new double[corrSize];
// shift variable
int shift = x1.length;
double val;
int maxIndex = 0;
double maxVal = 0;
// we have push the signal from the left to the right
for(int i=0;i<corrSize;i++)
{
val = 0;
// multiply sample by sample and sum up
for(int k=0;k<x1.length;k++)
{
// x2 has reached his end - abort
if((k+shift) > (x2.length -1))
{
break;
}
// x2 has not started yet - continue
if((k+shift) < 0)
{
continue;
}
// multiply sample with sample and sum up
val += x1[k] * x2[k+shift];
//System.out.print("x1["+k+"] * x2["+(k+tmp_tau)+"] + ");
}
//System.out.println();
// save the sample
out[i] = val;
shift--;
// save highest correlation index
if(out[i] > maxVal)
{
maxVal = out[i];
maxIndex = i;
}
}
// set the delay
this.delay = maxIndex - x1.length;
}
最佳答案
如果我没记错的话,互相关与其中一个时间反转信号的卷积相同。通过将两个信号的频谱相乘,可以有效地计算出卷积;即,对每个信号进行 FFT 填充,至少填充到两个信号大小的总和,乘以 FFT 变换后的频谱,进行逆 IFFT,然后搜索峰值。
对于 Java,您可以使用 JTransforms进行 FFT/IFFT。
如果您想在实际实现之前尝试一下这种方法,您可以尝试我的应用程序 FScape ;它有一个卷积模块,需要两个声音文件(您标记了问题“音频处理”,所以我假设您可以生成声音文件)。
关于java - 使用互相关的声音文件的时间延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23610415/