Skip to content

Stream data to digital filter / live IIR filter #548

@s-celles

Description

Hello,

Following discussion started at https://discourse.julialang.org/t/scipy-signal-iirfilter-equivalent-in-dsp-jl-and-more/110783/4 I wonder if DSP.jl provides structure of digital filter which can be used for streaming input data ie processing live data and not a vector of precalculated values ?
ie is there some kind of filter which preserve its state each time a new input is coming.

I did this Pluto.jl notebook https://gist.github.com/scls19fr/0ae16d92ca39d3eb9c42cc0fc618c723 for experimenting this kind of problem (both for filtering a vector of input signal and for displaying streamed signal and output of filter thanks to PlutoUI Clock).

I end up to convert idea mentioned https://www.samproell.io/posts/yarppg/yarppg-live-digital-filter/ with Julia.

OnlineStatsBase.jl API looks interesting for this kind of work (this is API which is used by OnlineStats.jl

So I did

abstract type AbstractLiveFilter{T} <: OnlineStat{T} end

mutable struct LiveDigitalFilter{T} <: AbstractLiveFilter{T}
    value::T
    n::Int

    b::Vector
    a::Vector

    _xs::CircularBuffer
    _ys::CircularBuffer

    function LiveDigitalFilter{T}(pr::PolynomialRatio) where {T}
        b = reverse(pr.b.coeffs)
        a = reverse(pr.a.coeffs)
        _xs = CircularBuffer{T}(length(b))
        fill!(_xs, zero(T))
        _ys = CircularBuffer{T}(length(a) - 1)
        fill!(_ys, zero(T))
        new{T}(0, 0, b, a, _xs, _ys)
    end
end

function reset!(f::LiveDigitalFilter)
    f.n = 0
    empty!(f._xs)
    empty!(f._ys)
    fill!(f._xs, zero(eltype(f.b)))
    fill!(f._ys, zero(eltype(f.a)))	
end

function OnlineStatsBase._fit!(f::LiveDigitalFilter, x)
    f.n += 1
    pushfirst!(f._xs, x)
    y = sum(f.b .* f._xs) - sum(f.a[2:end] .* f._ys)
    y = y / f.a[1]
    pushfirst!(f._ys, y)		
    f.value = y
end

Notebook run on my side at around 10fps.

Any opinion?

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions