I want to calculate delay between an input and an output audio signal of my audio processing system. The input and output signals are available as signed 16 bit integers. To try out, I tried the autocorrelation of the input signal with the following numpy commands:

import numpy as np
import wave
wfp = wave.open('test.wav', 'rb')
samples = wfp.readframes(wfp.getnframes())
signal = np.frombuffer(samples, np.int16)
corr = np.correlate(signal, signal, "full")

I assumed that the peak of the autocorrelation is always at lag 0, which is at the index corr.size / 2 in the corr array. However I get different values for the index, when I calculate np.argmax(corr).

When I normalize the signal first to get values between -1.0 and +1.0, the peak is always at corr.size / 2 as expected, at least in my tests with different signals.

For normalization, I used the following steps:

signal = signal / float(0xFFFF)

Can someone please explain to me, why I have to normalize the signal.

  • 1
    $\begingroup$ If you want to measure time delay, shouldn't you be looking at two signals? Also, you aren't required to normalize; you indicated that you see similar results with and without normalization. $\endgroup$
    – Jason R
    Dec 17 '13 at 16:59
  • 1
    $\begingroup$ Are you having an integer overflow problem? $\endgroup$
    – Aaron
    Dec 17 '13 at 17:03
  • $\begingroup$ Thanks for the suggestion of integer overflow. This is plausible. I am not used to care for integer overflow in python, but here I specified int16 as dtype of the array. $\endgroup$
    – Emil
    Dec 20 '13 at 20:42
  • $\begingroup$ Your signal becomes float dtype after normalizing, right? So it won't have integer overflow if you do that before the correlation. Incidentally scipy.signal.fftconvolve(a, b[::-1]) is equivalent to numpy.correlate(a, b), but much faster. $\endgroup$
    – endolith
    Jun 6 '14 at 13:36

Having had the same problem and without success to find a tool to sync the start of video/audio recordings automatically, I decided to make syncstart (github).

The basic code is this:

import numpy as np
from scipy import fft
from scipy.io import wavfile
r1,s1 = wavfile.read(in1)
r2,s2 = wavfile.read(in2)
assert r1==r2, "syncstart normalizes using ffmpeg"
fs = r1
ls1 = len(s1)
ls2 = len(s2)
padsize = ls1+ls2+1
padsize = 2**(int(np.log(padsize)/np.log(2))+1)
s1pad = np.zeros(padsize)
s1pad[:ls1] = s1
s2pad = np.zeros(padsize)
s2pad[:ls2] = s2
corr = fft.ifft(fft.fft(s1pad)*np.conj(fft.fft(s2pad)))
ca = np.absolute(corr)
xmax = np.argmax(ca)
if xmax > padsize // 2:
    file,offset = in2,(padsize-xmax)/fs
    file,offset = in1,xmax/fs
  • $\begingroup$ This is the same answer as in stackoverflow.com/a/66285894/1803897. It is also the same problem, just the delay here will be small. I don't know whether one can/should mark questions as duplicates across stackXXX sites. $\endgroup$ Feb 20 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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