# Detect playback position in swept sine sweep

I am wondering what the most precise method is to detect the playback sample position of a sine sweep? The real playback sample position is unknown and an DSP with constraint computing capabilities shoud be used for the estimation, recording the playback by an external microphone.

In the concrete case the sine sweep is repeatedly played with fixed duration in the ultrasound range and a microphone 50 cm away from the loudspeaker is used to record the chirp and detect the playback position. After each single chirp playback might be a delay, whereby the delay time is known and doesn't change. Real-word noise is given in the background, which might be as loud as the ultrasound playback. One period of the sine sweep looks like this:

As visible, the frequency in the chirp is either linear or exponentially increasing from a low frequency to a high frequency, fade in and fade out is applied and the chirp duration is 100ms with 44kHz sampling rate.

• Matched filter? Find the index of the peak value. If single-sample accuracy is not good enough you can always use quadratic interpolation to find the true peak. There’s a simple formula for finding the location of the peak.
– Bob
Nov 22, 2019 at 21:08
• good idea! Below also some Matlab code where this principle can be tested. The peak after applying the machted filter shifts linearly with the playback sample position. Nov 23, 2019 at 15:22
• @Bob do you want to explain in more detail what you meant with the simple formula? Nov 23, 2019 at 15:32
• Here is a link to the formula I mentioned ccrma.stanford.edu/~jos/sasp/…
– Bob
Nov 24, 2019 at 6:21
• @Bob very helpful, thanks for the formula! Nov 24, 2019 at 9:23

Attached Matlab sample code to apply an matched filter to a sine sweep for finding the playback position (the playback position estimate can be derived as the position of the peak in the matched filter plot):

% params

sampling_rate = 44000;
f_low = 10;
f_high = 100;
shift_percent = 0.0;
shift_samples = 30000;

% init
t = 0:1/sampling_rate:1;
N = length(t);
y = chirp(t,f_low,1,f_high, "linear");
y_inv = flip(y);
if(shift_percent ~= 0.0)
y = circshift(y, round(shift_percent * N));
else
y = circshift(y, shift_samples);
end
figure(235)
plot(y)
fade = [linspace(0, 1, (N/2)), linspace(1, 0, (N/2) + 1)];