TinyChan

New reply in topic: Bytebeat/Floatbeat/Funcbeat

You are not recognized as the original poster of this topic.

:

You are required to fill in a captcha for your first 5 posts. Sorry, but this is required to stop people from posting while drunk. Please be responsible and don't drink and post!
If you receive this often, consider not clearing your cookies.

Please familiarise yourself with the rules and markup syntax before posting.


Replying to FFT test (WIP)…

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);
};