//
// 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' });