This ditty only uses time input, it does its own sequencing
Log in to post a comment.
var dittyTime = 0;
var myNotes = [[0, c4], [0, e4], [0, g4], [1, e3], [2, g3], [3.5, c4]];
var loopCount = 4;
synth.def(
class {
constructor() {
this.playingNotes = []
}
process() {
dittyTime += ditty.dt;
let playedNotes = getNotes(dittyTime, myNotes, loopCount);
this.playingNotes = this.playingNotes.concat(playedNotes);
let doneNotes = []
let result = 0;
for (let i in this.playingNotes) {
let playingNote = this.playingNotes[i];
let freq = midi_to_hz(playingNote.pitch);
let ampEnv = basicEnv(dittyTime, playingNote.startTime, 0.01, 0.5);
if (ampEnv.done) {
doneNotes.push(i)
continue;
}
result += osc(dittyTime, freq) * ampEnv.value * 0.75;
}
for (let i of doneNotes) this.playingNotes.splice(i, 1);
return result;
}
}, {}
).play(0, { env: one });
function basicEnv(time, startTime, attack, release) {
let noteTime = time - startTime;
if (noteTime > attack + release) return { "done": true, "value" : 0 }
return { "done": false, "value" : noteTime < attack ? noteTime / attack : 1 - Math.min((noteTime - attack) / release, 1) }
}
function osc(time, freq) {
return Math.sin(time * freq * Math.PI * 2)
}
// -- utilities --
var prevSeqTime = -1;
function getNotes(time, notes, loopCount) {
let noteNum = null;
let seqTime = (time + ditty.dt) % loopCount;
let playedNotes = [];
notes.forEach(note => {
if (note[0] > prevSeqTime && note[0] <= seqTime) {
playedNotes.push({ "startTime" : time, "pitch" : note[1] });
}
});
prevSeqTime = prevSeqTime > seqTime ? -1 : seqTime;
return playedNotes;
}