package com.foxx.androidcast.receiver.av;

/**
 * Lightweight clarity chain (no ML): DC/high-pass, noise gate, gentle presence, limiter.
 * Aligns with receiver live path in {@code AV_QUALITY_QA_SESSION.md} §8A audio.
 */
public final class ImmersiveAudioFilter implements AudioFilter {
    private float hpL;
    private float hpR;
    private float env;
    private int channels;

    @Override
    public void reset(int sampleRate, int channels) {
        this.channels = Math.max(1, channels);
        hpL = hpR = env = 0f;
    }

    @Override
    public void process(byte[] pcm, int bytes, int sampleRate, int channels, int intensity) {
        if (intensity <= 0 || sampleRate <= 0) {
            return;
        }
        if (this.channels != channels) {
            reset(sampleRate, channels);
        }
        float g = PcmAudioFilters.intensityGain(intensity);
        float hpAlpha = (float) (1.0 - Math.exp(-2.0 * Math.PI * 90.0 / sampleRate));
        float envAlpha = (float) (1.0 - Math.exp(-2.0 * Math.PI * 12.0 / sampleRate));
        float gateThresh = 0.008f * (1f - 0.5f * g);
        float presence = 0.15f * g;
        float ceiling = 0.98f - 0.05f * g;
        PcmAudioFilters.process16Le(pcm, bytes, channels, (sample, ch, frame) -> {
            float hp = ch == 0 ? hpL : (ch == 1 ? hpR : hpL);
            hp += hpAlpha * (sample - hp);
            if (ch == 0) {
                hpL = hp;
            } else if (ch == 1) {
                hpR = hp;
            }
            float x = sample - hp;
            float ax = Math.abs(x);
            env += envAlpha * (ax - env);
            if (env < gateThresh) {
                x *= 0.25f + 0.75f * (env / Math.max(gateThresh, 1e-6f));
            }
            float bright = x + presence * (x - hp);
            return Math.max(-ceiling, Math.min(ceiling, bright * (1f + 0.08f * g)));
        });
    }
}
