# 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 '19 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. – pffelix Nov 23 '19 at 15:22
• @Bob do you want to explain in more detail what you meant with the simple formula? – pffelix Nov 23 '19 at 15:32
• Here is a link to the formula I mentioned ccrma.stanford.edu/~jos/sasp/… – Bob Nov 24 '19 at 6:21
• @Bob very helpful, thanks for the formula! – pffelix Nov 24 '19 at 9:23

## 1 Answer

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)];
y = y .* fade;
y_inv = y_inv .* fade;
y_matched = conv(y, y_inv);
figure(236)
plot(y_matched)

% plot
fvtool(y)