Skip to content

Instantly share code, notes, and snippets.

@petersalomonsen
Created October 28, 2021 16:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petersalomonsen/7868e46c3ba499612326efbf157b5f05 to your computer and use it in GitHub Desktop.
Save petersalomonsen/7868e46c3ba499612326efbf157b5f05 to your computer and use it in GitHub Desktop.
/*
* Copyright (c) 2021 - Peter Johan Salomonsen
*/
setBPM(85);
addInstrument('piano');
addInstrument('string');
addInstrument('drums');
addInstrument('guitar');
addInstrument('bass');
addInstrument('tubelead');
addInstrument('flute');
addInstrument('padsynth');
addInstrument('brass');
const beat = () => createTrack(2).steps(6,[
[c5,fs5],,fs5(0.5,5),fs5,,[c5,fs5(0.5,5)],
[d5,fs5],,fs5(0.5,5),[c5,fs5],,fs5(0.5,5),
[fs5],,fs5(0.5,5),[c5,fs5],,fs5(0.5,5),
[d5,fs5],,fs5(0.5,5),[fs5(0.3)],,fs5(0.1,5),
].repeat(3));
const padsynth = () => createTrack(7).play([[ 1.00, controlchange(64, 127) ],
[ 0.05, a5(1.07, 78) ],
[ 0.06, d3(1.09, 77) ],
[ 0.04, d5(1.15, 83) ],
[ 0.02, f5(1.27, 83) ],
[ 1.72, controlchange(64, 0) ],
[ 2.21, controlchange(64, 127) ],
[ 2.34, controlchange(64, 0) ],
[ 3.14, controlchange(64, 127) ],
[ 1.56, as4(1.94, 84) ],
[ 1.56, d5(1.96, 74) ],
[ 1.56, g5(1.98, 83) ],
[ 1.56, g2(2.06, 69) ],
[ 4.13, controlchange(64, 0) ],
[ 5.08, controlchange(64, 127) ],
[ 4.06, f5(1.06, 84) ],
[ 4.05, as4(1.10, 83) ],
[ 4.06, d5(1.14, 79) ],
[ 4.07, as2(1.25, 69) ],
[ 5.73, controlchange(64, 0) ],
[ 7.10, controlchange(64, 127) ],
[ 5.55, c5(1.75, 75) ],
[ 5.57, g5(1.75, 78) ],
[ 5.55, e5(1.78, 75) ],
[ 5.58, c3(1.94, 72) ],
[ 8.05, controlchange(64, 0) ],
[ 9.10, controlchange(64, 127) ],
[ 8.02, a5(1.18, 82) ],
[ 8.01, d5(1.22, 83) ],
[ 7.99, f5(1.28, 84) ],
[ 8.02, d3(1.28, 78) ],
[ 9.73, controlchange(64, 0) ],
[ 11.17, controlchange(64, 127) ],
[ 9.57, as4(1.92, 82) ],
[ 9.55, d5(1.94, 75) ],
[ 9.57, g5(1.99, 82) ],
[ 9.58, g2(2.09, 65) ],
[ 12.07, controlchange(64, 0) ],
[ 13.00, controlchange(64, 127) ],
[ 12.07, d5(1.04, 77) ],
[ 12.07, f5(1.05, 77) ],
[ 12.04, as4(1.16, 73) ],
[ 12.05, as2(1.23, 71) ],
[ 13.68, controlchange(64, 0) ],
[ 13.56, g4(2.21, 78) ],
[ 13.56, e5(2.24, 69) ],
[ 13.55, c5(2.26, 79) ],
[ 13.57, c3(2.28, 74) ],
[ 14, controlchange(64, 127) ],
[ 15.99, controlchange(64, 0) ],
].quantize(6));
const introbass = () => createTrack(4).play([[ 0.02, d2(1.13, 87) ],
[ 1.52, g2(2.35, 78) ],
[ 4.03, as2(1.14, 83) ],
[ 5.52, c3(1.99, 87) ],
[ 7.54, a2(0.18, 77) ],
[ 7.75, c3(0.05, 64) ],
[ 8.05, d3(0.94, 89) ],
[ 9.54, g2(2.15, 82) ],
[ 11.82, a2(0.11, 82) ],
[ 12.08, as2(1.25, 86) ],
[ 13.56, c3(1.37, 90) ],
[ 15.5, a2(0.4, 93) ]].quantize(6));
const guitar1 = () => createTrack(3).play([[ 0.51, a4(0.32, 63) ],
[ 0.82, d5(0.10, 77) ],
[ 1.30, f5(0.16, 77) ],
[ 1.81, e5(1.72, 57) ],
[ 3.56, c5(0.29, 70) ],
[ 3.86, d5(0.11, 67) ],
[ 4.34, f5(0.13, 77) ],
[ 4.83, e5(0.17, 65) ],
[ 5.34, c5(0.13, 70) ],
[ 5.82, g4(0.18, 70) ],
[ 6.32, g4(0.14, 82) ],
[ 6.83, g4(0.06, 58) ],
[ 6.90, gs4(0.11, 71) ],
[ 6.99, g4(0.29, 2) ],
[ 7.34, f4(0.11, 67) ],
[ 7.49, d4(0.51, 74) ],
[ 8.89, a4(0.13, 44) ],
[ 9.03, d5(0.30, 60) ],
[ 9.38, f5(0.14, 79) ],
[ 9.83, g5(0.20, 87) ],
[ 10.32, g5(0.15, 79) ],
[ 10.80, g5(0.05, 43) ],
[ 10.86, gs5(0.14, 69) ],
[ 11.01, g5(0.29, 2) ],
[ 11.36, f5(0.05, 57) ],
[ 11.47, d5(0.29, 78) ],
[ 11.81, c5(0.20, 74) ],
[ 12.32, d5(0.11, 62) ],
[ 12.83, a4(0.63, 52) ],
[ 13.00, d5(0.51, 78) ],
[ 13.83, g4(1.20, 42) ],
[ 13.82, c5(1.31, 49) ]]);
const piano1 = () => createTrack(0).play([[ 1.01, controlchange(64, 127) ],
[ 0.05, d3(0.97, 70) ],
[ 0.04, f4(1.13, 87) ],
[ 0.03, d5(1.19, 77) ],
[ 1.56, controlchange(64, 0) ],
[ 3.10, controlchange(64, 127) ],
[ 1.53, as4(1.68, 78) ],
[ 1.55, g3(1.66, 55) ],
[ 1.53, d5(1.70, 63) ],
[ 4.00, controlchange(64, 0) ],
[ 4.88, controlchange(64, 127) ],
[ 4.03, d5(1.06, 68) ],
[ 4.03, f5(1.09, 74) ],
[ 4.05, as3(1.08, 56) ],
[ 5.61, controlchange(64, 0) ],
[ 6.34, controlchange(64, 127) ],
[ 5.54, e5(1.53, 55) ],
[ 5.55, c5(1.59, 60) ],
[ 5.58, c4(1.65, 52) ],
[ 7.03, f5(0.48, 74) ],
[ 7.53, g5(0.15, 65) ],
[ 7.96, controlchange(64, 0) ],
[ 8.55, controlchange(64, 127) ],
[ 7.87, d5(0.68, 28) ],
[ 8.02, d4(0.88, 43) ],
[ 8.04, a5(0.87, 79) ],
[ 8.50, f5(0.45, 62) ],
[ 9.01, d5(0.05, 7) ],
[ 9.60, controlchange(64, 0) ],
[ 11.14, controlchange(64, 127) ],
[ 9.53, g3(1.71, 62) ],
[ 9.49, as4(1.82, 54) ],
[ 9.49, d5(1.90, 58) ],
[ 11.99, controlchange(64, 0) ],
[ 12.44, controlchange(64, 127) ],
[ 12.03, as3(0.73, 48) ],
[ 12.01, d5(0.78, 65) ],
[ 12.02, f5(0.77, 74) ],
[ 13.49, d5(0.05, 42) ],
[ 13.62, controlchange(64, 0) ],
[ 13.54, g5(2.28, 54) ],
[ 13.55, c4(2.28, 50) ],
[ 13.54, e5(2.29, 50) ]]);
const emptypattern = () => createTrack(0).steps(1/16,[,]);
emptypattern();
padsynth();
introbass();
await beat();
guitar1();
padsynth();
introbass();
await beat();
createTrack(1).play([[ 0.03, a4(1.22, 75) ],
[ 0.06, f5(1.24, 58) ],
[ 1.44, g4(2.46, 74) ],
[ 1.43, as4(4.00, 77) ],
[ 0.02, d5(5.53, 63) ],
[ 4.00, f5(1.60, 60) ],
[ 5.57, g4(2.28, 64) ],
[ 5.53, e5(2.52, 55) ],
[ 5.57, c5(2.51, 88) ],
[ 8.09, a4(1.28, 78) ],
[ 8.07, f5(1.41, 64) ],
[ 9.56, g4(2.39, 84) ],
[ 9.52, as4(3.70, 73) ],
[ 12.06, f5(1.23, 69) ],
[ 8.07, d5(5.26, 67) ],
[ 13.42, g4(2.32, 67) ],
[ 13.40, e5(2.36, 50) ],
[ 13.41, c5(2.35, 74) ]]);
guitar1();
padsynth();
introbass();
await beat();
const flute1 = () => createTrack(6).play([[ 0.29, d7(0.24, 67) ],
[ 0.52, f7(0.29, 82) ],
[ 0.85, a7(0.16, 83) ],
[ 1.32, a7(0.19, 59) ],
[ 1.80, g7(0.17, 83) ],
[ 2.25, g7(0.17, 72) ],
[ 2.36, gs7(0.16, 69) ],
[ 2.46, g7(0.29, 10) ],
[ 2.81, f7(0.15, 65) ],
[ 2.95, d7(0.34, 90) ],
[ 3.32, c7(0.23, 79) ],
[ 3.79, d7(0.17, 83) ],
[ 4.28, d7(0.18, 44) ],
[ 4.46, f7(0.29, 82) ],
[ 4.80, a7(0.16, 77) ],
[ 5.30, a7(0.17, 79) ],
[ 5.80, g7(0.17, 88) ],
[ 6.24, g7(0.13, 67) ],
[ 6.33, gs7(0.16, 76) ],
[ 6.48, g7(0.30, 44) ],
[ 6.84, f7(0.14, 69) ],
[ 7.00, d7(0.31, 84) ],
[ 7.34, c7(0.20, 82) ],
[ 7.82, d7(0.19, 77) ],
[ 11.36, d7(0.11, 63) ],
[ 11.49, a7(0.33, 79) ],
[ 11.86, d8(0.20, 92) ],
[ 12.35, c8(0.17, 74) ],
[ 12.80, a7(0.17, 68) ],
[ 13.20, g7(0.12, 68) ],
[ 13.27, gs7(0.16, 68) ],
[ 13.43, g7(0.31, 47) ],
[ 13.77, f7(0.14, 67) ],
[ 14.00, g7(0.22, 89) ],
[ 14.47, g7(0.15, 94) ],
[ 14.90, gs7(0.14, 68) ],
[ 14.79, g7(0.51, 60) ],
[ 15.35, f7(0.14, 75) ],
[ 15.51, d7(0.27, 84) ],
[ 15.81, c7(0.15, 83) ]]);
piano1();
flute1();
introbass();
await beat();
const strings2 = () => createTrack(1).play([[ 0.03, d3(1.44, 70) ],
[ 0.01, a4(1.47, 69) ],
[ 1.48, g3(2.50, 77) ],
[ 1.46, as4(3.82, 81) ],
[ 3.98, d5(1.5, 72) ],
[ 0.01, f5(5.5, 64) ],
[ 3.97, as3(1.56, 78) ],
[ 5.5, f5(0.04, 48) ],
[ 5.52, c5(2.22, 69) ],
[ 5.55, c4(2.38, 75) ],
[ 5.54, g5(2.43, 63) ],
[ 5.56, e5(2.43, 28) ],
[ 7.98, a5(1.43, 79) ],
[ 8.00, d4(1.53, 77) ],
[ 7.95, f5(3.93, 65) ],
[ 9.57, g3(2.43, 83) ],
[ 13.09, controlchange(64, 127) ],
[ 8.01, d5(5.22, 72) ],
[ 11.97, as5(1.33, 78) ],
[ 9.59, d6(3.74, 60) ],
[ 11.98, as3(1.52, 72) ],
[ 13.56, f5(0.04, 20) ],
[ 13.73, controlchange(64, 0) ],
[ 15.12, controlchange(64, 127) ],
[ 13.49, e6(2.30, 59) ],
[ 13.51, c4(2.27, 54) ],
[ 13.54, g5(2.27, 57) ],
[ 13.48, c6(2.36, 59) ],
[ 15.99, controlchange(64, 0) ]]);
piano1();
flute1();
strings2();
introbass();
await beat();
const strings3 = () => createTrack(1).play([[ 0.03, a5(5.27, 94) ],
[ 0.03, f5(5.49, 89) ],
[ 0.05, d2(5.49, 82) ],
[ 5.52, g5(2.33, 84) ],
[ 5.52, as5(2.41, 86) ],
[ 5.53, g2(2.46, 83) ],
[ 8.04, d2(3.89, 79) ],
[ 0.03, d6(11.95, 84) ],
[ 8.01, a5(5.18, 84) ],
[ 8.03, f5(5.31, 70) ],
[ 11.99, f2(1.56, 82) ],
[ 11.97, c6(1.61, 82) ],
[ 13.54, d5(2.38, 74) ],
[ 13.54, g5(2.39, 75) ],
[ 13.54, as5(2.41, 81) ],
[ 13.54, g2(2.43, 83) ]]);
const piano3 = () => createTrack(0).play([[ 0.04, controlchange(64, 0) ],
[ 0.35, d6(0.34, 67) ],
[ 0.75, controlchange(64, 127) ],
[ 0.53, a6(0.32, 83) ],
[ 0.99, a6(0.47, 83) ],
[ 1.48, c7(0.26, 82) ],
[ 1.81, d7(0.54, 83) ],
[ 2.37, d6(0.14, 43) ],
[ 2.50, a6(0.25, 89) ],
[ 2.96, a6(0.52, 72) ],
[ 3.47, c7(0.26, 82) ],
[ 3.78, d7(0.59, 99) ],
[ 4.36, d6(0.09, 30) ],
[ 4.47, a6(0.48, 94) ],
[ 4.96, c7(0.38, 88) ],
[ 5.45, d7(0.40, 89) ],
[ 5.76, c7(0.57, 88) ],
[ 6.43, g6(0.54, 70) ],
[ 6.95, a6(0.51, 88) ],
[ 7.46, as6(0.31, 81) ],
[ 7.81, controlchange(64, 0) ],
[ 7.91, controlchange(64, 127) ],
[ 7.78, a6(0.49, 89) ],
[ 8.31, d6(0.23, 53) ],
[ 8.53, f6(0.24, 99) ],
[ 8.95, controlchange(64, 0) ],
[ 9.02, controlchange(64, 127) ],
[ 8.99, f6(0.48, 70) ],
[ 9.48, g6(0.26, 60) ],
[ 9.80, a6(0.49, 89) ],
[ 10.35, d6(0.12, 49) ],
[ 10.50, f6(0.28, 77) ],
[ 10.91, controlchange(64, 0) ],
[ 11.00, controlchange(64, 127) ],
[ 10.95, f6(0.45, 68) ],
[ 11.46, g6(0.24, 58) ],
[ 11.79, a6(0.50, 93) ],
[ 12.36, d6(0.17, 55) ],
[ 12.52, f6(0.45, 95) ],
[ 13.01, g6(0.41, 84) ],
[ 13.51, a6(0.30, 93) ],
[ 13.89, controlchange(64, 0) ],
[ 14.02, controlchange(64, 127) ],
[ 13.82, g6(0.67, 82) ],
[ 14.92, controlchange(64, 0) ],
[ 14.53, e6(0.47, 64) ],
[ 15.05, controlchange(64, 127) ],
[ 14.99, f6(0.47, 78) ],
[ 15.48, g6(0.34, 74) ]].quantize(6));
const bass3 = () => createTrack(4).play([
[ 0.04, d2(0.38, 89) ],
[ 0.84, d2(0.26, 88) ],
[ 1.55, d2(1.90, 90) ],
[ 3.50, a2(0.14, 68) ],
[ 3.82, d3(0.14, 82) ],
[ 4.35, d3(0.14, 72) ],
[ 4.55, a2(0.12, 77) ],
[ 5.02, d2(0.68, 89) ],
[ 5.87, d3(0.14, 70) ],
[ 6.02, g2(0.22, 82) ],
[ 6.55, g2(0.45, 67) ],
[ 7.50, g2(0.39, 68) ],
[ 8.02, d2(0.51, 78) ],
[ 8.82, d2(0.31, 79) ],
[ 9.53, d2(2.00, 82) ],
[ 11.58, d3(0.12, 77) ],
[ 11.88, f2(0.20, 84) ],
[ 12.37, f2(0.19, 89) ],
[ 12.85, f2(0.20, 84) ],
[ 13.07, f3(0.35, 95) ],
[ 13.51, f2(0.16, 82) ],
[ 14.02, g2(0.57, 84) ],
[ 14.89, g2(0.24, 72) ],
[ 15.00, a2(0.38, 79) ],
[ 15.54, c3(0.31, 87) ]].quantize(6));
strings3();
piano3();
bass3();
await beat();
const guitar4 = () => createTrack(3).play([[ 0.53, a4(0.36, 82) ],
[ 0.86, c5(0.16, 98) ],
[ 1.38, a4(0.05, 25) ],
[ 2.07, controlchange(64, 127) ],
[ 1.49, c5(1.02, 92) ],
[ 2.47, d5(0.25, 88) ],
[ 2.86, controlchange(64, 0) ],
[ 3.51, a4(0.17, 64) ],
[ 3.82, c5(0.16, 98) ],
[ 3.82, f5(0.17, 94) ],
[ 4.32, c5(0.17, 92) ],
[ 4.34, f5(0.20, 88) ],
[ 4.87, a4(0.07, 13) ],
[ 5.01, f5(0.24, 94) ],
[ 5.00, c5(0.29, 100) ],
[ 5.55, c5(0.32, 94) ],
[ 5.56, f5(0.33, 94) ],
[ 6.05, g4(0.26, 88) ],
[ 6.05, e5(0.28, 79) ],
[ 6.04, c5(0.31, 75) ],
[ 6.83, e5(0.24, 82) ],
[ 6.82, c5(0.25, 84) ],
[ 7.36, c5(0.16, 82) ],
[ 7.35, e5(0.19, 65) ],
[ 7.89, a4(1.06, 74) ],
[ 7.88, f5(1.55, 89) ],
[ 9.79, a5(1.75, 95) ],
[ 9.53, d5(2.11, 57) ],
[ 11.52, g5(0.14, 88) ],
[ 11.87, a5(0.18, 108) ],
[ 12.35, c6(0.24, 87) ],
[ 12.81, c6(0.13, 90) ],
[ 12.89, d6(0.22, 89) ],
[ 13.30, c6(0.23, 89) ],
[ 13.78, a5(0.17, 92) ],
[ 14.25, g5(0.21, 93) ],
[ 14.80, f5(0.11, 63) ],
[ 14.98, g5(0.20, 94) ],
[ 15.40, gs5(0.11, 63) ],
[ 15.30, g5(0.52, 94) ],
[ 15.84, f5(0.15, 83) ]]);
guitar4();
strings3();
piano3();
bass3();
await beat();
const beat2 = () => createTrack(2).steps(6,[
[c5,fs5],,[d5(0.2,20),fs5(0.5,5)],fs5,,[fs5(0.5,5)],
[c5,d5,fs5],,fs5(0.5,5),[fs5],,fs5(0.5,5),
[c5,fs5],,fs5(0.5,5),[fs5],,[c5(0.5,30),fs5(0.5,5)],
[c5, d5,fs5],,fs5(0.1,5),[fs5(0.1)],,[d5(0.1,30),fs5(0.1,5)],
].repeat(3));
const padsynth2 = () => createTrack(7).play([[ 1.09, controlchange(64, 127) ],
[ 0.03, f5(1.22, 77) ],
[ 0.11, a5(1.25, 68) ],
[ 1.54, d5(0.82, 60) ],
[ 1.56, f5(0.94, 74) ],
[ 0.01, as2(2.63, 62) ],
[ 3.80, d5(0.17, 39) ],
[ 3.85, f5(0.44, 52) ],
[ 4.06, d6(0.34, 75) ],
[ 3.99, a5(0.46, 37) ],
[ 4.87, c6(0.50, 94) ],
[ 5.39, a5(0.34, 87) ],
[ 5.88, g5(0.40, 68) ],
[ 6.36, f5(0.36, 62) ],
[ 4.03, as2(3.08, 46) ],
[ 6.87, e5(0.45, 53) ],
[ 7.43, c5(0.08, 53) ],
[ 8.07, controlchange(64, 0) ],
[ 9.11, controlchange(64, 127) ],
[ 8.10, c5(1.22, 67) ],
[ 8.02, a4(1.31, 69) ],
[ 7.95, f4(2.69, 54) ],
[ 8.14, e5(2.67, 60) ],
[ 9.56, c5(1.28, 72) ],
[ 8.13, d3(2.83, 29) ],
[ 11.98, controlchange(64, 0) ],
[ 11.91, g5(0.20, 65) ],
[ 12.11, controlchange(64, 127) ],
[ 11.86, e5(0.45, 42) ],
[ 12.07, c6(0.32, 88) ],
[ 12.42, d6(0.25, 94) ],
[ 12.89, e6(0.32, 77) ],
[ 13.36, g6(0.41, 83) ],
[ 13.89, f6(0.42, 70) ],
[ 14.36, e6(0.38, 65) ],
[ 14.82, c6(0.57, 64) ],
[ 11.97, d4(3.84, 50) ],
[ 15.38, d6(0.48, 60) ],
[ 15.97, controlchange(64, 0) ]]);
const bass4 = () => createTrack(4).play([[ 0.04, as2(0.97, 72) ],
[ 1.06, f3(0.74, 63) ],
[ 1.81, as3(0.14, 66) ],
[ 2.36, as3(0.17, 33) ],
[ 2.58, f3(0.05, 53) ],
[ 3.04, as3(0.48, 76) ],
[ 3.56, f3(0.45, 62) ],
[ 4.05, as2(0.89, 72) ],
[ 5.00, f3(0.23, 64) ],
[ 5.28, as3(0.16, 59) ],
[ 5.80, c4(0.19, 65) ],
[ 6.32, c4(0.14, 48) ],
[ 6.49, g3(0.48, 63) ],
[ 7.01, c3(0.47, 74) ],
[ 7.53, g3(0.39, 57) ],
[ 8.01, d3(0.93, 77) ],
[ 8.99, a3(0.26, 55) ],
[ 9.32, c4(0.15, 72) ],
[ 9.79, d4(0.16, 60) ],
[ 10.28, c4(0.20, 54) ],
[ 10.83, a3(0.17, 55) ],
[ 11.29, a3(0.17, 54) ],
[ 11.52, c4(0.13, 48) ],
[ 11.85, d4(0.12, 72) ],
[ 12.04, d3(0.82, 78) ],
[ 12.94, d4(0.11, 75) ],
[ 13.28, c4(0.05, 63) ],
[ 13.83, a3(0.16, 70) ],
[ 14.31, gs3(0.20, 71) ],
[ 14.85, g3(0.16, 55) ],
[ 15.37, f3(0.30, 78) ]].quantize(6));
const whistle = () => createTrack(6).play([[ 0.02, f7(0.48, 43) ],
[ 0.50, d7(0.25, 53) ],
[ 0.99, c7(0.23, 70) ],
[ 1.31, d7(0.23, 54) ],
[ 1.78, a6(0.30, 58) ],
[ 12.47, g7(0.03, 42) ],
[ 12.47, gs7(0.10, 63) ],
[ 12.53, a7(0.31, 74) ],
[ 12.97, c8(0.35, 87) ],
[ 13.47, c8(0.03, 67) ],
[ 13.49, cs8(0.02, 68) ],
[ 13.52, d8(0.24, 90) ],
[ 14.01, c8(0.03, 69) ],
[ 14.02, cs8(0.02, 56) ],
[ 14.05, d8(0.22, 93) ],
[ 14.32, c8(0.22, 68) ],
[ 14.57, a7(0.14, 87) ],
[ 14.82, gs7(0.17, 83) ],
[ 15.02, g7(0.27, 62) ],
[ 15.35, f7(0.04, 52) ],
[ 15.53, d7(0.25, 58) ],
[ 15.83, c7(0.07, 63) ]]);
bass4();
padsynth2();
whistle();
await beat2();
createTrack(1).play([[ 0.08, d5(5.71, 49) ],
[ 0.09, a5(5.74, 54) ],
[ 0.06, as2(5.95, 48) ],
[ 6.04, c3(0.05, 42) ],
[ 6.03, e5(1.65, 37) ],
[ 6.02, g5(1.74, 67) ],
[ 0.06, d6(7.97, 54) ],
[ 6.18, c3(1.91, 11) ],
[ 8.06, c6(4.03, 35) ],
[ 8.07, e6(4.39, 58) ],
[ 8.09, d3(7.80, 55) ],
[ 8.03, f5(7.87, 60) ],
[ 12.03, a5(3.88, 55) ]]);
bass4();
padsynth2();
whistle();
await beat2();
const kickbeat = () => createTrack(2).steps(6,[
[c5,fs5],,[d5(0.2,20),fs5(0.5,5)],fs5,,[fs5(0.5,5)],
[c5,fs5],,fs5(0.5,5),[fs5],,fs5(0.5,5),
[c5,fs5],,fs5(0.5,5),[fs5],,[c5(0.5,30),fs5(0.5,5)],
[c5, d5,fs5],,fs5(0.1,5),[fs5(0.1)],,[d5(0.1,30),fs5(0.1,5)],
].repeat(3));
const endstrings = () => createTrack(1).play([[ 0.02, d3(1.46, 78) ],
[ 0.02, a5(1.46, 68) ],
[ 1.50, g3(2.45, 74) ],
[ 1.49, as5(2.53, 76) ],
[ 4.00, f3(1.50, 69) ],
[ 0.02, f5(5.49, 65) ],
[ 4.03, a5(1.53, 59) ],
[ 4.02, c5(3.93, 60) ],
[ 5.56, c3(2.42, 63) ],
[ 5.53, g5(2.52, 64) ],
[ 5.51, e5(2.61, 52) ],
[ 8.09, a5(1.41, 59) ],
[ 8.06, d3(1.46, 77) ],
[ 9.53, as5(2.25, 81) ],
[ 9.53, g3(2.42, 64) ],
[ 8.10, d5(3.97, 67) ],
[ 11.99, a5(1.43, 43) ],
[ 11.99, f3(1.46, 79) ],
[ 8.09, f5(5.39, 63) ],
[ 13.50, c3(2.40, 68) ],
[ 11.98, c6(3.93, 67) ],
[ 13.47, e5(2.45, 44) ],
[ 13.45, g5(2.49, 58) ]]);
const endguitar = () => createTrack(3).play([[ 0.03, a5(0.57, 82) ],
[ 1.05, f5(0.56, 82) ],
[ 1.51, a5(0.22, 54) ],
[ 0.03, d4(1.89, 75) ],
[ 0.52, d5(1.44, 63) ],
[ 1.76, f5(0.33, 8) ],
[ 1.80, as5(0.88, 83) ],
[ 2.52, d5(0.94, 60) ],
[ 2.96, f5(0.59, 64) ],
[ 3.41, as5(0.38, 83) ],
[ 2.01, g4(1.81, 55) ],
[ 3.75, a5(0.75, 72) ],
[ 4.93, f5(0.56, 69) ],
[ 5.46, a5(0.33, 72) ],
[ 4.43, c5(1.41, 68) ],
[ 3.88, f4(2.00, 52) ],
[ 5.75, g5(0.70, 78) ],
[ 6.76, f5(0.73, 63) ],
[ 6.43, c5(1.49, 70) ],
[ 7.48, e5(0.51, 65) ],
[ 5.96, c4(2.05, 59) ],
[ 7.98, a5(0.57, 79) ],
[ 8.78, f5(0.59, 62) ],
[ 8.53, d5(0.92, 58) ],
[ 9.36, a5(0.38, 79) ],
[ 7.97, d4(1.95, 74) ],
[ 9.69, d5(0.60, 8) ],
[ 9.95, as5(0.61, 83) ],
[ 10.47, d5(0.83, 59) ],
[ 10.80, g5(0.52, 60) ],
[ 11.31, as5(0.51, 94) ],
[ 9.95, g4(1.92, 64) ],
[ 11.83, a5(0.69, 83) ],
[ 12.82, c6(0.39, 65) ],
[ 13.35, a5(0.24, 72) ],
[ 12.54, c5(1.46, 72) ],
[ 11.98, f4(2.02, 22) ],
[ 13.81, g5(0.71, 78) ],
[ 14.80, f5(0.39, 72) ],
[ 14.49, c5(1.41, 63) ],
[ 15.28, e5(0.64, 55) ],
[ 14.04, c4(1.89, 68) ]].quantize(6));
const endbass = () => createTrack(4).play([[ 0.05, d2(1.81, 87) ],
[ 2.02, g2(1.90, 87) ],
[ 4.00, f2(1.98, 84) ],
[ 6.04, c3(1.77, 84) ],
[ 7.81, cs3(0.10, 63) ],
[ 8.02, d3(1.94, 94) ],
[ 10.04, g2(1.93, 78) ],
[ 12.03, f2(1.90, 83) ],
[ 14.02, c3(0.68, 87) ],
[ 14.79, g3(0.17, 78) ],
[ 15.01, c4(0.94, 89) ]].quantize(6));
endstrings();
endguitar();
endbass();
await kickbeat();
const endpiano = () => createTrack(0).play([[ 0.09, controlchange(64, 127) ],
[ 0.05, a5(0.41, 97) ],
[ 0.79, f5(0.55, 89) ],
[ 0.48, d5(0.96, 60) ],
[ 1.33, a5(0.20, 83) ],
[ 1.98, controlchange(64, 0) ],
[ 2.22, controlchange(64, 127) ],
[ 1.86, as5(0.70, 94) ],
[ 2.56, d5(0.39, 62) ],
[ 3.09, controlchange(64, 0) ],
[ 2.90, g5(0.31, 87) ],
[ 3.37, controlchange(64, 127) ],
[ 3.27, as5(0.35, 101) ],
[ 3.95, controlchange(64, 0) ],
[ 4.24, controlchange(64, 127) ],
[ 3.80, a5(0.73, 89) ],
[ 4.58, c5(0.30, 74) ],
[ 4.95, controlchange(64, 0) ],
[ 4.87, f5(0.41, 95) ],
[ 5.30, controlchange(64, 127) ],
[ 5.30, a5(0.35, 89) ],
[ 5.87, controlchange(64, 0) ],
[ 6.10, controlchange(64, 127) ],
[ 5.84, g5(0.57, 77) ],
[ 6.78, controlchange(64, 0) ],
[ 6.46, c5(0.48, 65) ],
[ 7.07, controlchange(64, 127) ],
[ 6.78, f5(0.52, 69) ],
[ 7.46, controlchange(64, 0) ],
[ 7.32, e5(0.63, 78) ],
[ 8.13, controlchange(64, 127) ],
[ 8.03, a5(0.45, 94) ],
[ 8.69, controlchange(64, 0) ],
[ 9.08, controlchange(64, 127) ],
[ 8.81, f5(0.52, 79) ],
[ 8.50, d5(0.84, 48) ],
[ 9.35, a5(0.20, 87) ],
[ 9.89, controlchange(64, 0) ],
[ 10.12, controlchange(64, 127) ],
[ 9.84, as5(0.66, 94) ],
[ 10.81, controlchange(64, 0) ],
[ 10.53, d5(0.45, 58) ],
[ 11.16, controlchange(64, 127) ],
[ 10.84, g5(0.43, 70) ],
[ 11.30, as5(0.32, 97) ],
[ 11.87, controlchange(64, 0) ],
[ 12.10, controlchange(64, 127) ],
[ 11.81, a5(0.66, 89) ],
[ 12.79, controlchange(64, 0) ],
[ 12.55, c5(0.31, 60) ],
[ 13.07, controlchange(64, 127) ],
[ 12.80, c6(0.46, 84) ],
[ 13.32, a5(0.36, 98) ],
[ 13.82, controlchange(64, 0) ],
[ 14.06, controlchange(64, 127) ],
[ 13.85, g5(0.32, 83) ],
[ 14.42, controlchange(64, 0) ],
[ 14.55, controlchange(64, 127) ],
[ 14.38, g5(0.29, 93) ],
[ 14.96, controlchange(64, 0) ],
[ 14.85, f5(0.48, 84) ],
[ 15.41, controlchange(64, 127) ],
[ 15.35, e5(0.46, 89) ],
[ 15.93, controlchange(64, 0) ]].quantize(6));
endstrings();
endguitar();
endbass();
endpiano();
await kickbeat();
const endflute = () => createTrack(6).play([[ 0.45, d7(0.24, 69) ],
[ 0.76, f7(0.20, 84) ],
[ 1.25, a7(0.15, 74) ],
[ 1.79, as7(0.59, 96) ],
[ 2.50, d7(0.24, 67) ],
[ 2.81, g7(0.21, 68) ],
[ 3.21, as7(0.20, 83) ],
[ 3.78, a7(0.69, 87) ],
[ 4.53, c7(0.15, 82) ],
[ 4.78, f7(0.15, 74) ],
[ 5.24, a7(0.34, 60) ],
[ 5.80, g7(0.26, 84) ],
[ 6.31, g7(0.27, 67) ],
[ 6.84, f7(0.32, 74) ],
[ 7.31, e7(0.42, 65) ],
[ 8.02, a7(0.39, 88) ],
[ 8.48, d7(0.32, 60) ],
[ 8.79, f7(0.32, 70) ],
[ 9.31, a7(0.14, 83) ],
[ 9.81, as7(0.71, 94) ],
[ 10.49, d7(0.17, 65) ],
[ 10.81, g7(0.26, 65) ],
[ 11.27, as7(0.23, 91) ],
[ 11.79, a7(0.73, 82) ],
[ 12.56, c7(0.10, 63) ],
[ 12.84, c8(0.30, 95) ],
[ 13.35, a7(0.18, 70) ],
[ 13.81, g7(0.25, 74) ],
[ 14.33, g7(0.25, 89) ],
[ 14.84, f7(0.25, 65) ],
[ 15.35, e7(0.31, 82) ]]);
endstrings();
endguitar();
endbass();
endpiano();
endflute();
await kickbeat();
const highendstrings = () => createTrack(1).play([[ 0.20, controlchange(64, 127) ],
[ 0.77, controlchange(64, 0) ],
[ 1.00, controlchange(64, 127) ],
[ 0.05, d5(1.89, 77) ],
[ 0.07, a5(1.93, 94) ],
[ 2.03, controlchange(64, 0) ],
[ 3.02, controlchange(64, 127) ],
[ 1.99, as5(1.27, 84) ],
[ 0.06, f6(3.27, 95) ],
[ 1.98, g4(1.87, 78) ],
[ 4.01, controlchange(64, 0) ],
[ 5.04, controlchange(64, 127) ],
[ 3.94, f4(1.99, 60) ],
[ 3.92, a6(2.02, 82) ],
[ 3.91, f6(2.09, 82) ],
[ 6.13, controlchange(64, 0) ],
[ 7.05, controlchange(64, 127) ],
[ 5.99, g6(1.38, 69) ],
[ 5.98, e6(1.40, 69) ],
[ 3.93, c6(3.47, 74) ],
[ 6.01, c5(1.90, 65) ],
[ 8.09, controlchange(64, 0) ],
[ 9.09, controlchange(64, 127) ],
[ 8.01, d5(2.02, 70) ],
[ 8.01, a5(2.05, 84) ],
[ 10.11, controlchange(64, 0) ],
[ 11.10, controlchange(64, 127) ],
[ 10.04, as5(1.33, 86) ],
[ 7.99, f6(3.41, 88) ],
[ 10.06, g4(1.89, 79) ],
[ 12.08, controlchange(64, 0) ],
[ 13.07, controlchange(64, 127) ],
[ 12.01, c6(1.45, 79) ],
[ 11.99, f6(1.52, 83) ],
[ 12.01, a6(1.55, 83) ],
[ 12.02, f4(1.66, 67) ],
[ 14.19, controlchange(64, 0) ],
[ 14.01, c5(1.87, 67) ],
[ 14.01, e6(1.89, 68) ],
[ 13.99, c7(1.91, 87) ],
[ 13.99, g6(1.93, 79) ]]);
endguitar();
endbass();
endpiano();
endflute();
highendstrings();
await kickbeat();
createTrack(6).play([[ 0.46, g7(0.03, 65) ],
[ 0.45, gs7(0.11, 81) ],
[ 0.51, a7(0.33, 88) ],
[ 1.01, c8(0.27, 104) ],
[ 1.57, d8(0.22, 104) ],
[ 2.02, d8(0.41, 93) ],
[ 2.53, c8(0.28, 88) ],
[ 2.84, a7(0.11, 75) ],
[ 2.98, c8(0.26, 87) ],
[ 3.33, c8(0.15, 90) ],
[ 3.43, d8(0.18, 89) ],
[ 3.81, c8(0.64, 95) ],
[ 4.94, gs7(0.14, 91) ],
[ 5.00, a7(0.17, 87) ],
[ 5.22, g7(0.31, 47) ],
[ 5.54, f7(0.19, 97) ],
[ 5.86, g7(0.27, 107) ],
[ 6.33, g7(0.20, 87) ],
[ 6.85, gs7(0.19, 69) ],
[ 6.77, g7(0.55, 82) ],
[ 7.35, f7(0.19, 89) ],
[ 7.53, d7(0.27, 75) ],
[ 7.84, c7(0.17, 97) ],
[ 8.05, d7(0.47, 103) ],
[ 8.91, d7(0.08, 63) ],
[ 8.99, f7(0.45, 89) ],
[ 9.51, g7(0.22, 93) ],
[ 10.00, gs7(0.10, 94) ],
[ 10.07, a7(0.35, 79) ],
[ 10.52, c8(0.17, 97) ],
[ 10.91, c8(0.21, 97) ],
[ 11.33, c8(0.13, 75) ],
[ 11.40, d8(0.20, 88) ],
[ 11.83, c8(0.32, 90) ],
[ 12.29, a7(0.11, 68) ],
[ 12.48, c8(0.23, 78) ],
[ 12.97, c8(0.23, 94) ],
[ 13.47, c8(0.09, 87) ],
[ 13.53, d8(0.24, 82) ],
[ 13.83, c8(0.20, 92) ],
[ 14.30, gs7(0.08, 83) ],
[ 14.35, a7(0.14, 78) ],
[ 14.47, g7(0.32, 63) ],
[ 14.82, f7(0.12, 67) ],
[ 15.04, g7(0.28, 102) ],
[ 15.51, g7(0.14, 78) ],
[ 15.57, a7(0.31, 94) ]]);
const endbass2 = () => createTrack(4).play([
[ 0.0, d3(0.5, 68) ],
[ 0.78, a3(0.17, 68) ],
[ 0.98, d4(0.20, 89) ],
[ 1.50, d4(0.29, 78) ],
[ 2.03, g3(1.18, 97) ],
[ 3.39, d3(0.17, 78) ],
[ 3.54, g3(0.45, 84) ],
[ 4.07, f3(0.66, 88) ],
[ 4.83, c4(0.18, 75) ],
[ 5.07, f4(0.19, 88) ],
[ 5.53, f4(0.20, 83) ],
[ 6.02, c4(0.74, 75) ],
[ 6.83, a3(0.15, 74) ],
[ 7.01, c4(0.24, 89) ],
[ 7.35, d4(0.14, 87) ],
[ 7.85, d4(0.14, 78) ],
[ 8.03, d3(0.73, 82) ],
[ 8.79, a3(0.17, 60) ],
[ 8.97, c4(0.21, 88) ],
[ 9.49, d4(0.30, 89) ],
[ 10.03, g3(1.09, 94) ],
[ 11.35, fs3(0.20, 69) ],
[ 11.82, f3(0.99, 94) ],
[ 12.82, c4(0.19, 75) ],
[ 13.05, f4(0.15, 94) ],
[ 13.53, f4(0.22, 84) ],
[ 14.03, c4(0.48, 87) ],
[ 14.83, c4(0.16, 84) ],
[ 15.28, c4(0.20, 77) ],
[ 15.49, d4(0.29, 92) ]].quantize(6));
endguitar();
endbass2();
endpiano();
highendstrings();
await kickbeat();
createTrack(0).play([[ 0.80, controlchange(64, 127) ],
[ 0.02, a5(1.19, 48) ],
[ 0.49, d6(0.75, 52) ],
[ 0.82, f6(0.45, 60) ],
[ 0.03, f5(1.25, 43) ],
[ 0.03, d5(1.25, 35) ],
[ 1.27, a6(0.20, 72) ],
[ 1.92, controlchange(64, 0) ],
[ 1.81, d6(0.16, 43) ],
[ 2.09, controlchange(64, 127) ],
[ 1.96, as6(0.56, 88) ],
[ 2.77, g6(0.42, 49) ],
[ 2.48, d6(0.77, 44) ],
[ 1.94, g4(1.44, 37) ],
[ 1.90, d5(1.50, 30) ],
[ 1.90, as4(1.53, 26) ],
[ 3.32, as6(0.36, 84) ],
[ 3.98, controlchange(64, 0) ],
[ 3.81, c6(0.23, 39) ],
[ 4.14, controlchange(64, 127) ],
[ 4.01, a6(0.45, 88) ],
[ 4.48, c6(0.71, 39) ],
[ 3.97, f4(1.25, 32) ],
[ 3.96, a4(1.30, 14) ],
[ 3.98, c5(1.33, 43) ],
[ 4.76, f6(0.82, 55) ],
[ 5.29, a6(0.36, 57) ],
[ 6.02, controlchange(64, 0) ],
[ 5.80, c6(0.30, 19) ],
[ 6.14, controlchange(64, 127) ],
[ 6.06, g6(0.79, 89) ],
[ 6.54, c6(0.79, 54) ],
[ 6.80, f6(0.57, 87) ],
[ 7.34, e6(0.09, 72) ],
[ 5.94, c5(1.50, 34) ],
[ 5.91, e5(1.55, 15) ],
[ 5.98, g5(1.50, 34) ],
[ 7.98, controlchange(64, 0) ],
[ 7.79, d6(0.25, 49) ],
[ 8.15, controlchange(64, 127) ],
[ 8.01, a6(0.45, 89) ],
[ 7.98, a5(1.18, 37) ],
[ 7.85, f5(1.38, 20) ],
[ 7.90, d5(1.34, 30) ],
[ 8.48, d6(0.82, 50) ],
[ 8.85, f6(0.47, 64) ],
[ 9.30, a6(0.12, 63) ],
[ 9.94, controlchange(64, 0) ],
[ 9.78, d6(0.23, 49) ],
[ 10.06, controlchange(64, 127) ],
[ 10.00, as6(0.23, 87) ],
[ 10.50, c7(0.05, 62) ],
[ 10.77, d7(0.53, 64) ],
[ 9.97, g4(1.51, 25) ],
[ 9.84, as4(1.68, 19) ],
[ 11.30, c7(0.23, 72) ],
[ 9.96, d5(1.57, 16) ],
[ 11.54, as6(0.27, 66) ],
[ 12.01, controlchange(64, 0) ],
[ 12.16, controlchange(64, 127) ],
[ 11.89, c7(0.43, 72) ],
[ 12.36, f7(0.22, 78) ],
[ 12.82, c7(0.42, 68) ],
[ 12.05, f4(1.30, 28) ],
[ 11.99, a4(1.38, 35) ],
[ 13.27, as6(0.13, 62) ],
[ 12.00, c5(1.41, 39) ],
[ 13.39, c7(0.12, 65) ],
[ 13.47, as6(0.12, 17) ],
[ 13.55, a6(0.21, 65) ],
[ 13.99, controlchange(64, 0) ],
[ 13.84, g6(0.29, 63) ],
[ 14.17, controlchange(64, 127) ],
[ 14.36, g6(0.32, 72) ],
[ 15.00, controlchange(64, 0) ],
[ 15.13, controlchange(64, 127) ],
[ 14.82, f6(0.50, 60) ],
[ 14.02, g5(1.78, 43) ],
[ 14.03, c5(1.78, 35) ],
[ 14.02, e5(1.84, 23) ],
[ 15.35, e6(0.52, 58) ],
[ 15.89, controlchange(64, 0) ]]);
endbass2();
await kickbeat();
loopHere();
/*
* (c) Peter Johan Salomonsen 2021
*/
import { DelayLineFloat, outputline, MonoAudioPlayer, hardclip, AuxExciterWaveGuide, allocateAudioBuffer, LoPassBiQuadFilter, HiPassBiQuadFilter, noise, Freeverb, WaveGuide, AllPassFloat, beatToFrame, AudioPlayer, cos, outputline, Limiter, TriangleOscillator, PI, sin, cos, FFT, EQBand, TriBandEQ, EnvelopeState, Pan, SineOscillator, IFFTOscillator, BiQuadFilter, FilterType, Q_BUTTERWORTH, DelayLine, BandPass,SawOscillator,softclip, midichannels, MidiChannel, MidiVoice, StereoSignal, SineOscillator, Envelope } from '../mixes/globalimports';
import { SAMPLERATE } from '../environment';
const BPM: f32 = 85;
function notefreq(note: f32): f32 {
return 440 * Mathf.pow(2, (-69 + note) / 12);
}
const delayframes = (SAMPLERATE * (2/8) * 60 / BPM) as usize;
const echoLeft = new DelayLine(delayframes);
const echoRight = new DelayLine(delayframes);
const echoline = new StereoSignal();
class MultiBandEQ {
bands: StaticArray<EQBand>;
constructor(freqs: f32[]) {
this.bands = new StaticArray<EQBand>(freqs.length - 1);
for ( let n=1; n<freqs.length; n++) {
this.bands[n-1] = new EQBand(freqs[n-1], freqs[n]);
}
}
process(signal: f32, levels: f32[]): f32 {
let ret: f32 = 0;
for (let n = 0;n<this.bands.length; n++) {
ret += this.bands[n].process(signal) * levels[n];
}
return ret;
}
}
export class WaveGuideFeedbackLimit {
envExciter: Envelope;
filterExciter: BiQuadFilter = new BiQuadFilter();
delay: DelayLineFloat = new DelayLineFloat((SAMPLERATE / notefreq(1)) as i32);
filterFeedback: BiQuadFilter = new BiQuadFilter();
feedbackLevel: f32;
feedbackFilterFreq: f32;
freq: f32;
exciterenvlevel: f32;
constructor(exciterAttack: f32, exciterRelease: f32, exciterFilterFreq: f32, feedbackLevel: f32) {
this.envExciter = new Envelope(exciterAttack,
exciterRelease, 0,
exciterRelease);
this.filterExciter.update_coeffecients(FilterType.LowPass, SAMPLERATE,
exciterFilterFreq, Q_BUTTERWORTH);
this.feedbackLevel = feedbackLevel;
}
setFilterExciterFreq(freq: f32): void {
this.filterExciter.update_coeffecients(FilterType.LowPass, SAMPLERATE,
freq, Q_BUTTERWORTH);
}
start(freq: f32, feedbackFilterFreq: f32): void {
if (freq != this.freq) {
this.freq = freq;
const maxFeedbackFilterFreq: f32 = 20000;
if (feedbackFilterFreq > maxFeedbackFilterFreq as f32) {
feedbackFilterFreq = maxFeedbackFilterFreq as f32;
} else if (feedbackFilterFreq < 10) {
feedbackFilterFreq = 10;
}
this.filterFeedback.update_coeffecients(FilterType.LowPass, SAMPLERATE,
feedbackFilterFreq, Q_BUTTERWORTH);
this.filterFeedback.coeffs.calculatePhaseAndMagnitudeForFreq(freq);
const filterphase = this.filterFeedback.coeffs.phaseSamples;
this.filterFeedback.clearBuffers();
this.filterExciter.clearBuffers();
this.feedbackFilterFreq = feedbackFilterFreq;
this.delay.setNumFramesAndClear(
(SAMPLERATE /
(freq)
) - filterphase
);
this.envExciter.val = 0;
}
this.exciterenvlevel = 1;
this.envExciter.attack();
}
process(): f32 {
const envexciter = this.envExciter.next() * this.exciterenvlevel;
let exciterSignal: f32 = noise() * envexciter;
exciterSignal = this.filterExciter.process(exciterSignal);
const feedback = this.delay.read();
let signal = exciterSignal + feedback;
signal = this.filterFeedback.processForm2(signal);
this.delay.write_and_advance(
Mathf.tanh(signal * this.feedbackLevel)
);
return signal;
}
}
export class BandPassWaveGuide {
envExciter: Envelope;
filterExciter: BiQuadFilter = new BiQuadFilter();
delay: DelayLineFloat = new DelayLineFloat((SAMPLERATE / notefreq(1)) as i32);
hipass: HiPassBiQuadFilter = new HiPassBiQuadFilter();
filterFeedback: BiQuadFilter = new BiQuadFilter();
feedbackLevel: f32;
feedbackFilterFreq: f32;
freq: f32;
exciterenvlevel: f32;
constructor(exciterAttack: f32, exciterRelease: f32, exciterFilterFreq: f32, feedbackLevel: f32) {
this.envExciter = new Envelope(exciterAttack,
exciterRelease, 0,
exciterRelease);
this.filterExciter.update_coeffecients(FilterType.LowPass, SAMPLERATE,
exciterFilterFreq, Q_BUTTERWORTH);
this.feedbackLevel = feedbackLevel;
}
setFilterExciterFreq(freq: f32): void {
this.filterExciter.update_coeffecients(FilterType.LowPass, SAMPLERATE,
freq, Q_BUTTERWORTH);
}
start(freq: f32, feedbackFilterFreq: f32): void {
freq*=1.6;
if (freq != this.freq) {
this.freq = freq;
const maxFeedbackFilterFreq: f32 = 20000;
if (feedbackFilterFreq > maxFeedbackFilterFreq as f32) {
feedbackFilterFreq = maxFeedbackFilterFreq as f32;
} else if (feedbackFilterFreq < 10) {
feedbackFilterFreq = 10;
}
this.filterFeedback.update_coeffecients(FilterType.LowPass, SAMPLERATE,
feedbackFilterFreq, Q_BUTTERWORTH);
this.hipass.update(freq * 0.5 , 0.93);
this.hipass.coeffs.calculatePhaseAndMagnitudeForFreq(freq);
this.filterFeedback.coeffs.calculatePhaseAndMagnitudeForFreq(freq);
const filterphase = this.filterFeedback.coeffs.phaseSamples +
this.hipass.coeffs.phaseSamples;
this.hipass.clearBuffers();
this.filterFeedback.clearBuffers();
this.filterExciter.clearBuffers();
this.feedbackFilterFreq = feedbackFilterFreq;
this.delay.setNumFramesAndClear(
(SAMPLERATE /
(freq)
) - filterphase
);
this.envExciter.val = 0;
}
this.exciterenvlevel = 1;
this.envExciter.attack();
}
process(): f32 {
const envexciter = this.envExciter.next() * this.exciterenvlevel;
let exciterSignal: f32 = noise() * envexciter;
exciterSignal = this.filterExciter.process(exciterSignal);
const feedback = this.delay.read();
let signal = exciterSignal + feedback;
signal = this.filterFeedback.processForm2(signal);
signal = this.hipass.process(signal);
this.delay.write_and_advance(
Mathf.tanh(signal * this.feedbackLevel)
);
return signal;
}
}
class PianoWaveGuide extends WaveGuide {
hipass: HiPassBiQuadFilter = new HiPassBiQuadFilter();
constructor() {
super(0.001,0.15,600,0.25);
this.hipass.update(30, Q_BUTTERWORTH);
}
process(): f32 {
return this.hipass.process(super.process());
}
}
class Piano extends MidiVoice {
env: Envelope = new Envelope(0.001, 0.04, 1.0, 0.3);
waveguide1: AuxExciterWaveGuide = new AuxExciterWaveGuide(new PianoWaveGuide());
waveguide2: AuxExciterWaveGuide = new AuxExciterWaveGuide(new PianoWaveGuide());
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq: f32 = notefreq(note);
let feedbackfreq: f32 = note as f32 * 155;
let feedbacklevel: f32 = 0.999 * (-(1/(freq + 25)) + 1.00000) as f32;
if (feedbacklevel > 0.999) {
feedbacklevel = 0.999;
} else if (feedbacklevel < 0) {
feedbacklevel = 0;
}
this.waveguide1.feedbackLevel = feedbacklevel;
this.waveguide1.start(freq , feedbackfreq);
this.waveguide1.exciter.start(10000 + note ,700 + freq * 0.65);
this.waveguide1.exciter.exciterenvlevel = velocity / 127.0 as f32;
this.waveguide2.feedbackLevel = feedbacklevel;
this.waveguide2.start(freq , feedbackfreq);
this.waveguide2.exciter.start(10000 + note, 700 + freq * 0.65);
this.waveguide2.exciter.exciterenvlevel = velocity / 127.0 as f32;
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone() && this.waveguide1.exciter.envExciter.isDone() && this.waveguide2.exciter.envExciter.isDone();
}
nextframe(): void {
let env = this.env.next();
const wg1: f32 = this.waveguide1.process() * env;
const wg2: f32 = this.waveguide2.process() * env;
this.channel.signal.left += 2 *((wg1) + wg2 * 0.2);
this.channel.signal.right += 2*((wg2)+ wg1 * 0.2);
}
}
class String extends MidiVoice {
env: Envelope = new Envelope(0.001, 1, 0.9, 0.3);
waveguide1: WaveGuide = new WaveGuide(0.01, 20.0, 610, 0.995);
waveguide2: WaveGuide = new WaveGuide(0.01, 20.0, 620, 0.995);
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq = notefreq(note);
this.waveguide1.start(freq, freq * 4000 / Mathf.pow(note, 1.3) );
this.waveguide2.start(freq, freq * 4000 / Mathf.pow(note, 1.3) );
this.env.attack();
}
noteoff(): void {
this.env.release();
this.waveguide1.envExciter.releaseStep = 0.05;
this.waveguide2.envExciter.releaseStep = 0.05;
this.waveguide1.envExciter.release();
this.waveguide2.envExciter.release();
}
isDone(): boolean {
return this.env.isDone() &&
this.waveguide1.envExciter.isDone() &&
this.waveguide2.envExciter.isDone();
}
nextframe(): void {
const env:f32 = this.env.next() * this.velocity * 0.01;
const left =
this.waveguide1.process()
* env;
const right =
this.waveguide2.process()
* env;
this.channel.signal.add(
left, right
);
}
}
class Brass extends MidiVoice {
env: Envelope = new Envelope(0.01, 1.0, 1.0, 0.1);
waveguide1: WaveGuide = new WaveGuide(0.02, 0.15, 1000, 0.99999);
waveguide2: WaveGuide = new WaveGuide(0.03, 0.2, 5000, 1.0);
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq = notefreq(note);
this.waveguide1.start(freq, freq * 10);
this.waveguide2.start(freq, freq * 8);
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone();
}
nextframe(): void {
const env = this.env.next();
let signal = (
this.waveguide1.process() +
this.waveguide2.process()
)
* env * this.velocity / 127 as f32;
this.channel.signal.add(
signal, signal
);
}
}
class Guitar extends MidiVoice {
env: Envelope = new Envelope(0.001, 1, 1.0, 0.1);
waveguide1: WaveGuide = new WaveGuide(0.005, 0.005, 1600, 0.995);
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq = notefreq(note);
this.waveguide1.start(freq, freq * 3500 / Mathf.pow(note, 1.3) );
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone();
}
nextframe(): void {
const env = this.env.next();
const signal = ((
this.waveguide1.process()
)
* env * this.velocity * 0.05) as f32;
this.channel.signal.add(
signal, signal
);
}
}
class GuitarChannel extends MidiChannel {
bandpass: BandPass = new BandPass(100,3000);
feedback: f32 = 0;
preprocess(): void {
let signal = this.signal.left;
const feedback = this.feedback;
signal = softclip(signal * 1.2);
this.feedback += this.bandpass.process(signal * 1.8);
signal += feedback;
signal *= 0.1;
echoline.left += (signal) * this.volume;
echoline.right += (signal) * this.volume;
this.signal.left = signal;
this.signal.right = signal;
}
}
class Bass extends MidiVoice {
env: Envelope = new Envelope(0.001, 1, 1.0, 0.1);
waveguide1: WaveGuide = new WaveGuide(0.001, 0.01, 200, 0.999);
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq = notefreq(note);
this.waveguide1.start(freq, freq * 8000 / Mathf.pow(note, 1.7));
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone();
}
nextframe(): void {
const env = this.env.next();
const signal = (
this.waveguide1.process()
)
* env * this.velocity * 0.25 as f32;
this.channel.signal.add(
signal, signal
);
}
}
class TubeLead extends MidiVoice {
env: Envelope = new Envelope(0.05, 1, 1.0, 0.1);
waveguide1: WaveGuideFeedbackLimit = new WaveGuideFeedbackLimit(0.001, 0.01,200, -1.12);
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq = notefreq(note);
this.waveguide1.start(freq, 230 * Mathf.pow(freq, 0.36 ));
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone();
}
nextframe(): void {
const env = this.env.next() * 0.02;
const signal = (
this.waveguide1.process()
)
* env * this.velocity as f32;
this.channel.signal.add(
signal, signal
);
}
}
class Flute extends MidiVoice {
env: Envelope = new Envelope(0.05, 1, 1.0, 0.1);
waveguide1: BandPassWaveGuide = new BandPassWaveGuide(0.001, 0.01,150, -1.1);
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq = notefreq(note);
this.waveguide1.start(freq, 80 * Mathf.pow(freq, 0.5 ));
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone();
}
nextframe(): void {
const env = this.env.next() * 0.01;
const signal = (
this.waveguide1.process()
)
* env * this.velocity as f32;
this.channel.signal.add(
signal, signal
);
}
}
class Hihat extends MidiVoice {
env: Envelope = new Envelope(0.0001, 1, 1.0, 0.2);
waveguide1: WaveGuide = new WaveGuide(0.012, 0.06, 20000, 0.9);
waveguide2: WaveGuide = new WaveGuide(0.012, 0.06, 20000, 0.9);
notch1: BiQuadFilter = new BiQuadFilter();
notch2: BiQuadFilter = new BiQuadFilter();
constructor(channel: MidiChannel) {
super(channel);
this.minnote = 66;
this.maxnote = 66;
}
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq: f32 = 7200;
this.waveguide1.start(freq, 20000);
this.waveguide2.start(freq, 20000);
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone();
}
nextframe(): void {
const env = this.env.next() * 0.04;
let left = (
this.waveguide1.process()
)
* env as f32;
let right = (
this.waveguide2.process()
)
* env as f32;
this.notch1.update_coeffecients(FilterType.Notch, SAMPLERATE,
900, (this.velocity + 1) as f32 / 127 as f32);
this.notch2.update_coeffecients(FilterType.Notch, SAMPLERATE,
900, (this.velocity + 1) as f32 / 127 as f32);
left = this.notch1.process(left);
right = this.notch2.process(right);
this.channel.signal.add(
left, right
);
}
}
class Kick2 extends MidiVoice {
env: Envelope = new Envelope(0.0001, 1, 1.0, 0.4);
waveguide1: WaveGuide = new WaveGuide(0.005, 0.1, 60, 0.5);
waveguide2: WaveGuide = new WaveGuide(0.005, 0.1, 60, 0.5);
constructor(channel: MidiChannel) {
super(channel);
this.minnote = 60;
this.maxnote = 60;
}
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq: f32 = 1000;
this.waveguide1.start(freq, 300);
this.waveguide2.start(freq, 300);
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone();
}
nextframe(): void {
const env = this.env.next() * 0.5 * this.velocity;
const left = (
this.waveguide1.process()
)
* env as f32;
const right = (
this.waveguide2.process()
)
* env as f32;
this.channel.signal.add(
left, right
);
}
}
class Snare2 extends MidiVoice {
env: Envelope = new Envelope(0.005, 0.5, 0.1, 0.3);
waveguide1: WaveGuide = new WaveGuide(0.005, 0.2, 15000, 0.999);
waveguide2: WaveGuide = new WaveGuide(0.005, 0.2, 15000, 0.999);
notch1: BiQuadFilter = new BiQuadFilter();
notch2: BiQuadFilter = new BiQuadFilter();
constructor(channel: MidiChannel) {
super(channel);
this.minnote = 62;
this.maxnote = 62;
}
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
const freq: f32 = 1400;
this.waveguide1.start(freq, 1660);
this.waveguide2.start(freq, 1660);
this.env.attack();
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
return this.env.isDone();
}
nextframe(): void {
const env = this.env.next() * 1.6 * this.velocity as f32 / 127 as f32;
let left = (
this.waveguide1.process()
)
* env as f32;
let right = (
this.waveguide2.process()
)
* env as f32;
this.notch1.update_coeffecients(FilterType.Notch, SAMPLERATE,
300, this.velocity as f32 / 127 as f32);
this.notch2.update_coeffecients(FilterType.Notch, SAMPLERATE,
300, this.velocity as f32 / 127 as f32);
//left = this.notch1.process(left);
//right = this.notch2.process(right);
this.channel.signal.add(
left, right
);
}
}
class DrumChannel extends MidiChannel {
preprocess(): void {
let left = this.signal.left;
let right = this.signal.right;
//echoline.left += (left) * this.volume;
//echoline.right += (right) * this.volume;
}
}
const fft: FFT = new FFT(11);
for (let n=1; n< (fft.buffer.length / 2) - 1; n+=1) {
let v = Mathf.exp((-n as f32 ) * 0.2) * 1023 * cos((n * 5) as f32);
//fft.buffer[n].re = v;
//fft.buffer[fft.buffer.length - n].re = -v;
fft.buffer[n].im = -v;
fft.buffer[fft.buffer.length - n].im = v;
}
fft.calculateInverse();
class PadSynth extends MidiVoice {
env: Envelope = new Envelope(0.001, 2.5, 0.00, 0.2);
t: f64 = 0;
freq: f32 = 0;
spread: i32 = 9;
hprofile: StaticArray<f32> = new StaticArray<f32>(this.spread);
phase: StaticArray<f32> = new StaticArray<f32>(this.spread);
freqs: StaticArray<f32> = new StaticArray<f32>(this.spread);
level: f32 = 1.0;
constructor(channel: MidiChannel) {
super(channel);
const halfspread: f32 = (this.spread / 2) as f32;
for(let n=0;n<this.spread;n++) {
const v: f32 = 2 as f32 * (
n as f32 - halfspread);
this.hprofile[n] = Mathf.exp(v * -v);
this.phase[n] = noise() * 0x800 as f32;
}
}
noteon(note: u8, velocity: u8): void {
super.noteon(note, velocity);
this.env.attack();
const halfspread: f32 = (this.spread / 2) as f32;
for (let n = 0;n<this.freqs.length; n++) {
const v: f32 = 0.04 as f32 * (n as f32 - halfspread);
this.freqs[n] = notefreq((note + v));
}
this.level = (-(1/(notefreq(note)-200)) + 1) as f32;
}
noteoff(): void {
this.env.release();
}
isDone(): boolean {
const ret = this.env.isDone();
return ret;
}
nextframe(): void {
const env = this.env.next() * this.level;
let left: f32 = 0;
let right: f32 = 0;
const t = this.t;
const freq = this.freq;
for(let n = 0;n < this.spread ; n++) {
const f = this.freqs[n];
const bufferpos = t * 0x800 * f + this.phase[n];
const floorbufferpos = Math.floor(bufferpos);
const delta = (bufferpos - floorbufferpos) as f32;
const v1 = fft.buffer[((bufferpos as i64) & 0x7ff) as i32].re;
const v = v1;
const leftlevel: f32 = (((n) / 2) + 0.5) as f32;
const rightlevel: f32 = (((this.hprofile.length - n) / 2) + 0.5) as f32;
left += v* leftlevel;
right += v* rightlevel;
}
left *= env;
right *= env;
this.t += 1 / SAMPLERATE;
this.channel.signal.add(
left, right
);
}
}
class PadSynthChannel extends MidiChannel {
lopassleft: BiQuadFilter = new BiQuadFilter();
lopassright: BiQuadFilter = new BiQuadFilter();
constructor(numvoices: i32, factoryFunc: (channel: MidiChannel, voiceindex: i32) => MidiVoice) {
super(numvoices, factoryFunc);
this.lopassleft.update_coeffecients(FilterType.LowPass, SAMPLERATE,
4000, 0.3);
this.lopassright.update_coeffecients(FilterType.LowPass, SAMPLERATE,
4000, 0.3);
}
preprocess(): void {
let left = this.signal.left;
let right = this.signal.right;
const gain:f32 = 0.04;
left*=gain;
right*=gain;
left = this.lopassleft.process(left);
right = this.lopassright.process(right);
//echoline.left += (left * 0.1);
//echoline.right += (right * 0.1);
this.signal.left = left;
this.signal.right = right;
}
}
export function initializeMidiSynth(): void {
midichannels[0] = new MidiChannel(10, (ch) => new Piano(ch));
midichannels[0].controlchange(7, 80);
midichannels[0].controlchange(10, 64);
midichannels[0].controlchange(91, 30);
midichannels[1] = new MidiChannel(10, (ch) => new String(ch));
midichannels[1].controlchange(7,55);
midichannels[1].controlchange(10, 64);
midichannels[1].controlchange(91, 30);
midichannels[2] = new DrumChannel(4, (ch, ndx) => {
switch(ndx) {
case 1:
return new Hihat(ch);
case 2:
return new Snare2(ch);
default:
return new Kick2(ch);
}
});
midichannels[2].controlchange(7, 100);
midichannels[2].controlchange(91, 60);
midichannels[3] = new GuitarChannel(3, (ch) => new Guitar(ch));
midichannels[3].controlchange(7, 60);
midichannels[3].controlchange(10, 55);
midichannels[3].controlchange(91, 40);
midichannels[4] = new MidiChannel(2, (ch) => new Bass(ch));
midichannels[4].controlchange(7, 80);
midichannels[4].controlchange(10, 64);
midichannels[4].controlchange(91, 20);
midichannels[5] = new MidiChannel(1, (ch) => new TubeLead(ch));
midichannels[5].controlchange(7, 30);
midichannels[5].controlchange(10, 50);
midichannels[5].controlchange(91, 40);
midichannels[6] = new MidiChannel(1, (ch) => new Flute(ch));
midichannels[6].controlchange(7, 43);
midichannels[6].controlchange(10, 70);
midichannels[6].controlchange(91, 40);
midichannels[7] = new PadSynthChannel(15, (ch) => new PadSynth(ch));
midichannels[7].controlchange(7, 48);
midichannels[7].controlchange(10, 64);
midichannels[7].controlchange(91, 40);
midichannels[8] = new MidiChannel(5, (ch) => new Brass(ch));
midichannels[8].controlchange(7, 40);
midichannels[8].controlchange(10, 32);
midichannels[8].controlchange(91, 40);
}
const eqfreqs: f32[] = [20,60,150,600,12000,19000]
const eqlevels: f32[] = [1.0, 0.9, 1.0, 1.0, 1.0];
const eqleft = new MultiBandEQ(eqfreqs);
const eqright = new MultiBandEQ(eqfreqs);
export function postprocess(): void {
const gain: f32 = 1.0;
let left = outputline.left;
let right = outputline.right;
const echol = echoLeft.read() * 0.3;
const echor = echoRight.read() * 0.3;
echoLeft.write_and_advance(echol + echoline.left);
echoRight.write_and_advance(echor + echoline.right);
left+=echol;
right+=echor;
left = eqleft.process(left, eqlevels);
right = eqright.process(right, eqlevels);
left*=gain;
right*=gain;
outputline.left = left;
outputline.right = right;
echoline.clear();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment