Full Measure
Goose - Full Measure - original at youtube.com/watch?v=o8cghxh9gm4 - transcribed from onlinesequencer.net/5261760
Technically it's Half Truths, given there is no drum track here.
Log in to post a comment.
// Goose - Full Measure
// Manually transcribed from https://onlinesequencer.net/5261760
// KlemmentiumSeloi on Online Sequencer
// === Instruments ===
function softsaw(p, formant) {
const x = p-~~p;
// polyblep
const f = Math.abs(formant);
const s = Math.max(0, Math.abs((f + 1) * (2*x - 1)) - f);
// saw - polyblep
return 2 * x - 1 - s*s * Math.sign(x - 0.5);
}
// from my Piano ditty, https://dittytoy.net/ditty/bc17a034bf
// modified slightly
const osc = class {
constructor(options) {
// The value of the note argument of the play call is retrievable via options.note.
this.phases = new Float32Array(8).map(_ => Math.random());
this.damping = new Float32Array(8).map(_ => Math.random());
// frequency
this.freq = midi_to_hz(options.note) * ditty.dt;
// phasor
this.time = Math.random();
}
process(note, env, tick, options) {
// phasor times
this.time += ditty.dt * 3;
this.time -= this.time|0;
let phase = Math.sin(this.time * 2 * Math.PI);
// total
let l = 0.0;
let r = 0.0;
// all saw waves
for (let i = 0; i < this.phases.length; i++) {
// sample wave
const v = softsaw(
this.phases[i],
this.damping[i] * (options.soft_decay * env.value + options.soft_base)
) * env.value;
// update phase
this.phases[i] += this.freq * (options.detune||1) + phase * ditty.dt * (options.vibrato||0);
this.phases[i] -= this.phases[i]|0;
// stereo
if (i < this.phases.length / 2) l += v;
else r += v;
}
return [l * 0.707, r * 0.707];
}
};
// Sounds fine:tm:, but could be better
// Piano is very hard to recreate properly
const piano = synth.def(
osc, {
soft_decay: 8,
soft_base: 0,
levels: [0, 1, 0, 0],
times: [0.001, 6, 1],
env: segenv,
}
);
// closest I could get this to a saxaphone
const sax = synth.def(
osc, {
soft_decay: 20,
soft_base: 10,
vibrato: 1.2,
detune: 0.5,
levels: [0, 1, 0.7, 0],
times: [0.05, 2, 0.2],
env: segenv,
}
);
// more of a violin considering how high it plays, but reasonably close
const cello = synth.def(
osc, {
soft_decay: 4,
soft_base: 4,
vibrato: 3,
levels: [0, 1, 0.7, 0],
times: [0.05, 0.2, 0.2],
env: segenv,
}
);
// === Song utils ===
// play one or more notes at a time
function playOne(instr, duration, ...notes) {
for (let note of notes) {
// if it's one note, make it an array of one note
if (!Array.isArray(note)) note = [note];
// play the notes
for (let i = 0; i < notes.length; ++i) {
// but only if the note has a higher than 0 frequency
if (note[i] > 0) {
instr.play(note[i], { duration: duration });
}
}
// no altered duration here
sleep(duration);
}
}
// === Song ===
ditty.bpm = 140;
// loop 1 (32 beats each loop, but at loop 5 I switch to 16 beats per loop)
function piano1(instr) {
for (let i = 0; i < 2; i++) {
playOne(instr, 3/4, [b3, d3], [cs4, fs3]);
playOne(instr, 1/2, [d4, g3]);
playOne(instr, 3/4, [b3, fs3], [cs4, d3]);
playOne(instr, 1/2, d4);
}
for (let i = 0; i < 2; i++) {
playOne(instr, 3/4, [as3, cs3], [cs4, fs3]);
playOne(instr, 1/2, [d4, g3]);
playOne(instr, 3/4, [as3, fs3], [cs4, cs3]);
playOne(instr, 1/2, d4);
}
// part 2.1
playOne(instr, 3/4, [b3, d3], [cs4, fs3]);
playOne(instr, 1/2, [d4, g3]);
playOne(instr, 3/4, [e4, fs3], [fs4, d3]);
playOne(instr, 1/2, e4);
playOne(instr, 3/4, [d4, d3], [cs4, fs3]);
playOne(instr, 1/4, [b3, g3], cs4);
playOne(instr, 3/4, [b3, fs3], [g3, d3]);
playOne(instr, 1/2, fs3);
// part 2.2
playOne(instr, 3/4, [as3, cs3], [cs4, fs3]);
playOne(instr, 1/2, [d4, g3]);
playOne(instr, 3/4, [e4, fs3], [d4, cs3]);
playOne(instr, 1/2, cs4);
playOne(instr, 3/4, [as3, cs3], [cs4, fs3]);
playOne(instr, 1/2, [d4, g3]);
playOne(instr, 3/4, [cs4, fs3], [as3, cs3]);
playOne(instr, 1/2, [cs4, cs3]);
}
function sax1(instr) {
playOne(instr, 7/1, b3);
playOne(instr, 1/2, cs4, d4);
playOne(instr, 7/1, as3);
playOne(instr, 1/2, cs4, d4);
playOne(instr, 7/1, fs4);
playOne(instr, 1/2, e4, d4);
playOne(instr, 4/1, cs4, as3);
}
// loop 2
function piano2(instr) {
// same as the first
piano1(instr);
}
function sax2(instr) {
playOne(instr, 7/1, b3);
playOne(instr, 1/2, cs4, d4);
playOne(instr, 7/1, as3);
playOne(instr, 1/2, cs4, d4);
playOne(instr, 7/1, b3);
playOne(instr, 1/2, cs4, d4);
playOne(instr, 2/1, as3, g3, fs3);
playOne(instr, 3/4, cs4, d4);
playOne(instr, 1/2, d4);
}
// loop 3
function piano3(instr) {
const pat = (a, b, c, l, h) => {
playOne(instr, 3/4, [c, b], [a, l]);
playOne(instr, 1/2, [b, a]);
playOne(instr, 1/1, [c, b]);
playOne(instr, 1/2, [a, l], [b, a]);
playOne(instr, 3/4, [c, b], [a, l]);
playOne(instr, 1/2, [b, a]);
playOne(instr, 1/1, [c, b]);
playOne(instr, 1/2, [h, b], [c, b]);
}
// part 1
pat(b3, d4, fs4, fs3, g4);
// part 2
pat(as3, cs4, e4, fs3, fs4);
// part 3
pat(fs3, b3, d4, d3, e4);
// part 4
pat(fs3, as3, cs4, cs3, d4);
}
function sax3(instr) {
playOne(instr, 12/2, b3);
playOne(instr, 3/4, b3, cs4);
playOne(instr, 1/2, d4);
playOne(instr, 12/2, as3);
playOne(instr, 3/4, b3, cs4);
playOne(instr, 1/2, d4);
playOne(instr, 14/2, fs3);
playOne(instr, 1/2, fs3, g3);
playOne(instr, 8/1, fs3);
}
function string3(instr) {
// only the short buildup
sleep(32 - 1);
playOne(instr, 1/2, cs5, d5);
}
// loop 4
function piano4(instr) {
// same as loop 3
piano3(instr);
}
function sax4(instr) {
playOne(instr, 8/1, b3, cs4, d4, e4);
}
function string4(instr) {
playOne(instr, 7/1, fs5);
playOne(instr, 1/1, b5);
playOne(instr, 7/1, fs5);
playOne(instr, 1/1, cs6);
playOne(instr, 7/1, fs5);
playOne(instr, 1/1, d6);
playOne(instr, 7/1, fs5);
playOne(instr, 1/4, e6, d6, cs6, b5);
}
// loop 5 (full measure motif, go to 16 beats per loop)
function piano5(instr) {
// the motif
// note that the reference has it one octave higher still
// a
playOne(instr, 1/4, d5, fs4, d3, fs5, fs4, d3);
playOne(instr, 1/4, g5, fs4),
playOne(instr, 1/4, fs5, fs4, d4, d5, fs4, d3);
playOne(instr, 1/4, cs5, d5);
// b
playOne(instr, 1/4, cs5, fs4, cs4, fs5, fs4, cs4);
playOne(instr, 1/4, g5, fs4);
playOne(instr, 1/4, fs5, fs4, cs4, cs5, fs4, cs4);
playOne(instr, 1/4, e5, d5);
// c
playOne(instr, 1/4, d5, g4, d4, fs5, g4, d4);
playOne(instr, 1/4, g5, g4);
playOne(instr, 1/4, fs5, g4, d4, d5, g4, d4);
playOne(instr, 1/4, cs5, d5);
// d
playOne(instr, 1/4, cs5, fs4, cs4, fs5, fs4, cs4);
playOne(instr, 1/4, e5, fs4);
playOne(instr, 1/4, d5, fs4, cs4, cs5, fs4, cs4);
playOne(instr, 1/4, b4, cs5);
}
function sax5(instr) {
playOne(instr, 3/1, d4);
playOne(instr, 1/2, fs4, d4);
playOne(instr, 2/1, cs4, a3);
playOne(instr, 3/1, b3);
playOne(instr, 1/2, d4, b3);
playOne(instr, 4/1, as3);
}
function string5(instr) {
playOne(instr, 3/1, b4);
playOne(instr, 1/2, cs5, d5);
playOne(instr, 2/1, a4, fs4, e4, fs4, e4);
playOne(instr, 1/4, d4, e4, fs4, g4, a4, b4, cs5, d5);
}
// loop 6 (full measure motif part 2)
function piano6(instr) {
// same
piano5(instr);
}
function sax6(instr) {
playOne(instr, 3/1, fs3);
playOne(instr, 1/1, b3);
playOne(instr, 2/1, fs3, g3);
playOne(instr, 3/1, fs3);
playOne(instr, 1/2, b3, g3);
playOne(instr, 2/1, fs3);
playOne(instr, 1/1, e3, d3);
}
function string6(instr) {
playOne(instr, 5/2, fs5);
playOne(instr, 1/2, a5, g5, fs5);
playOne(instr, 2/1, fs5);
playOne(instr, 2/1, d5);
playOne(instr, 5/2, cs5);
playOne(instr, 1/2, b4);
playOne(instr, 1/1, fs5);
playOne(instr, 2/1, cs5);
playOne(instr, 3/4, e5, d5);
playOne(instr, 1/2, cs5);
}
// loop 7
function piano7(instr) {
// same again
piano5(instr);
}
function sax7(instr) {
playOne(instr, 2/1, b2, b3, cs4, e4, d4);
playOne(instr, 1/1, fs4, d4);
playOne(instr, 2/1, e4, as4);
}
function string7(instr) {
playOne(instr, 3/4, b4, fs5);
playOne(instr, 1/2, g5);
playOne(instr, 3/4, b4, fs5);
playOne(instr, 1/2, g5);
playOne(instr, 3/4, a4, fs5);
playOne(instr, 1/2, g5);
playOne(instr, 1/4, a4, b4, cs5, d5, e5, d5, cs5, d5);
playOne(instr, 3/4, b4, fs5);
playOne(instr, 1/2, g5);
playOne(instr, 3/4, b4, fs5);
playOne(instr, 1/2, g5);
playOne(instr, 3/4, a4, fs5);
playOne(instr, 1/2, g5);
playOne(instr, 1/2, as4, e5);
playOne(instr, 1/4, d5, cs5, b4, cs5);
}
// loop 8
function piano8(instr) {
// different this time!
// a
playOne(instr, 1/4, [d5, d4], fs4, [cs5, d4], [fs5, b4]);
playOne(instr, 1/4, fs4, [b4, d4], [g5, a4], [b4, fs4]);
playOne(instr, 1/4, [fs5, d5], fs4, [cs5, d4], [d5, b4]);
playOne(instr, 1/4, fs4, [b4, d4], cs5, d5);
// b
playOne(instr, 1/4, cs5, fs4, [b4, cs4], [fs5, a4]);
playOne(instr, 1/4, fs4, [a4, cs4], [g5, e4], [a4, fs4]);
playOne(instr, 1/4, [fs5, cs4], [a4, fs4], [cs5, cs4], [e5, cs5]);
playOne(instr, 1/4, [a4, fs4], [e5, cs4], [e5, cs4], [d5, a4]);
// c, same as a
playOne(instr, 1/4, [d5, d4], fs4, [cs5, d4], [fs5, b4]);
playOne(instr, 1/4, fs4, [b4, d4], [g5, a4], [b4, fs4]);
playOne(instr, 1/4, [fs5, d5], fs4, [cs5, d4], [d5, b4]);
playOne(instr, 1/4, fs4, [b4, d4], cs5, d5);
// d
playOne(instr, 1/4, cs4, fs4, [b4, cs4], [fs5, as4]);
playOne(instr, 1/4, fs4, [as4, cs4], [e5, fs5], [as4, fs4]);
playOne(instr, 1/4, [d5, cs5], [as4, fs4], [cs5, cs4], [fs5, cs5]);
playOne(instr, 1/4, [as5, fs4], [fs5, cs4], [cs5, b4], [cs5, as4]);
}
function sax8(instr) {
playOne(instr, 3/1, fs4);
playOne(instr, 1/2, d4, fs4);
playOne(instr, 9/4, g4);
playOne(instr, 1/4, fs4, e4, d4, cs4, d4, fs4, a4);
playOne(instr, 7/2, b4);
playOne(instr, 1/4, cs5, d5);
playOne(instr, 2/1, cs5);
playOne(instr, 3/4, cs4, b3);
playOne(instr, 1/4, d4, cs4);
}
function string8(instr) {
playOne(instr, 3/1, d5);
playOne(instr, 1/2, fs5, d5);
playOne(instr, 2/1, cs5, a4, b4, d5, as5);
playOne(instr, 3/4, cs6, b5);
playOne(instr, 1/2, fs5);
}
// loop 9
function piano9(instr) {
// a
playOne(instr, 1/4, d5, fs4, d4, fs5, fs4, d4, g5, fs4);
playOne(instr, 1/4, fs5, fs4, d4, d5, fs4, d4, cs5, fs4);
// b
playOne(instr, 1/4, d5, fs4, d4, fs5, fs4, d4, g5, fs4);
playOne(instr, 1/4, fs5, fs4, d4, d5, fs4, d4, cs5, e5);
// c
playOne(instr, 1/4, d5, g4, d4, fs5, g4, d4, g5, g4);
playOne(instr, 1/4, fs5, g4, d4, d5, g4, d4, cs5, d5);
// d
playOne(instr, 1/4, d5, g4, d4, fs5, g4, d4, g5, g4);
playOne(instr, 1/4, fs5, g4, d4, d5, g4, d4, d5, e5);
}
function sax9(instr) {
playOne(instr, 7/1, b3);
playOne(instr, 1/2, cs4, d4);
playOne(instr, 9/2, g3);
playOne(instr, 1/2, d4, cs4, d4, e4, d4, cs4, d4);
}
function string9(instr) {
playOne(instr, 8/1, [fs5, b4, b3], [fs4, b4, g4]);
}
// loop 10
function piano10(instr) {
// almost the same as loop 9
playOne(instr, 1/4, d5, fs4, d4, fs5, fs4, d4, g5, fs4);
playOne(instr, 1/4, fs5, fs4, d4, d5, fs4, d4, cs5, fs4);
// b
playOne(instr, 1/4, d5, fs4, d4, fs5, fs4, d4, g5, fs4);
playOne(instr, 1/4, fs5, fs4, d4, d5, fs4, d4, cs5, e5);
// c
playOne(instr, 1/4, d5, g4, d4, fs5, g4, d4, g5, g4);
playOne(instr, 1/4, fs5, g4, d4, d5, g4, d4, cs5, d5);
// d, this one is different however
playOne(instr, 1/4, d5, g4, d4, fs5, g4, d4, e5, g4);
playOne(instr, 1/4, d5, g4, d4, cs5, g4, d4, cs5, d5);
}
function sax10(instr) {
playOne(instr, 7/1, b3);
playOne(instr, 1/2, d4, fs4);
playOne(instr, 4/1, g4);
playOne(instr, 1/2, g4, fs4, e4, d4, cs4, b3, cs4, d4);
}
function string10(instr) {
playOne(instr, 7/1, [b5, fs5, b4, b3]);
playOne(instr, 1/2, [cs6, d4], [d6, fs4]);
playOne(instr, 4/1, [g5, fs5, b4, g4]);
playOne(instr, 2/1, [a5, fs5, b4, g4], [fs5, b4, g4]);
}
// loop 11
function piano11(instr) {
// same as loop 9
piano9(instr);
}
function sax11(instr) {
playOne(instr, 7/1, b3);
playOne(instr, 1/2, cs4, d4);
playOne(instr, 4/1, g3);
playOne(instr, 3/1, g3);
playOne(instr, 1/2, cs4, d4);
}
function string11(instr) {
playOne(instr, 3/2, [b4, fs4]);
playOne(instr, 1/2, fs5, g5, b5, d6, fs6);
playOne(instr, 3/2, [fs5, b4]);
playOne(instr, 1/2, fs5, g5, b5, cs6, d6);
playOne(instr, 3/2, [fs5, b4, g4]);
playOne(instr, 1/2, fs5, g5, b5, d6, fs5);
playOne(instr, 3/2, [fs5, b4]);
playOne(instr, 1/2, cs6, d6, e6, d6, cs6);
}
// loop 12
function piano12(instr) {
// different again!
// a
playOne(instr, 1/4, d5, g4, [cs5, d4], [fs5, b4], g4, [b4, d4], [g5, a4], [b4, g4]);
playOne(instr, 1/4, [fs5, d5], g4, [cs5, d4], [d5, b4], g4, [b4, d4], cs5, [d5, g4]);
// b
playOne(instr, 1/4, d5, g4, [cs5, d4], [fs5, b4], g4, [b4, d4], [g5, fs4], [b4, g4]);
playOne(instr, 1/4, [fs5, d5], [b4, g4], [d5, d4], [fs5, d5], [b5, g4], [fs5, cs5], [e5, d5], [d5, b4]);
// c
playOne(instr, 1/4, [d5, cs5], fs4, [cs5, cs4], [fs5, b4], fs4, [b4, cs4], [g5, g4], [b4, fs4]);
playOne(instr, 1/4, [fs5, d5], fs4, [cs5, cs4], [d5, b4], fs4, [g4, cs4], cs5, d5);
// d
playOne(instr, 1/4, cs5, fs4, [b4, cs4], [fs5, g4], fs4, [a4, cs4], [e5, g4], [a4, fs4]);
playOne(instr, 1/4, [d5, b4], [cs5, fs4], [d5, cs4], [e5, cs5], [fs5, fs4], [g5, cs4], [a5, b4], [as5, cs5]);
}
function sax12(instr) {
playOne(instr, 7/1, fs4);
playOne(instr, 1/2, e4, d4);
playOne(instr, 7/2, g3)
playOne(instr, 1/2, fs3);
playOne(instr, 5/2, e3);
playOne(instr, 1/4, fs3, g3, a3, b3, cs4, d4);
}
function string12(instr) {
// this is repeated twice
// sort of, the original adds some extra notes that I don't
for (let i = 0; i < 2; i++) {
playOne(instr, 3/4, [fs4, b4, d5], fs5);
playOne(instr, 1/2, g5);
playOne(instr, 3/4, [fs5, b4, fs4], d5);
playOne(instr, 1/2, cs5);
// b
playOne(instr, 3/4, [d5, b4], fs5);
playOne(instr, 1/2, g5);
playOne(instr, 3/4, [fs5, b4]);
playOne(instr, 1/2, d5);
playOne(instr, 1/4, cs5, e5, d5);
}
}
// loop 13
function piano13(instr) {
// no more full measure motif :(
playOne(instr, 4/1, [b5, fs5]);
playOne(instr, 3/1, [g5, e5]);
playOne(instr, 1/1, [fs5, d5]);
playOne(instr, 2/1, [fs5, cs5], [g5, d5], [fs5, cs5], [d5, b4]);
}
function sax13(instr) {
playOne(instr, 4/1, fs4);
playOne(instr, 2/1, g4, fs4);
playOne(instr, 4/1, fs4);
playOne(instr, 2/1, g4, fs4);
}
function string13(instr) {
playOne(instr, 16/1, [g5, fs5]);
}
// loop 14
function piano14(instr) {
playOne(instr, 3/1, [b4, g4]);
playOne(instr, 1/1, [fs5, d5]);
playOne(instr, 2/1, [e5, cs5]);
playOne(instr, 3/2, [d5, b4]);
playOne(instr, 1/4, [e5, cs5], [d5, b4]);
playOne(instr, 2/1, [cs5, as4], [fs5, cs5], [e5, cs5], [d5, as4]);
}
function sax14(instr) {
playOne(instr, 4/1, fs4, e4, e4, d4);
}
function string14(instr) {
playOne(instr, 8/1, [g5, fs5]);
playOne(instr, 2/1, g5, e5, d5, cs5);
}
// loop 15
function piano15(instr) {
playOne(instr, 4/1, [b5, fs5]);
playOne(instr, 3/1, [g5, e5]);
playOne(instr, 1/1, [fs5, d5]);
playOne(instr, 2/1, [fs5, cs5], [g5, d5], [fs5, cs5], [d5, b4]);
}
function sax15(instr) {
playOne(instr, 4/1, b3);
playOne(instr, 2/1, d4, e4);
playOne(instr, 4/1, cs4, d4);
}
function string15(instr) {
playOne(instr, 8/1, b4, as4);
}
// loop 16
function piano16(instr) {
playOne(instr, 3/1, [b4, g4]);
playOne(instr, 1/1, [fs5, d5]);
playOne(instr, 2/1, [e5, cs4]);
playOne(instr, 3/2, [d5, b4]);
playOne(instr, 1/4, [e5, cs5], [d5, b4]);
playOne(instr, 2/1, [cs5, as4], [fs5, cs5], [e5, cs5], [d5, as4]);
}
function sax16(instr) {
playOne(instr, 4/1, cs4, b3, fs3, d3);
}
function string16(instr) {
playOne(instr, 8/1, g4);
playOne(instr, 4/1, e4, fs4);
}
// loop 17
function piano17(instr) {
playOne(instr, 16, [b4, fs4]);
}
function sax17(instr) {
playOne(instr, 1/1, cs3, d3);
playOne(instr, 6/1, b2);
sleep(8);
}
function string17(instr) {
playOne(instr, 8/1, d4);
sleep(8);
}
// === Song loops ===
loop(() => {
piano1(piano);
piano2(piano);
piano3(piano);
piano4(piano);
piano5(piano);
piano6(piano);
piano7(piano);
piano8(piano);
piano9(piano);
piano10(piano);
piano11(piano);
piano12(piano);
piano13(piano);
piano14(piano);
piano15(piano);
piano16(piano);
piano17(piano);
}, { name: 'Piano', amp: 0.5, pan: -0.3 });
loop(() => {
sax1(sax);
sax2(sax);
sax3(sax);
sax4(sax);
sax5(sax);
sax6(sax);
sax7(sax);
sax8(sax);
sax9(sax);
sax10(sax);
sax11(sax);
sax12(sax);
sax13(sax);
sax14(sax);
sax15(sax);
sax16(sax);
sax17(sax);
}, { name: 'Sax', amp: 0.7, pan: 0.3 });
loop(() => {
sleep(32 * 2);
string3(cello);
string4(cello);
string5(cello);
string6(cello);
string7(cello);
string8(cello);
string9(cello);
string10(cello);
string11(cello);
string12(cello);
string13(cello);
string14(cello);
string15(cello);
string16(cello);
string17(cello);
}, { name: 'Cello', amp: 0.6, pan: 0.1 });