8

can someone tell how to do the cross-correlation of two speech signals (each of 40,000 samples) in MATLAB without using the built-in function xcorr and the correlation coefficient?

Thanks in advance.

Amro
  • 123,847
  • 25
  • 243
  • 454
jay
  • 89
  • 1
  • 1
  • 4
  • Like, but also not like, http://stackoverflow.com/questions/7036628/xcorr-for-autocorrelation-with-nan-values – Alex Sep 13 '11 at 05:45
  • @jay: if this is homework, please tag as such – Amro Oct 01 '11 at 01:33
  • related question: [Calculate autocorrelation using FFT in matlab](http://stackoverflow.com/questions/3949324/calculate-autocorrelation-using-fft-in-matlab) – Amro Oct 01 '11 at 01:36

3 Answers3

31

You can do cross-correlations using fft. The cross-correlation of two vectors is simply the product of their respective Fourier transforms, with one of the transforms conjugated.

Example:

a=rand(5,1);
b=rand(5,1);
corrLength=length(a)+length(b)-1;

c=fftshift(ifft(fft(a,corrLength).*conj(fft(b,corrLength))));

Compare results:

c =

    0.3311
    0.5992
    1.1320
    1.5853
    1.5848
    1.1745
    0.8500
    0.4727
    0.0915

>> xcorr(a,b)

ans =

    0.3311
    0.5992
    1.1320
    1.5853
    1.5848
    1.1745
    0.8500
    0.4727
    0.0915
Community
  • 1
  • 1
abcd
  • 41,765
  • 7
  • 81
  • 98
  • I cant use any matlab inbuilt functions. Can you suggest me something else? – jay Sep 13 '11 at 05:30
  • 4
    You should make that clear in your question. You merely disallowed `xcorr` initially. At what point do you consider it ok to use inbuilt functions? Is `2+2` allowed? How about `plus(2,2)`? You should explain why you have these restrictions – abcd Sep 13 '11 at 05:35
  • I apologize for being vague. Since I am doing the cross-correlation between two signals each 40,000 samples this creates some delay in the real-time application for processing the entire 40,000 samples So, I am looking for something else like processing block of samples rather than processing all the samples at a time. I trying to do convolution but could't do it. – jay Sep 13 '11 at 05:41
  • Well, all you need to do is break up your data into smaller blocks of data and use the above. You don't need a different technique. For large sample sizes, FFT approach will be much faster than `xcorr`. If I do the above with 40,000 samples for both `a` and `b`, on my machine, it takes about 0.7 seconds. And if I simply halve it (i.e., 20,000) samples, it takes merely 0.04 seconds and is near instant at 0.006 seconds for 10,000 samples. – abcd Sep 13 '11 at 14:15
  • 1
    @yoda: instead of padding the signals, use the second argument of the FFT function – Amro Oct 01 '11 at 01:32
  • @Amro Uuh, of course! I have no idea what I was smoking that day... Thanks, – abcd Oct 01 '11 at 05:02
4

If there some good reason why you can't use the inbuilt, you can use a convolution instead. Cross-correlation is simply a convolution without the reversing, so to 'undo' the reversing of the correlation integral you can first apply an additional reverse to one of your signals (which will cancel out in the convolution).

wim
  • 338,267
  • 99
  • 616
  • 750
4

Well yoda gave a good answer but I thought I mention this anyway just in case. Coming back to the definition of the discrete cross correlation you can compute it without using (too much) builtin Matlab functions (which should be what Matlab do with xcorr). Of course there is still room for improvment as I did not try to vectorize this:

n=1000;
x1=rand(n,1);
x2=rand(n,1);
xc=zeros(2*n-1,1);
for i=1:2*n-1
    if(i>n)
        j1=1;
        k1=2*n-i;
        j2=i-n+1;
        k2=n;
    else
        j1=n-i+1;
        k1=n;
        j2=1;
        k2=i;
    end
    xc(i)=sum(conj(x1(j1:k1)).*x2(j2:k2));
end
xc=flipud(xc);

Which match the result of the xcorr function.

UPDATE: forgot to mention that in my opinion Matlab is not the appropriate tool for doing real time cross correlation of large data sets, I would rather try it in C or other compiled languages.

Aabaz
  • 3,106
  • 2
  • 21
  • 26