广义互相关问题(PHAT 过滤器)

信息处理 matlab 声音的 互相关
2022-02-22 06:21:04

我必须计算两个信号之间的时间延迟。我使用的是 GCC-PHAT 方法。首先,我将信号切割成更小的部分(约 0.5 秒),然后尝试计算延迟。当我在图表上显示这两个信号时,延迟非常明显。

问题是对于那个长信号的某些部分,我的程序计算了正确的延迟,但对于某些部分,延迟是完全不正确的。在这两种情况下,当我在图表上显示这两个信号时,延迟似乎非常明显。

相关代码:

duration=20000
a=hanning(duration+1)
[signal1,Fs] = audioread(mic1);
[signal2,Fs] = audioread(mic2);

start=1000;
stop=start+duration;
x1=[a.*signal1(start:stop)];
x2=[a.*signal2(start:stop)];

A=fft(x1);
B=fft(x2);

PHAT=A.*conj(B)./(abs((A).*conj(B)));   
result=abs(ifft(PHAT)); 

示例: 1) 正确结果: 互相关结果和对应信号

2)不正确的结果:

互相关结果和对应信号

我在一个封闭的房间里录制了这些信号,所以可能还有混响。难道我做错了什么?或者这种方法在我的情况下不是很有效?

我也尝试对信号进行预过滤,但结果是一样的。如果我改变信号的长度,也没有任何改善。

2个回答

使用 gcc-phat 方法,您可以使用 matlab 函数“gccphat(s2,s1,fs)”(R2016a),其中 s1 为参考信号,s2 为另一个,fs 为采样频率。

基本上它会做类似的相关计算:

  Ncorr = 2*N-1;  % N size of the signal
  NFFT = 2^nextpow2(Ncorr);
  R12 = bsxfun(@times,fft(s2,NFFT),conj(fft(s1,NFFT)));
  r12_temp = fftshift(ifft(exp(1i*angle(R12))),1);
  r12 = r12_temp(NFFT/2+1-(N-1)/2:NFFT/2+1+(N-1)/2,:);

与您的代码的唯一区别是 matlab 函数对 fft 使用最接近的两个序列长度的幂(正如 Peter.K 建议的“Nfft = length(x1) + length(x2) - 1”)并做指数的东西(这部分与常规相关性有所不同,你在做什么)

但是要返回时间延迟,该函数正在做另一个技巧:

  lags = (-(Ncorr-1)/2:(Ncorr-1)/2).';
  lags = lags/fs;
  [~,idx] = max(abs(r12));
  tau = ts/(2*fs)+lags(idx); % ts as the total sample of the signal

我正在做类似的实验,这种方法适用于长短不移动的信号。房间的混响可能会导致一些问题,但如果您在显示信号时可以看到明显的延迟,它应该可以正常工作。

现在,我很难用移动的源返回良好的时间延迟(函数返回 0 或 +/- 信号的长度)而且我仍在努力......所以如果有人领先,这将是非常apreciate ;-)

希望这会帮助你。

和平

PS:另外,在执行 fft/ifft 时,您确实应该使用 fftshift/ifftshift,因为 matlab fft/ifft 在此过程中混合了一些东西。

我怀疑您对时域混叠有疑问。

代替

A=fft(x1);
B=fft(x2);

尝试

Nfft = length(x1) + length(x2) - 1;
A=fft(x1, Nfft);
B=fft(x2, Nfft);