8
$\begingroup$

Before anyone yells at me I fully realize that this question has been asked numerous times. I assure you that I've read through the existing questions and answers but I am still confused about part of the problem.

I have a sound source that plays music (A) in a closed environment. I have a mic that I'm using to record A. I am left with two wav files which share the same characteristics and length (number of samples).

My goal is calculate the time it took for A to reach the mic.

I am trying to perform the calculation using cross-correlation (numpy):

# Delay estimation
corr = numpy.convolve(original_audio, recorded_audio, 'full')
delay = int(len(corr)/2) - numpy.argmax(corr)
distance = delay / sample_rate * 343 # sample_rate == 22050, m/s = speed of sound
print("Distance full: %.2f cm" % (distance * 100))

I consistently obtain values in the 300,000 cm range. The distance between the speaker and mic is approximately 2 feet.

This is all pretty new to me so I'm sure I'm missing something obvious.

Thanks in advance.

$\endgroup$
2
  • 3
    $\begingroup$ Are you sure you shouldn't be using numpy.correlate instead of numpy.convolve? To estimate delay, you want to cross-correlate your signals, not convolve them. You'll possibly end up with a much larger delay by convolving. $\endgroup$
    – Peter K.
    May 8, 2013 at 18:01
  • $\begingroup$ PeterK is likely correct. Note that you can implement correlation via convolution by time-reversing and conjugating one of the inputs first. This can allow you to use fast convolution algorithms (like overlap-save) for correlation. $\endgroup$
    – Jason R
    May 8, 2013 at 18:20

1 Answer 1

8
$\begingroup$

Are you sure you shouldn't be using numpy.correlate instead of numpy.convolve? To estimate delay, you want to cross-correlate your signals, not convolve them. You'll possibly end up with a much larger delay by convolving.

Trying something simple:

x = [1, 0, 0, 0, 0 ];
y = [0, 0, 0, 0, 1 ];
conv = numpy.convolve(x,y); 
conv
array([0, 0, 0, 0, 1, 0, 0, 0, 0])
corr = numpy.correlate(x,y,"full");
corr
array([1, 0, 0, 0, 0, 0, 0, 0, 0])
$\endgroup$
1
  • 3
    $\begingroup$ This is exactly what I was looking for. Another example I had seen used convolution and it hadn't occurred to me that direct correlation would be the correct choice. Thank you. $\endgroup$
    – CaymanEss
    May 8, 2013 at 22:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.