package net.heartshield.filter;

import net.heartshield.signal.DVec;
import net.heartshield.signal.Signal;

/**
 * Rough envelope detection for heart sounds (phonocardiography),
 * to provide user feedback.
 *
 * Downsamples.
 *
 * @author David Madl (git@abanbytes.eu)
 * @date 2017-05-15
 */
public class PcgEnvelopeFilter extends RFilterBlock {
    private FirFilterRunning mMovingAverage;
    private Downsampler mDownsampler;
    private ButterBandPassFilter mBandPass;
    private RectifierFilter mRectifier;
    private FirFilterRunning mLowPass;
    private double mBackFps;

    private int mDownsamplingRatio = 24; // 48 kHz -> 2 kHz

    public PcgEnvelopeFilter(double frontFps) {
        // note: performance wise, we could do better than these two.
        mMovingAverage = new FirFilterRunning(DVec.ones(mDownsamplingRatio)); // TODO: fps-dependent
        mDownsampler = new Downsampler(frontFps, mDownsamplingRatio);
        mBackFps = mDownsampler.getFps();
        mBandPass = new ButterBandPassFilter(3, mBackFps, 30.0, 250.0);
        mRectifier = new RectifierFilter();
        mLowPass = new FirFilterRunning(Signal.triangle(200));

        mMovingAverage.connect(mDownsampler);
        mDownsampler.connect(mBandPass);
        mBandPass.connect(mRectifier);
        mRectifier.connect(mLowPass);
    }

    public int getDownsamplingRatio() { return mDownsamplingRatio; }

    public double getFps() {
        return mBackFps;
    }

    @Override
    protected double[] batch(double[] x) {
        throw new IllegalStateException();
    }

    @Override
    public void connect(IRFilterBlock consumer) {
        mLowPass.connect(consumer);
    }

    @Override
    public void put(double[] x) {
        mMovingAverage.put(x);
    }
}
