This fractal (Weierstrass function) is created for blind people to hear what fractals sound like
Log in to post a comment.
input.a = 0.25; // min=0.10, max=0.99, step=0.01
input.b = 7.00; // min=1.10, max=20.00, step=0.01
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],
];
// I'm really sorry, but I don't remember from who I stole this reverb. Comment if you know and I will credit properly
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());