package net.heartshield.filter;

/**
 * Downsamples by an integer ratio.
 *
 * @author David Madl (git@abanbytes.eu)
 * @date 2017-03-30
 */
public class Downsampler extends RFilterBlock {
    private int N; // left samples
    private int M; // modulus
    private double mFps;

    public Downsampler(double fpsIn, int ratio) {
        if(ratio <= 0)
            throw new IllegalArgumentException("ratio must be >= 1");
        M = ratio;
        N = M;

        mFps = fpsIn / ratio;

        this.mDownsamplingRatio = ratio;
    }

    /** downsampled output FPS */
    public double getFps() { return mFps; }

    @Override
    protected double[] batch(double[] x) {
        /*
         * N  left samples  1 <= N <= M
         * L  input length  0 < L
         * M  modulus       1 <= M
         *
         *      N      ||        L
         * +---+---+---++---+---+---+---+---+
         * |   |   |   ||   |   |   |   |   |
         * +---+---+---++---+---+---+---+---+
         */

        int L = x.length;

        // too short to give even a single sample
        if(N + L <= M) {
            N += L;
            return new double[0];
        }

        int start = M - N;
        int outLen = (N + L - 1) / M;

        double[] ret = new double[outLen];

        int j = 0;
        for(int i = start; i < L; i += M)
            ret[j++] = x[i];

        N = (N + L - 1) % M + 1;

        return ret;
    }
}
