// // You can find the Dittytoy API Reference here: https://Dittytoy.net/syntax // Example ditties can be found here: https://dittytoy.net/user/Dittytoy // // Most of your ditty will run 44100 times per second using javascript in the browser. // Make sure you optimize your ditty to work well on as many devices as possible. To do that, try to limit // the number of simultaneously active synths: make sure they don't last longer than necessary, or you can // hear them, and spread them over different loops (each loop runs in a separate worker). // function fn(x) { return (Math.sin(x*3.1415*2.0)+(x%1))*0.5; } const test = synth.def( class { constructor(options) { // The value of the note argument of the play call is retrievable via options.note. this.phase = 0; this.v = 0; } process(note, env, tick, options) { this.phase += midi_to_hz(note) * ditty.dt * (env.value ** options.xenv); this.v += (fn(this.phase)) * env.value * 0.1; this.v *= 0.9; return this.v; } }, { xenv: 0.5, amp: 1, attack: 0.01, release: 0.3 } ); const background = synth.def( class { constructor(options) { this.k = 0; this.v = 0; } process(note, env, tick, options) { this.k += Math.random()*0.001; this.k *= 0.99; var k = 0.01/(this.k+0.01); this.v += Math.random()*k; this.v *= 1-k; return this.v; } }, { xenv: 0.5, amp: 1, attack: 0.01, release: 0.3 } ); class State { constructor(note, next, time, info) { this.note = note; this.next = next; this.time = time; this.info = info; } } class superState { constructor(notes, next, time, type) { this.notes = notes; this.next = next; this.time = time; this.type = type; } play() { var state = this.notes[0]; for (let i = 0; i < this.time; i++) { this.type.play(state.note, state.info); sleep(state.time); var next = state.next.shift(); state.next.push(next); state = this.notes[next]; } } } ditty.bpm = 120; var info = { attack: 0.01, release: 0, duration: 0.5 }; var states = [ new superState([ new State(c4, [1], 0.75, { attack: 0.01, release: 3.75, duration: 0}), new State(c5, [2], 0.5, { attack: 0.01, release: 0.5, duration: 0.5 }), new State(b4, [3], 0.8, { attack: 0.01, release: 0.1, duration: 0.6 }), new State(g4, [4], 0.7, { attack: 0.01, release: 0.1, duration: 0.8 }), new State(e4, [5], 2.5, { attack: 0.01, release: 1, duration: 1 }), new State(d4, [6], 0.75, { attack: 0.01, release: 3.75, duration: 0}), new State(c5, [7, 1], 0.5, { attack: 0.01, release: 0.5, duration: 0.5 }), new State(b4, [8], 0.8, { attack: 0.01, release: 0.1, duration: 0.6 }), new State(g4, [9], 0.7, { attack: 0.01, release: 0.1, duration: 0.8 }), new State(d5, [1, 0], 2.5, { attack: 0.01, release: 1, duration: 1 }), ], [1, 0], 20, sine), new superState([ new State(c4, [1], 0.5, { attack: 0.01, release: 0.5, duration: 0.5 }), new State(e4, [2], 0.5, { attack: 0.01, release: 0.1, duration: 0.5 }), new State(b4, [0, 0, 3], 0.5, { attack: 0.01, release: 1, duration: 0.5 }), new State(d4, [1], 3, { attack: 0.01, release: 2, duration: 0.5 }), ], [0, 1], 10, test), ]; var state = states[0]; loop( () => { state.play(); var next = state.next.shift(); state.next.push(next); state = states[next]; }, { name: 'my first loop' }); loop( () => { background.play(f4, { attack: 0.01, release: 2, duration: 1000 }); sleep(100000) }, { name: 'background' });