1<!doctype html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>Buildless Vanilla Strudel REPL</title> 7 </head> 8 <body style="margin: 0; background: #222"> 9 <div style="display: grid; height: 100vh; grid-template-rows: 32px auto"> 10 <button id="start" style="width: 100vw; height: 32px">evaluate</button> 11 <textarea 12 id="text" 13 style="font-size: 2em; border: 0; color: white; background: transparent; outline: none; padding: 20px" 14 spellcheck="false" 15 ></textarea> 16 </div> 17 <div id="output"></div> 18 <script type="module"> 19 // TODO: refactor to use newer version without controls import 20 import { controls, repl, evalScope } from 'https://cdn.skypack.dev/@strudel/core@0.11.0'; 21 import { mini } from 'https://cdn.skypack.dev/@strudel/mini@0.11.0'; 22 import { transpiler } from 'https://cdn.skypack.dev/@strudel/transpiler@0.11.0'; 23 import { 24 getAudioContext, 25 webaudioOutput, 26 initAudioOnFirstClick, 27 registerSynthSounds, 28 } from 'https://cdn.skypack.dev/@strudel/webaudio@0.11.0'; 29 30 const ctx = getAudioContext(); 31 const input = document.getElementById('text'); 32 input.innerHTML = getTune(); 33 34 const loadModules = evalScope( 35 controls, 36 import('https://cdn.skypack.dev/@strudel/core@0.11.0'), 37 import('https://cdn.skypack.dev/@strudel/mini@0.11.0'), 38 import('https://cdn.skypack.dev/@strudel/tonal@0.11.0'), 39 import('https://cdn.skypack.dev/@strudel/webaudio@0.11.0'), 40 ); 41 42 const initAudio = Promise.all([initAudioOnFirstClick(), registerSynthSounds()]); 43 44 const { evaluate } = repl({ 45 defaultOutput: webaudioOutput, 46 getTime: () => ctx.currentTime, 47 transpiler, 48 }); 49 document.getElementById('start').addEventListener('click', async () => { 50 await loadModules; 51 await initAudio; 52 evaluate(input.value); 53 }); 54 55 function getTune() { 56 return `samples('github:tidalcycles/dirt-samples') 57setcps(1); 58stack( 59 // amen 60 n("0 1 2 3 4 5 6 7") 61 .sometimes(x=>x.ply(2)) 62 .rarely(x=>x.speed("2 | -2")) 63 .sometimesBy(.4, x=>x.delay(".5")) 64 .s("amencutup") 65 .slow(2) 66 .room(.5) 67 , 68 // bass 69 sine.add(saw.slow(4)).range(0,7).segment(8) 70 .superimpose(x=>x.add(.1)) 71 .scale('G0 minor').note() 72 .s("sawtooth").decay(.1).sustain(0) 73 .gain(.4).cutoff(perlin.range(300,3000).slow(8)).resonance(10) 74 .degradeBy("0 0.1 .5 .1") 75 .rarely(add(note("12"))) 76 , 77 // chord 78 note("Bb3,D4".superimpose(x=>x.add(.2))) 79 .s('sawtooth').cutoff(1000).struct("<~@3 [~ x]>") 80 .decay(.05).sustain(.0).delay(.8).delaytime(.125).room(.8) 81 , 82 // alien 83 s("breath").room(1).shape(.6).chop(16).rev().mask("<x ~@7>") 84 , 85 n("0 1").s("east").delay(.5).degradeBy(.8).speed(rand.range(.5,1.5)) 86).reset("<x@7 x(5,8)>")`; 87 } 88 </script> 89 </body> 90</html>