This fractal (Weierstrass function) is created for blind people to hear what fractals sound like
Log in to post a comment.
input.a = 0.5; // min=0.10, max=0.99, step=0.01 input.b = 7.00; // min=1.10, max=9.00, step=0.10 ditty.bpm = 69; const Weierstrass = synth.def(class { constructor(){ this.p = 0; } process(note, env){ const f = midi_to_hz(note); this.p += f * ditty.dt; let s = 0, A = 1, M = 1; for(let i=0;i<12;i++){ s += A * Math.cos(2*Math.PI*M*this.p); A *= input.a; M *= input.b; } s *= env.value * 0.18; return [s,s]; } },{attack:0.01,release:1.6}); function P(n,d){ Weierstrass.play(n,{duration:d}); } function play_bar(bass,tri){ P(bass,12); for(let k=0;k<4;k++){ for(let i=0;i<3;i++){ P(tri[i],1); sleep(1); } } } const BAR_SEQ=[[37,[61,64,68]],[47,[61,64,68]],[45,[57,61,64]],[42,[62,66,69]]]; const MELODY=[ [73,6],[72,6],[71,6],[73,12],[68,6],[69,6],[71,12], [73,6],[72,6],[71,6],[73,12],[68,6],[69,6],[71,12], [73,6],[75,6],[76,6],[75,12],[73,6],[72,6],[71,12], [73,6],[72,6],[71,6],[73,12],[68,6],[69,6],[71,12], ]; class Delayline { constructor(n){ this.n=~~n; this.p=0; this.lastOut=0; this.data=new Float32Array(n); } clock(input){ this.lastOut=this.data[this.p]; this.data[this.p]=input; if(++this.p>=this.n){ this.p=0; } } tap(offset){ var x=this.p-offset-1; x%=this.n; if(x<0){ x+=this.n; } return this.data[x]; } } function allpass(delayline,x,k){ var delayin=x-delayline.lastOut*k; var y=delayline.lastOut+k*delayin; delayline.clock(delayin); return y; } const reverb = filter.def(class { constructor(options){ this.lastReturn=0; this.krt=0.7; this.delaylines=[]; for(var i=0;i<12;++i){ this.delaylines.push(new Delayline(10+Math.floor(Math.random()*5000))); } } process(input, options){ var inv=input[0]+input[1]; var v=this.lastReturn; v=allpass(this.delaylines[0],v+inv,.5); v=allpass(this.delaylines[1],v,.5); this.delaylines[2].clock(v); v=this.delaylines[2].lastOut*this.krt; v=allpass(this.delaylines[3],v+inv,.5); v=allpass(this.delaylines[4],v,.5); this.delaylines[5].clock(v); v=this.delaylines[5].lastOut*this.krt; v=allpass(this.delaylines[6],v+inv,.5); v=allpass(this.delaylines[7],v,.5); this.delaylines[8].clock(v); v=this.delaylines[8].lastOut*this.krt; v=allpass(this.delaylines[9],v+inv,.5); v=allpass(this.delaylines[10],v,.5); this.delaylines[11].clock(v); v=this.delaylines[11].lastOut*this.krt; this.lastReturn=v; var ret=[0,0]; ret[0]+=this.delaylines[2].tap(111); ret[1]+=this.delaylines[2].tap(2250); ret[0]+=this.delaylines[5].tap(311); ret[1]+=this.delaylines[5].tap(1150); ret[0]+=this.delaylines[8].tap(511); ret[1]+=this.delaylines[8].tap(50); ret[0]+=this.delaylines[11].tap(4411); ret[1]+=this.delaylines[11].tap(540); ret[0]=ret[0]*.2+input[0]; ret[1]=ret[1]*.2+input[1]; var m=(ret[0]+ret[1])*.5; var s=(ret[1]-ret[0])*.5; ret[0]=m+s*1.5; ret[1]=m-s*1.5; return ret; } }); const main = loop(()=>{ for(let r=0;r<4;r++){ for(let b=0;b<4;b++){ const [bass,tri]=BAR_SEQ[b]; const id=(r*4+b)%MELODY.length; const [mn,md]=MELODY[id]; P(mn,md); play_bar(bass,tri); } } }); main.connect(reverb.create());