You are not recognized as the original poster of this topic.
const TAU=Math.PI*2;
function sineWindow(x){ //x: 0 to 1
return Math.sin(TAU*(x-.25))*.5+.5;
}
function multiply(a,b){return{r:a.r*b.r-a.i*b.i,i:a.r*b.i+a.i*b.r};}
function add(a,b){return{r:a.r+b.r,i:a.i+b.i};}
function subtract(a,b){return{r:a.r-b.r,i:a.i-b.i};}
function FFT(a,invert=false){
let n=a.length;
if(n===1)return;
if(Math.log2(n)%1!==0)throw new Error("Length isn't a power of 2.");
let a0=new Array(n/2),a1=new Array(n/2);
for(let i=0;2*i<n;i++){a0[i]=a[2*i];a1[i]=a[2*i+1];}
FFT(a0,invert);FFT(a1,invert);
let ang=TAU/n*(invert?-1:1),
wn={r:Math.cos(ang),i:Math.sin(ang)},
w={r:1,i:0};
for(let i=0;i<n/2;i++){
let even=a0[i],odd=multiply(w,a1[i]),
sum=add(even,odd),difference=subtract(even,odd);
a[i]=sum;a[i+n/2]=difference;
if(invert){
a[i].r/=2;a[i].i/=2;
a[i+n/2].r/=2;a[i+n/2].i/=2;
}
w=multiply(w,wn);
}
}
let mod=(n,m)=>(n%m+m)%m,
read=(a,i)=>a[mod(Math.floor(i),a.length)],
sine=x=>Math.sin(x*TAU),
mix=(a,b,x)=>a+(b-a)*x;
class realtimeFFT{
constructor(size=11){
this.FFT_SIZE=2**size;
this.inputBuffer=[new Float32Array(this.FFT_SIZE).fill(0),new Float32Array(this.FFT_SIZE).fill(0)];
this.outputBuffer=[new Float32Array(this.FFT_SIZE).fill(0),new Float32Array(this.FFT_SIZE).fill(0)];
this.bufferIndex=[0,-(2**size)*.5];
}
process(x,t){
//record input
this.inputBuffer[0][this.bufferIndex[0]]=x;
if(this.bufferIndex[1]>=0)
this.inputBuffer[1][this.bufferIndex[1]]=x;
//windowing
let win=sineWindow,
o=this.outputBuffer[0][this.bufferIndex[0]]*win(this.bufferIndex[0]/this.FFT_SIZE)+this.outputBuffer[1][this.bufferIndex[1]]*win(this.bufferIndex[1]/this.FFT_SIZE);
for(let bI=0;bI<2;bI++){
this.bufferIndex[bI]++;
if(this.bufferIndex[bI]>=this.FFT_SIZE){
let a=[...this.inputBuffer[bI]].map(x=>({r:x,i:0}));
FFT(a,false);
let b=a.map(x=>({r:x.r,i:x.i}));
for(let i=0;i<a.length;i++){
a[i]=read(b,i*(1+sin(t*3)*.1));
}
FFT(a,true);
for(let i=0;i<a.length;i++){
this.outputBuffer[bI][i]=(a[i].r+a[i].i)*.5;//Math.sqrt(a[i].r**2+a[i].i**2);
}
this.bufferIndex[bI]=0;
}
}
return o;
}
}
let eff=new realtimeFFT(10);
return t=>{
let o=(sine(t*440)+sine(t*550)+sine(t*163))*.1;
return eff.process(o,t);
};