Created
October 28, 2021 16:23
-
-
Save petersalomonsen/7868e46c3ba499612326efbf157b5f05 to your computer and use it in GitHub Desktop.
WebAssembly Music at NEARCON 2021 https://petersalomonsen.com/webassemblymusic/livecodev2/?gist=7868e46c3ba499612326efbf157b5f05
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* (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