Simple adaptive AR filters. We export two functions:
yh = adaptive_filter(y, alg=MSPI; order=4, lr=0.1)
This filters y
with an adaptive AR (only poles) filter with specified order and returns yh
which is the predicted output from an adaptive line enhancer (ALE). If your noise is wideband and signal narrowband, yh
is your desired filtered signal. If the noise is narrowband and the signal is wideband, then y-yh
is your desired filtered signal.
Arguments:
alg
: Stochastic approximation algorithm or weight function. Examples:OMAP, MSPI, OMAS, ADAM, ExponentialWeight, EqualWeight
.ExponentialWeight
corresponds to the recursive least-squares algorithm (RLS).ADAM
corresponds roughly to the normalized least-mean squares (NLMS) algorithm. More options exist if OnlineStats is loaded.y
: Input signalorder
: Filter orderlr
: Learning rate or weight depending onalg
The function
focused_adaptive_filter(y, band, fs, args...; kwargs...)
allows you to specify a frequency band (tuple) in which to focus the attention of the adaptive filter. fs
here denotes the sample rate, e.g., 44100Hz.
using Pkg; Pkg.add("AdaptiveFilters")
using AdaptiveFilters, Plots, Interact
inspectdr() # Preferred plotting backend for waveforms
y = [sin.(1:100) .+ 0.1.*randn(100);
sin.(0.2 .*(1:100)) .+ 0.1.*randn(100)]
function app(req=nothing)
@manipulate for order = 2:2:10,
lr = LinRange(0.01, 0.99, 100),
alg = [ExponentialWeight, MSPI, OMAP, OMAS, ADAM]
yh = adaptive_filter(y, alg, order=order, lr=lr)
e = y.-yh
plot([y yh], lab=["Measured signal" "Prediction"], layout=(2,1), show=false, sp=1)
plot!(e, lab="Error", sp=2, title="RMS: $(√mean(abs2, e))")
end
end
app()
# Save filtered sound to disk
using WAV
yh = adaptive_filter(y, 4, 0.25, OMAP)
e = y.-yh
wavwrite(e, "filtered.wav"), Fs=fs)
This is a lightweight wrapper around functionality in OnlineStats.jl which does all the heavy lifting.
- First install Julia and install this package in Julia.
- Install pyjulia using their instructions.
- Now the following should work
$ python3
>>> import julia
>>> from julia import AdaptiveFilters as af
>>> yh = af.adaptive_filter(y)
if that fails, try replacing the first line with
>>> from julia.api import Julia
>>> jl = Julia(compiled_modules=False)
Keyword args etc. work as normal
af.adaptive_filter(y, af.ADAM, order=2)
The following function does a reasonable job at filtering out the sound of cicadas from an audio recording
cicada_filter(y,fs,args...; kwargs...) = y-focused_adaptive_filter(data,(4200,11000),fs,args...; kwargs...)