-
Notifications
You must be signed in to change notification settings - Fork 115
Open
Description
When calling resample
with a floating-point value, it takes a different codepath than with a rational value. The floating-point version seems more susceptible to aliasing issues.
Here is an example, minimized from a real-world issue, that demonstrates the problem:
using DSP, CairoMakie
function hpf(x, freq; fs)
return filtfilt(digitalfilter(Highpass(freq; fs), Butterworth(4)), x)
end
function lpf(x, freq; fs)
return filtfilt(digitalfilter(Lowpass(freq; fs), Butterworth(4)), x)
end
function middle_third(x)
third = div(length(x), 3)
return x[third:(2 * third + 1)]
end
function plt_filters(x; fs)
x = lpf(x, 35.0; fs)
x = hpf(x, 0.5; fs)
return x
end
sine_wave(freq_hz) = sin.(2π .* freq_hz .* ts)
n = 45 # seconds
fs = 250
ts = range(0, n; length=fs * n)
data = 0.05 * sine_wave(0.75) + 0.01 * sine_wave(5.0) + 0.025 * sine_wave(10.0) +
# lots of high frequency noise
sum(100 * sine_wave(f) for f in 90:125)
resampling_ratio = 1 / 1.00592
resampled = resample(data, resampling_ratio)
ts_resampled = resample(ts, resampling_ratio)
rational_resampled = resample(data, rationalize(resampling_ratio))
rational_ts_resampled = resample(ts, rationalize(resampling_ratio))
# individual axes
fig = let
fig = Figure()
colors = Makie.wong_colors()
ax_kwargs = (; ylabel="Data", limits=(nothing, nothing, -1, 1))
ax1 = Axis(fig[1, 1]; ax_kwargs...)
l1 = lines!(ax1, middle_third(ts), middle_third(plt_filters(data; fs)); color=colors[1])
ax2 = Axis(fig[2, 1]; ax_kwargs...)
l2 = lines!(ax2, middle_third(ts_resampled), middle_third(plt_filters(resampled; fs));
color=colors[2])
ax3 = Axis(fig[3, 1]; xlabel="Time (s)", ax_kwargs...)
l3 = lines!(ax3, middle_third(rational_ts_resampled),
middle_third(plt_filters(rational_resampled; fs)); color=colors[3])
Legend(fig[4, 1], [l1, l2, l3], ["original", "resampled", "rational resampled"];
orientation=:horizontal)
fig
end
save("mwe.png", fig)
# combined
fig = let
fig = Figure()
colors = Makie.wong_colors()
ax_kwargs = (; ylabel="Data", limits=(nothing, nothing, -1, 1))
ax = Axis(fig[1, 1]; xlabel="Time (s)", ax_kwargs...)
lines!(ax, middle_third(ts_resampled), middle_third(plt_filters(resampled; fs));
color=colors[2], label="resampled")
lines!(ax, middle_third(rational_ts_resampled),
middle_third(plt_filters(rational_resampled; fs)); color=colors[3],
label="rational resampled")
lines!(ax, middle_third(ts), middle_third(plt_filters(data; fs)); color=colors[1],
label="original")
axislegend(ax)
fig
end
save("mwe-combined.png", fig)
fig
Metadata
Metadata
Assignees
Labels
No labels