function waveform(x, t) {
x = x - Math.floor(x);
let y = t*x*(1-x);
return 2*Math.exp(-t*x)*y*y;
}
const rand = () => Math.random()*2-1;
const mySynth = synth.def(class {
constructor(opt) {
this.p = new Float32Array(opt.voices);
for(let i=0; i<opt.voices; i++) {
this.p[i] = Math.random();
}
this.f = midi_to_hz(opt.note);
}
process(note,env,tick,opt) {
let sig = 0;
let t = opt.tmax * env.value * 2**((60 - opt.note)/24);
let amp = 1.0;
for(let i=0; i<opt.voices; i++) {
this.p[i] += (this.f + opt.detune * rand()) * ditty.dt;
sig += waveform(this.p[i], t) * amp;
amp *= -0.9;
}
return sig / opt.voices;
}
}, {attack: 0.5, decay: 0.3, sustain: 0.7, release: 0.3,
voices: 8, tmax: 25, detune: 20,
duration: 3
});
const v_notes = [c2, g3, c3, d3, g3, a3, d4, a4, e5];
loop((i) => {
sleep(1);
if(i <= 5) {
for(let j=0; j<=i; j++) {
mySynth.play(a4, {pan: -0.5+0.3*rand()});
sleep(0.5*Math.random());
}
sleep(Math.random());
} else {
for(let j=0; j<8; j++) {
mySynth.play(v_notes.choose(), {pan: rand(), duration: 2+3*Math.random()});
}
sleep(Math.random());
}
}, {amp: 0.8, name:"Violins"});
/*
loop((i) => {
//if(i==0) {sleep(10);}
for(let j=0; j<8; j++) {
mySynth.play(a_notes.choose(), {pan: 0.3*rand()});
}
sleep(2*Math.random());
}, {amp: 0.3, name:"Violas"});
*/