diff --git a/packages/supradough/dough-export.mjs b/packages/supradough/dough-export.mjs index a9f5614b0..a6c55bf46 100644 --- a/packages/supradough/dough-export.mjs +++ b/packages/supradough/dough-export.mjs @@ -16,23 +16,72 @@ await evalScope( miniAllStrings(); // allows using single quotes for mini notation / skip transpilation let sampleRate = 48000, - cps = 0.5; + cps = 0.4; -let pat = note('[c e g b]*3') - .add(note(7)) - .lpf(sine.rangex(200, 4000).slow(2)) - .lpq(0.3) - .s('*2') - .att(0.01) - .rel(0.2) - .clip(2) - .delay(0.5) - .jux(rev) - .sometimes(add(note(12))) - .gain(0.25) +/* await doughsamples('github:eddyflux/crate'); +await doughsamples('github:eddyflux/wax'); */ + +let pat = note('c,eb,g,') + .s('sine') + .press() + .add(note(24)) + .fmi(3) + .fmh(5.01) + .dec(0.4) + .delay('.6:<.12 .22>:.8') + .jux(press) + .rarely(add(note('12'))) + .lpf(400) + .lpq(0.2) + .lpd(0.4) + .lpenv(3) + .fmdecay(0.4) + .fmenv(1) + .postgain(0.6) + .stack(s('*8').dec(0.07).rarely(ply('2')).delay(0.5).hpf(sine.range(200, 2000).slow(4)).hpq(0.2)) + .stack( + s('[- white@3]*2') + .dec(0.4) + .hpf('<2000!3 <4000 8000>>*4') + .hpq(0.6) + .ply('<1 2>*4') + .postgain(0.5) + .delay(0.5) + .jux(rev) + .lpf(5000), + ) + .stack( + note('*2') + .s('square') + .lpf(sine.range(100, 300).slow(4)) + .lpe(1) + .segment(8) + .lpd(0.3) + .lpq(0.2) + .dec(0.2) + .speed('<1 2>') + .ply('<1 2>') + .postgain(1), + ) + .stack( + chord('') + .voicing() + .s('') + .clip(1) + .rel(0.4) + .vib('4:.2') + .gain(0.7) + .hpf(1200) + .fm(0.5) + .att(1) + .lpa(0.5) + .lpf(200) + .lpenv(4) + .chorus(0.8), + ) .slow(1 / cps); -let cycles = 4; +let cycles = 30; let seconds = cycles + 1; // 1s release tail const haps = pat.queryArc(0, cycles); @@ -41,20 +90,32 @@ const dough = new Dough(sampleRate); console.log('spawn voices...'); haps.forEach((hap) => { hap.value._begin = Number(hap.whole.begin); - hap.value._duration = hap.duration / cps; + hap.value._duration = hap.duration/* / cps */; dough.scheduleSpawn(hap.value); }); -console.log(`render ${seconds}s long buffer...`); -const buffer = new Float32Array(seconds * sampleRate); -while (dough.t <= buffer.length) { +console.log(`render ${seconds}s long buffer, each dot is 1 second:`); +const buffers = [new Float32Array(seconds * sampleRate), new Float32Array(seconds * sampleRate)]; +let t = performance.now(); +while (dough.t <= buffers[0].length) { dough.update(); - buffer[dough.t] = dough.out[0]; + buffers[0][dough.t] = dough.out[0]; + buffers[1][dough.t] = dough.out[1]; + if (dough.t % sampleRate === 0) { + process.stdout.write('.'); + } } -console.log('done!'); +const took = (performance.now() - t) / 1000; +const load = (took / seconds) * 100; +const speed = (seconds / took).toFixed(2); +console.log(''); +console.log(`done! +rendered ${seconds}s in ${took.toFixed(2)}s +speed: ${speed}x +load: ${load.toFixed(2)}%`); const patternAudio = { sampleRate, - channelData: [buffer], + channelData: buffers, }; WavEncoder.encode(patternAudio).then((buffer) => {