You are not recognized as the original poster of this topic.
let mod=(n,m)=>(n%m+m)%m,
read=(a,i)=>a[mod(Math.floor(i),a.length)],
mix=(a,b,x)=>a+(b-a)*x,
noteHz=n=>440*2**(n/12),
rand=(...a)=>a.length===2?mix(a[0],a[1],Math.random()):a.length===1?Math.random()*x[0]:Math.random(),
pow2=(x,y)=>Math.pow(Math.abs(x),y)*Math.sign(x);
class StringWave{
constructor(N,damp=1.001,c=.2){
this.N=N;this.heights=new Array(N);this.velocities=new Array(N);
this.pluck(rand(),pow2(rand(-1,1),.3));
this.damp=damp;this.c=c;
}
pluck(x,y){
let xi=x*this.N;
for(let i=0;i<this.N;i++){
this.heights[i]=i<xi?y*(i/xi):y*(1-(i/xi)/(this.N-xi));
this.velocities[i]=0;
}
}
update(){
const v=this.velocities,h=this.heights;
for(let i=1;i<this.N-1;i++)
v[i]=(v[i]+2*(h[i-1]+h[i+1]-2*h[i]))/this.damp;
for(let i=0;i<this.N;i++)
h[i]+=v[i]*this.c;
}
}
function normalize(array){
let mn=Math.min(...array),
mx=Math.max(...array),
o=[];
if(mn===mx)return array;
for(let i=0;i<array.length;i++)
o[i]=mix(-1,1,(array[i]-mn)/(mx-mn));
return o;
}
let SR=8000,
N=70,chord=[0,3,7,10,14,15,17,22],w=[],a=[];
for(let i=0;i<8;i++){
w[i]=new StringWave(N,1.0005,.29);
a[i]=[];
for(let j=0;j<SR*2.8;j++){
w[i].update();
a[i][j]=w[i].heights[floor(N*(.25+sin((j/SR)*3)*.2))];
}
a[i]=normalize(a[i]);
//declicking
let fade=128;
for(let j=0;j<fade;j++){
a[i][j]*=(j+1)/(fade+1);
a[i][(a[i].length-1)-j]*=(j+1)/(fade+1);
}
}
let samp=()=>{
let t=0;
return(si,sa)=>{
t+=sa/32e3;
let a0=read(a[mod(floor(si),a.length)],t),
a1=read(a[mod(floor(si)+1,a.length)],t);
return mix(a0,a1,mod(si,1));
};
},s=chord.map(n=>[samp(),samp()]);
return t=>{
let o=0;
for(let i=0;i<chord.length;i++){
//o+=read(a[mod(floor(i+t),a.length)],t*noteHz(chord[i])*N)-read(a[mod(floor(i+t*.5),a.length)],-t*noteHz(chord[i])*1.02*N);
o+=s[i][0](t+i,noteHz(chord[i]+sin(t*7+i*.3)*.05)*N)-s[i][1](t+i*2,-noteHz(chord[i]+sin(t*6.5+i*.6)*.06)*N);
}
return tanh(o*.3);
};