import type { AudioProcessor, ProcessorCategory } from './AudioProcessor';

export class LowPassSweepUp implements AudioProcessor {
	getName(): string {
		return 'LP Sweep Up';
	}

	getDescription(): string {
		return 'Sweeps a low-pass filter from dark to bright';
	}

	getCategory(): ProcessorCategory {
		return 'Filter';
	}

	process(leftIn: Float32Array, rightIn: Float32Array): [Float32Array, Float32Array] {
		const length = leftIn.length;
		const leftOut = new Float32Array(length);
		const rightOut = new Float32Array(length);

		const sampleRate = 44100;
		const startFreq = 100;
		const endFreq = 18000;
		const Q = 1.5;

		let lx1 = 0, lx2 = 0, ly1 = 0, ly2 = 0;
		let rx1 = 0, rx2 = 0, ry1 = 0, ry2 = 0;

		let b0 = 0, b1 = 0, b2 = 0, a1 = 0, a2 = 0;

		for (let i = 0; i < length; i++) {
			if (i % 64 === 0) {
				const t = i / length;
				const freq = startFreq * Math.pow(endFreq / startFreq, t);
				const omega = 2.0 * Math.PI * freq / sampleRate;
				const alpha = Math.sin(omega) / (2.0 * Q);

				const a0 = 1.0 + alpha;
				b0 = ((1.0 - Math.cos(omega)) / 2.0) / a0;
				b1 = (1.0 - Math.cos(omega)) / a0;
				b2 = b0;
				a1 = (-2.0 * Math.cos(omega)) / a0;
				a2 = (1.0 - alpha) / a0;
			}

			const lx0 = leftIn[i];
			const rx0 = rightIn[i];

			leftOut[i] = b0 * lx0 + b1 * lx1 + b2 * lx2 - a1 * ly1 - a2 * ly2;
			rightOut[i] = b0 * rx0 + b1 * rx1 + b2 * rx2 - a1 * ry1 - a2 * ry2;

			lx2 = lx1;
			lx1 = lx0;
			ly2 = ly1;
			ly1 = leftOut[i];

			rx2 = rx1;
			rx1 = rx0;
			ry2 = ry1;
			ry1 = rightOut[i];
		}

		return [leftOut, rightOut];
	}
}
