66 lines
1.5 KiB
TypeScript
66 lines
1.5 KiB
TypeScript
import type { AudioProcessor, ProcessorCategory } from './AudioProcessor';
|
|
|
|
export class HighPassSweepDown implements AudioProcessor {
|
|
getName(): string {
|
|
return 'HP Sweep Down';
|
|
}
|
|
|
|
getDescription(): string {
|
|
return 'Sweeps a high-pass filter from thin to full';
|
|
}
|
|
|
|
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 = 8000;
|
|
const endFreq = 20;
|
|
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];
|
|
}
|
|
}
|