Created
January 18, 2020 06:07
-
-
Save petersalomonsen/a74d2d036b3ecaa01af4e0f6d03ae7c4 to your computer and use it in GitHub Desktop.
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
/** | |
* "WASM song" | |
* Copyright (c) 2019-2020 - Peter Johan Salomonsen - All rights reserved | |
*/ | |
global.bpm = 123; | |
global.pattern_size_shift = 4; | |
// global.looptimes = 100; | |
//soloInstrument('bass'); | |
//soloInstrument('kick'); | |
/*soloInstrument('pad1'); | |
soloInstrument('pad2'); | |
soloInstrument('pad3'); | |
soloInstrument('padsvolume');*/ | |
// global.WASM_SYNTH_LOCATION = 'https://gist.githubusercontent.com/petersalomonsen/ea73551e352440d5f470c6af89d7fe7c/raw/b23b32ba55c1c15e972f39724ae164025f569c76/webchipmusic.wasm'; | |
addInstrument('bass', {type: 'note'}); | |
addInstrument('lead', {type: 'note'}); | |
addInstrument('sinelead', {type: 'note'}); | |
addInstrument('kick', {type: 'number'}); | |
addInstrument('snare', {type: 'number'}); | |
addInstrument('hihat', {type: 'number'}); | |
const padVoices = []; | |
for(let n=1;n<11;n++) { | |
padVoices.push('pad'+n); | |
addInstrument('pad'+n, {type: 'note'}); | |
} | |
addInstrumentGroup('pads', padVoices); | |
addInstrument('padsvolume', {type: 'number'}); | |
addInstrument('drivelead', {type: 'note'}); | |
addInstrument('driveleadpitchbend', {type: 'number'}); | |
const intro = { | |
"bass": pp(4, [d2(3/4),,,, | |
a2(1/2),,c3,d3, | |
,c3(1/2),,a2, | |
c3,,d3(1/2),, | |
].repeat(2) | |
.concat([ | |
a2(1/4),,a3,, | |
,,a2(1),, | |
c3(1/8),,c4,, | |
c3,c4,,d4 | |
]) | |
), | |
"kick": pp(4, [ | |
100,,,, | |
100,,,10, | |
100,,,, | |
100,,,, | |
].repeat(3)), | |
"hihat": pp(4, [ | |
90,20,90,20, | |
90,20,90,20, | |
90,20,90,20, | |
90,20,90,20 | |
].repeat(3)), | |
"snare": pp(4, [ | |
,,,, | |
60,,,, | |
,,,, | |
60 | |
,,,, | |
].repeat(3)), | |
"padsvolume": pp(1,[100]), | |
"pads": pp(4, [ | |
[d5(1),fs5(1),a4(1)],,,, | |
,,,, | |
,,,, | |
[d5(1),fs5(1),a4(1)],,,, | |
[e5(1),g5(1),c5(1)] | |
,,,, | |
,,,, | |
,,,, | |
[e5(1),g5(1),b5(1)],,,, | |
[d5(1),fs5(1),a5(1)],,,, | |
,,,, | |
,,,, | |
,,,, | |
[e5(1/4),g5(1/4),c6(1/4)],,,[e5,g5,c6], | |
,,,, | |
[d5(1/4),g5(1/4),b5(1/4)],,,[d5,g5,b5], | |
,,,, | |
], 3) | |
}; | |
playPatterns(intro, 4); | |
playPatterns(Object.assign({},intro, { | |
"snare": pp(4, [ | |
,,,, | |
60,,,, | |
,,,, | |
60 | |
,,,, | |
].repeat(2).concat([ | |
,,,, | |
60,,,, | |
,,,30, | |
60,,,40 | |
])) | |
}), 4); | |
const lead = [,,a4(1/2),, | |
d5(1/2),,a4(1/2),, | |
d5(3/4),,,e5(3/4), | |
,,c5(1),, | |
,,b4(1/2),, | |
c5(1/2),,b4(1/2),, | |
c5(3/4),,,b4(3/4), | |
,,a4(1/4),, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,g5(1/2),, | |
g5(1/2),,g5(1/2),, | |
g5(1/2),,,a5(3/4), | |
,,fs5 | |
]; | |
// playFromHere(); | |
playPatterns(Object.assign({}, intro, {lead: pp(4, lead)}, 4), 4); | |
playPatterns(Object.assign({}, intro, { | |
"snare": pp(4, [ | |
,,,, | |
60,,,, | |
,,,, | |
60 | |
,,,, | |
].repeat(2).concat([ | |
,,,, | |
60,,,, | |
,,,30, | |
60,,,40 | |
])), | |
lead: pp(4, | |
lead.slice(0,48) | |
.concat([d5,e5,g5,, | |
b5,,,d6, | |
,g5 | |
]) | |
)}, 4), 4); | |
// playFromHere(); | |
const sineleadpartbass = pattern(4, [ | |
g2(1/8),,g3,, | |
,,,, | |
d2,d3,,f3, | |
,f3,g3,, | |
]); | |
const sineleadnotes = [ | |
,,g5,, | |
g5,,g5,b5, | |
,c6,,b5, | |
,g5,f5,, | |
,,,, | |
,,,, | |
,,,, | |
,,,f5, | |
,f5,d5,, | |
f5,,g5,, | |
a5,,,g5, | |
,,e5 | |
]; | |
const sineleadpart = { | |
kick: intro.kick, | |
snare: intro.snare, | |
hihat: intro.hihat, | |
bass: pp(4, sineleadpartbass | |
.concat(sineleadpartbass.transposeNotes(-5)) | |
.concat(sineleadpartbass.transposeNotes(-2)) | |
.concat(sineleadpartbass.transposeNotes(-7)) | |
), | |
sinelead: pp(4, sineleadnotes), | |
"pads": pp(1, [ | |
[d5(4),g5(4),b5(4)],,,, | |
[f5(4),a5(4),c6(4),d5(4)],,,, | |
[f5(4),a5(4),c6(4)],,,, | |
[e5(4),g5(4),c6(4)],,,, | |
],4), | |
"padsvolume": pp(1,[75]) | |
}; | |
playPatterns(sineleadpart,4); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes.slice(0,32).concat([ | |
,f5,d5,, | |
f5,,g5,, | |
a5,,,g5, | |
,,,c6, | |
,c6,b5,, | |
c6,,d6,, | |
b5,,,g5 | |
])) | |
}),4); | |
// playFromHere(); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes), | |
"lead": pp(4, [d5,d6,,d5, | |
d6,,d5,, | |
a5(1),,,g5, | |
,,,, | |
].repeat(3)), | |
"drivelead": pp(4, [ | |
,,,, | |
,,,, | |
,,d5,, | |
g5,,d6,c6(2), | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,d5,, | |
g5,,d6,c6(2), | |
,,,, | |
b5(1),,,, | |
g5(1/2) | |
]) | |
}),4); | |
// playFromHere(); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes), | |
"lead": pp(4, [d5,d6,,d5, | |
d6,,d5,, | |
a5(1),,,g5, | |
,,,, | |
].repeat(3)), | |
"drivelead": pp(4, [ | |
,,,, | |
,,,, | |
,,d5,, | |
g5,,d6,c6(2), | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,d5,, | |
g5,,d6,c6(2), | |
,,,, | |
b5(1),,,, | |
g5(1/2),,,, | |
a5(1/2),,,, | |
]) | |
}),4); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes), | |
"lead": pp(4, [d5,d6,,d5, | |
d6,,d5,, | |
a5(1),,,g5, | |
,,,, | |
].repeat(3)), | |
"drivelead": pp(4, [ | |
b5(4),,,, | |
,,,, | |
,,,, | |
,,,, | |
c6(4),,,, | |
,,,, | |
,,,, | |
b5(1),,a5(1),, | |
g5(4),,,, | |
,,,, | |
,,,, | |
,,e5(5) | |
]), | |
"driveleadpitchbend": pp(4, [ | |
2,16,32,48, | |
64,,,, | |
,,,, | |
,,,, | |
32,40,48,64, | |
,,,, | |
,,,, | |
,,,, | |
32,40,48,64, | |
]), | |
}),4); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes), | |
"lead": pp(4, [d5,d6,,d5, | |
d6,,d5,, | |
a5(1),,,g5, | |
,,,, | |
].repeat(3)), | |
"drivelead": pp(4, [ | |
d6(4),,,, | |
,,,, | |
,,,, | |
,,,f6(4), | |
,,,, | |
,,,, | |
,,,, | |
e6(1),,d6(1),, | |
c6(4),,,, | |
,,,, | |
,,,, | |
,,g6(5),, | |
,,,, | |
]), | |
"driveleadpitchbend": pp(4, [ | |
2,16,32,48, | |
64,,,, | |
,,,, | |
,80,96,32, | |
36,40,48,64, | |
,,,, | |
,,,, | |
,,,, | |
32,40,48,64, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
80,96,112,127 | |
]), | |
"snare": pp(4, [ | |
,,,, | |
60,,,, | |
,,,, | |
60 | |
,,,, | |
].repeat(2).concat([ | |
,20,,30, | |
60,,,20, | |
,20,,30, | |
60,20,60,40 | |
]) | |
) | |
}),4); | |
// ---------- back to intro ---------------- | |
playPatterns(Object.assign({}, intro, { | |
drivelead: pp(4,[ | |
a6(1) | |
]), | |
"driveleadpitchbend": pp(4,[ | |
64,,48,32,16, | |
,,,, | |
64 | |
]) | |
}), 4); | |
playPatterns(Object.assign({}, intro, { | |
"sinelead": pp(4,[ | |
a4,,a4,, | |
d5,,d5,, | |
a5,,a5,, | |
c6,d6,,, | |
,,,, | |
,,,, | |
,,,, | |
g6,fs6,d6,a5 | |
]), | |
"lead": pp(4, [ | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
d5,a5 | |
]) | |
}), 4); | |
playPatterns(Object.assign({}, intro, {lead: pp(4, lead)}, 4), 4); | |
playPatterns(Object.assign({}, intro, { | |
"snare": pp(4, [ | |
,,,, | |
60,,,, | |
,,,, | |
60 | |
,,,, | |
].repeat(2).concat([ | |
,,,, | |
60,,,, | |
,,,30, | |
60,,,40 | |
])), | |
lead: pp(4, | |
lead.slice(0,48) | |
.concat([d5,e5,g5,, | |
b5,,,d6, | |
,g5 | |
]) | |
)}, 4), 4); | |
playPatterns(sineleadpart,4); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes.slice(0,32).concat([ | |
,f5,d5,, | |
f5,,g5,, | |
a5,,,g5, | |
,,,c6, | |
,c6,b5,, | |
c6,,d6,, | |
b5,,,g5 | |
])) | |
}),4); | |
// playFromHere(); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes), | |
"lead": pp(4, [d5,d6,,d5, | |
d6,,d5,, | |
a5(1),,,g5, | |
,,,, | |
].repeat(3)), | |
"drivelead": pp(4, [ | |
,,,, | |
,,,, | |
,,d5,, | |
g5,,d6,c6(2), | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,d5,, | |
g5,,d6,c6(2), | |
,,,, | |
b5(1),,,, | |
g5(1/2) | |
]) | |
}),4); | |
// playFromHere(); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes), | |
"lead": pp(4, [d5,d6,,d5, | |
d6,,d5,, | |
a5(1),,,g5, | |
,,,, | |
].repeat(3)), | |
"drivelead": pp(4, [ | |
,,,, | |
,,,, | |
,,d5,, | |
g5,,d6,c6(2), | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,d5,, | |
g5,,d6,c6(2), | |
,,,, | |
b5(1),,,, | |
g5(1/2),,,, | |
a5(1/2),,,, | |
]) | |
}),4); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes), | |
"lead": pp(4, [d5,d6,,d5, | |
d6,,d5,, | |
a5(1),,,g5, | |
,,,, | |
].repeat(3)), | |
"drivelead": pp(4, [ | |
b5(4),,,, | |
,,,, | |
,,,, | |
,,,, | |
c6(4),,,, | |
,,,, | |
,,,, | |
b5(1),,a5(1),, | |
g5(4),,,, | |
,,,, | |
,,,, | |
,,e5(5) | |
]), | |
"driveleadpitchbend": pp(4, [ | |
2,16,32,48, | |
64,,,, | |
,,,, | |
,,,, | |
32,40,48,64, | |
,,,, | |
,,,, | |
,,,, | |
32,40,48,64, | |
]), | |
}),4); | |
playPatterns(Object.assign({}, sineleadpart,{ | |
"sinelead": pp(4, sineleadnotes), | |
"lead": pp(4, [d5,d6,,d5, | |
d6,,d5,, | |
a5(1),,,g5, | |
,,,, | |
].repeat(3)), | |
"drivelead": pp(4, [ | |
d6(4),,,, | |
,,,, | |
,,,, | |
,,,f6(4), | |
,,,, | |
,,,, | |
,,,, | |
e6(1),,d6(1),, | |
c6(4),,,, | |
,,,, | |
,,,, | |
,,g6(5),, | |
,,,, | |
]), | |
"driveleadpitchbend": pp(4, [ | |
2,16,32,48, | |
64,,,, | |
,,,, | |
,80,96,32, | |
36,40,48,64, | |
,,,, | |
,,,, | |
,,,, | |
32,40,48,64, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
80,96,112,127 | |
]), | |
"snare": pp(4, [ | |
,,,, | |
60,,,, | |
,,,, | |
60 | |
,,,, | |
].repeat(2).concat([ | |
,20,,30, | |
60,,,20, | |
,20,,30, | |
60,20,60,40 | |
]) | |
) | |
}),4); | |
playPatterns(intro, 4); | |
const newsnarebeat = pp(4,[ | |
,,,, | |
60,,,10, | |
,10,,, | |
60,,,25, | |
].repeat(2).concat([ | |
,20,,, | |
60,10,,10, | |
,10,35,, | |
60,10,,35, | |
])); | |
playPatterns(Object.assign({}, intro, { | |
snare: newsnarebeat | |
}), 4); | |
playPatterns(Object.assign({}, intro, { | |
snare: newsnarebeat, | |
sinelead: pp(4,[ | |
,,a5,,a5 | |
,,d6,,d6 | |
,,a6,,a6 | |
,,b6,,b6 | |
,,a6,,a6 | |
,,d6,,e6 | |
,,d6,,d6 | |
]), | |
drivelead: pp(4,[ | |
,,d5(1),, | |
,,a5(1/2),, | |
b5(1),,,, | |
a5(1),,,, | |
e5(1),,,a5(1), | |
,,d5(2) | |
]), | |
driveleadpitchbend: pp(4, [ | |
64,,,, | |
,,,, | |
2,32,64 | |
]) | |
}), 4); | |
playPatterns(Object.assign({}, intro, { | |
snare: newsnarebeat, | |
sinelead: pp(4,[ | |
,,a5,,a5 | |
,,d6,,d6 | |
,,a6,,a6 | |
,,b6,,b6 | |
,,a6,,a6 | |
,,d6,,e6 | |
,,d6,,d6 | |
]), | |
drivelead: pp(4,[ | |
,,d5(1),, | |
,,a5(1/2),, | |
b5(1),,,, | |
a5(1),,,, | |
e5(1),,,a5(1), | |
,,d5(2),, | |
,,e5(1),, | |
fs5(2),,,, | |
,,,, | |
,,,, | |
,,,, | |
,,g5(2),, | |
,,fs5(1),, | |
,,e5(1),, | |
d5(1),,,, | |
b4(1) | |
]), | |
driveleadpitchbend: pp(4, [ | |
64,,,, | |
,,,, | |
2,32,64, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,32,48, | |
64 | |
]) | |
}), 4); | |
playPatterns(Object.assign({}, intro, { | |
snare: newsnarebeat, | |
sinelead: pp(4,[ | |
,,a5,,a5 | |
,,d6,,d6 | |
,,a6,,a6 | |
,,b6,,b6 | |
,,a6,,a6 | |
,,d6,,e6 | |
,,d6,,d6 | |
,,,, | |
,,a5,,a5 | |
,,d6,d7,d6 | |
,,a6,,a6 | |
,,b6,g7,b6 | |
,,a6,,a6 | |
,,d6,d7,e6 | |
,,d6,d7, | |
g7,fs7,d7,a6 | |
]), | |
drivelead: pp(4,[ | |
,,d5(1),, | |
,,a5(1/2),, | |
b5(1),,,, | |
a5(1),,,, | |
e5(1),,,a5(1), | |
,,d5(2) | |
]), | |
driveleadpitchbend: pp(4, [ | |
64,,,, | |
,,,, | |
2,32,64 | |
]) | |
}), 4); | |
playPatterns(Object.assign({}, intro, { | |
snare: newsnarebeat, | |
sinelead: pp(4,[ | |
,,a5,,a5 | |
,,d6,,d6 | |
,,a6,,a6 | |
,,b6,,b6 | |
,,a6,,a6 | |
,,d6,,e6 | |
,,d6,,d6 | |
,,d7,, | |
,,a5,,a5 | |
,,d6,d7,d6 | |
,,a6,,a6 | |
,,b6,g7,b6 | |
,,a6,,a6 | |
,,d6,d7,e6 | |
,,d6,d7, | |
g7,fs7,d7,a6 | |
]), | |
drivelead: pp(4,[ | |
,,d5(1),, | |
,,a5(1/2),, | |
b5(1),,,, | |
a5(1),,,, | |
e5(1),,,a5(1), | |
,,d5(2),, | |
,,e5(1),, | |
fs5(2),,,, | |
,,,, | |
,,,, | |
,,,, | |
,,g5(2),, | |
,,fs5(1),, | |
,,e5(1),, | |
d5(1),,,, | |
b4(1) | |
]), | |
driveleadpitchbend: pp(4, [ | |
64,,,, | |
,,,, | |
2,32,64, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,32,48, | |
64 | |
]) | |
}), 4); | |
/// ---------- transpose it | |
const transposedBass = pattern(4, [d2(3/4),,,, | |
a2(1/2),,c3,d3, | |
,c3(1/2),,a2, | |
c3,,d3(1/2),, | |
].repeat(2) | |
.concat([ | |
a2(1/4),,a3,, | |
,,a2(1),, | |
c3(1/8),,c4,, | |
c3,c4,,d4 | |
])).transposeNotes(5); | |
const transposedPads = pattern(4,[ | |
[d5(1),fs5(1),a4(1)],,,, | |
,,,, | |
,,,, | |
[d5(1),fs5(1),a4(1)],,,, | |
[e5(1),g5(1),c5(1)] | |
,,,, | |
,,,, | |
,,,, | |
[e5(1),g5(1),b5(1)],,,, | |
[d5(1),fs5(1),a5(1)],,,, | |
,,,, | |
,,,, | |
,,,, | |
[e5(1/4),g5(1/4),c6(1/4)],,,[e5,g5,c6], | |
,,,, | |
[d5(1/4),g5(1/4),b5(1/4)],,,[d5,g5,b5], | |
,,,, | |
], 3).map(pattern => pattern.transposeNotes(5)); | |
const transposedPatternNames = addPatterns(transposedPads); | |
playPatterns(Object.assign({}, intro, { | |
bass: pp(4, transposedBass), | |
snare: newsnarebeat, | |
pads: transposedPatternNames, | |
sinelead: pp(4,pattern(4, [ | |
,,a5,,a5 | |
,,d6,,d6 | |
,,a6,,a6 | |
,,b6,,b6 | |
,,a6,,a6 | |
,,d6,,e6 | |
,,d6,,d6 | |
,,,, | |
,,a5,,a5 | |
,,d6,d7,d6 | |
,,a6,,a6 | |
,,b6,g7,b6 | |
,,a6,,a6 | |
,,d6,d7,e6 | |
,,d6,d7, | |
g7,fs7,d7,a6 | |
]).transposeNotes(5)), | |
drivelead: pp(4,pattern(4,[ | |
,,d5(1),, | |
,,a5(1/2),, | |
b5(1),,,, | |
a5(1),,,, | |
e5(1),,,a5(1), | |
,,d5(2) | |
]).transposeNotes(5)), | |
driveleadpitchbend: pp(4, [ | |
64,,,, | |
,,,, | |
2,32,64 | |
]) | |
}), 4); | |
playPatterns(Object.assign({}, intro, { | |
snare: newsnarebeat, | |
bass: pp(4, transposedBass), | |
pads: transposedPatternNames, | |
sinelead: pp(4,pattern(4,[ | |
,,a5,,a5 | |
,,d6,,d6 | |
,,a6,,a6 | |
,,b6,,b6 | |
,,a6,,a6 | |
,,d6,,e6 | |
,,d6,,d6 | |
,,d7,, | |
,,a5,,a5 | |
,,d6,d7,d6 | |
,,a6,,a6 | |
,,b6,g7,b6 | |
,,a6,,a6 | |
,,d6,d7,e6 | |
,,d6,d7, | |
g7,fs7,d7,a6 | |
]).transposeNotes(5)), | |
drivelead: pp(4,pattern(4,[ | |
,,d5(1),, | |
,,a5(1/2),, | |
b5(1),,,, | |
a5(1),,,, | |
e5(1),,,a5(1), | |
,,d5(2),, | |
,,e5(1),, | |
fs5(2),,,, | |
,,,, | |
,,,, | |
,,,, | |
,,g5(2),, | |
,,fs5(1),, | |
,,e5(1),, | |
d5(1),,,, | |
b4(1) | |
]).transposeNotes(5)), | |
driveleadpitchbend: pp(4, [ | |
64,,,, | |
,,,, | |
2,32,64, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,32,48, | |
64 | |
]) | |
}), 4); | |
playPatterns( { | |
"bass": pp(4, [d2(3/4),,,, | |
a2(1/2),,c3,d3, | |
,c3(1/2),,a2, | |
c3,,d3(1/2),, | |
].repeat(2) | |
.concat([ | |
d2(2) | |
]) | |
), | |
"kick": pp(4, [ | |
100,,,, | |
100,,,30, | |
100,,,, | |
100,,,, | |
].repeat(2).concat([100])), | |
"hihat": pp(4, [ | |
90,20,90,20, | |
90,20,90,20, | |
90,20,90,20, | |
90,20,90,20 | |
].repeat(2).concat([90])), | |
"padsvolume": pp(1,[100]), | |
"pads": pp(4, [ | |
[d5(1),fs5(1),a4(1)],,,, | |
,,,, | |
,,,, | |
[d5(1),fs5(1),a4(1)],,,, | |
[e5(1),g5(1),c5(1)] | |
,,,, | |
,,,, | |
,,,, | |
[e5(1),g5(1),c5(1)],,,, | |
[d5(1),fs5(1),a4(1)],,,, | |
,,,, | |
], 3), | |
drivelead: pp(4,[ | |
fs5(3),,,, | |
,,,, | |
,,,, | |
,,,, | |
g5(4),,,, | |
,,,, | |
,,,, | |
,,,, | |
a5(3) | |
]), | |
lead: pp(4,[ | |
fs5(3),,,, | |
,,,, | |
,,,, | |
,,,, | |
g5(4),,,, | |
,,,, | |
,,,, | |
,,,, | |
a5(3) | |
]), | |
sinelead: pp(4, [ | |
,a5,d6,a6, | |
,d6,a6,d7, | |
,,,, | |
,,,, | |
g7,fs7,d7,a6, | |
,,,, | |
,,,, | |
,,,, | |
a7,d7,a6,fs6, | |
d6,a5,d6,fs6, | |
,,,, | |
,d6,a6,d6, | |
a6,fs6 | |
]), | |
driveleadpitchbend: pp(4, [ | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
,,,, | |
2,16,32,48,64 | |
]) | |
}, 7); |
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
/** | |
* Mix for "WASM song" | |
*/ | |
import { EQBand } from "../fx/eqband"; | |
import { Envelope } from '../synth/envelope.class'; | |
import { Snare } from "../instruments/snare.class"; | |
import { SawBass3 } from "../instruments/bass/sawbass3"; | |
import { Eftang } from "../instruments/lead/eftang"; | |
import { StereoSignal } from "../synth/stereosignal.class"; | |
import { Kick } from "../instruments/kick.class"; | |
import { BrassyLead } from "../instruments/lead/brassy"; | |
import { Hihat } from "../instruments/hihat.class"; | |
import { WaveShaper } from '../synth/shaper'; | |
import { createInstrumentArray } from '../common/mixcommon'; | |
import { Freeverb } from "../fx/freeverb"; | |
import { DelayLine } from "../fx/delayline"; | |
import { SAMPLERATE } from "../environment"; | |
import { BiQuadFilter, FilterType, Q_BUTTERWORTH } from '../synth/biquad'; | |
import { notefreq } from '../synth/note'; | |
import { SineOscillator } from '../synth/sineoscillator.class'; | |
import { SawOscillator } from '../synth/sawoscillator.class'; | |
import { TriBandStereoCompressor } from "../fx/tribandstereocompressor"; | |
export const PATTERN_SIZE_SHIFT: usize = 4; | |
export const BEATS_PER_PATTERN_SHIFT: usize = 2; | |
const tribandstereocompressor = new TriBandStereoCompressor(20,500,7000,19500); | |
const ENABLE_MULTIBAND_COMPRESSOR = false; | |
const gain: f32 = 0.5; | |
const bass = new SawBass3(); | |
const lead = new Eftang(); | |
const kick = new Kick(); | |
const snare = new Snare(); | |
const hihat = new Hihat(); | |
export class FlatPad { | |
private _note: f32; | |
readonly envelope: Envelope = new Envelope(0.01, 0.1, 1.0, 0.1); | |
readonly filterenvelope: Envelope = new Envelope(0.001, 1.0, 1.0, 0.1); | |
readonly hipassfilterenvelope: Envelope = new Envelope(0.02, 3, 0.2, 2.0); | |
readonly sawoscillator: SawOscillator = new SawOscillator(); | |
readonly sawoscillator2: SawOscillator = new SawOscillator(); | |
readonly sawoscillator3: SawOscillator = new SawOscillator(); | |
readonly sawoscillator4: SawOscillator = new SawOscillator(); | |
readonly sawoscillator5: SawOscillator = new SawOscillator(); | |
readonly lfo: SineOscillator = new SineOscillator(); | |
readonly filterl: BiQuadFilter = new BiQuadFilter(); | |
readonly filterr: BiQuadFilter = new BiQuadFilter(); | |
readonly signal: StereoSignal = new StereoSignal(); | |
set note(note: f32) { | |
if(note > 1) { | |
this.lfo.frequency = 1; | |
this.lfo.position = 0; | |
this.sawoscillator.frequency = notefreq(note); | |
this.sawoscillator2.frequency = notefreq(note + 0.03); | |
this.sawoscillator3.frequency = notefreq(note - 0.03); | |
this.sawoscillator4.frequency = notefreq(note + 0.06); | |
this.sawoscillator5.frequency = notefreq(note - 0.06); | |
this.envelope.attack(); | |
this.filterenvelope.attack(); | |
this.hipassfilterenvelope.attack(); | |
this._note = note; | |
} else { | |
this.envelope.release(); | |
this.filterenvelope.release(); | |
this.hipassfilterenvelope.release(); | |
} | |
} | |
get note(): f32 { | |
return this._note; | |
} | |
next(): void { | |
let env: f32 = this.envelope.next(); | |
if(env === 0) { | |
this.signal.clear(); | |
return; | |
} | |
const lfo: f32 = this.lfo.next(); | |
const note = this.note; | |
if(note<2) { | |
return; | |
} | |
this.sawoscillator2.frequency = notefreq(note + 0.05 + (0.02 * lfo)); | |
this.sawoscillator3.frequency = notefreq(note - 0.05 - (0.02 * lfo)); | |
this.sawoscillator4.frequency = notefreq(note + 0.1 + (0.03 * lfo)); | |
this.sawoscillator5.frequency = notefreq(note - 0.1 - (0.03 * lfo)); | |
let osc: f32 = this.sawoscillator.next(); | |
let osc2: f32 = this.sawoscillator2.next(); | |
let osc3: f32 = this.sawoscillator3.next(); | |
let osc4: f32 = this.sawoscillator4.next(); | |
let osc5: f32 = this.sawoscillator5.next(); | |
let left = env * (osc + osc2 + osc5); | |
let right = env * (osc + osc3 + osc4 ); | |
const filterlfo: f32 = (lfo * 0.9) + 1; | |
this.filterl.update_coeffecients(FilterType.LowPass, SAMPLERATE, | |
200 + this.filterenvelope.next() * filterlfo * 10000 + 20 * (127 - this.note), Q_BUTTERWORTH); | |
this.filterr.update_coeffecients(FilterType.LowPass, SAMPLERATE, | |
200 + this.filterenvelope.next() * filterlfo * 10000 + 20 * (this.note), Q_BUTTERWORTH); | |
this.signal.left = this.filterl.process(left ); | |
this.signal.right = this.filterr.process(right ); | |
} | |
} | |
const pads: FlatPad[] = createInstrumentArray<FlatPad>(10, () => new FlatPad()); | |
let padsVolume: f32 = 1.0; | |
class SineLead { | |
private _note: f32; | |
readonly osc: SineOscillator = new SineOscillator(); | |
readonly env1: Envelope = new Envelope(0.02, 0.15, 0.5, 0.3); | |
readonly signal: StereoSignal = new StereoSignal(); | |
set note(note: f32) { | |
if(note > 1) { | |
this.osc.frequency = notefreq(note); | |
this._note = note; | |
this.env1.attack(); | |
} else { | |
this.env1.release(); | |
} | |
} | |
get note(): f32 { | |
return this._note; | |
} | |
next(): void { | |
const env1: f32 = this.env1.next(); | |
let osc: f32 = this.osc.next(); | |
osc *= env1; | |
const pan = this._note / 127; | |
this.signal.left = osc * pan; | |
this.signal.right = osc * (1 - pan); | |
} | |
} | |
export class DriveLead { | |
private _note: f32; | |
readonly envelope: Envelope = new Envelope(0.03, 1.0, 0.6, 0.2); | |
readonly sawoscillatorl: SawOscillator = new SawOscillator(); | |
readonly sawoscillatorr: SawOscillator = new SawOscillator(); | |
readonly shaper: WaveShaper = new WaveShaper(); | |
readonly signal: StereoSignal = new StereoSignal(); | |
readonly lfoenvelope: Envelope = new Envelope(1.0, 0, 1.0, 0.1); | |
readonly lfo: SineOscillator = new SineOscillator(); | |
private baseFrequency : f32; | |
private pitchbend: f32 = 0; | |
set note(note: f32) { | |
if(note > 1) { | |
this.shaper.drive = 0.5; | |
this.baseFrequency = notefreq(note + this.pitchbend); | |
this.lfo.frequency = 8; | |
this.envelope.attack(); | |
this.lfoenvelope.attack(); | |
this._note = note; | |
} else { | |
this.envelope.release(); | |
this.lfoenvelope.release(); | |
} | |
} | |
get note(): f32 { | |
return this._note; | |
} | |
setPitchbend(bend: f32): void { | |
this.pitchbend = bend; | |
this.baseFrequency = notefreq(this._note + bend); | |
} | |
next(): void { | |
let env: f32 = this.envelope.next(); | |
if(env===0) { | |
this.signal.clear(); | |
return; | |
} | |
let lfo: f32 = this.lfo.next() * 3 * this.lfoenvelope.next(); | |
this.sawoscillatorl.frequency = this.baseFrequency + lfo + 0.5; | |
this.sawoscillatorr.frequency = this.baseFrequency + lfo - 0.5; | |
let left = env* this.sawoscillatorl.next() + this.signal.right * 0.5; | |
left = this.shaper.process(left); | |
let right = env* this.sawoscillatorr.next() + this.signal.left * 0.5; | |
right = this.shaper.process(right); | |
this.signal.left = left * 0.5 + right; | |
this.signal.right = right * 0.5 + left; | |
} | |
} | |
const sinelead = new SineLead(); | |
const drivelead = new DriveLead(); | |
export function setChannelValue(channel: usize, value: f32): void { | |
const setChannelValueFunctions: usize[] = [ | |
changetype<usize>((value:f32): void => {bass.note = value;}), | |
changetype<usize>((value:f32): void => {lead.note = value;}), | |
changetype<usize>((value:f32): void => {sinelead.note = value;}), | |
changetype<usize>((value:f32): void => {kick.note = value;}), | |
changetype<usize>((value:f32): void => {snare.note = value;}), | |
changetype<usize>((value:f32): void => {hihat.note = value;}), | |
changetype<usize>((value:f32): void => {pads[0].note = value;}), | |
changetype<usize>((value:f32): void => {pads[1].note = value;}), | |
changetype<usize>((value:f32): void => {pads[2].note = value;}), | |
changetype<usize>((value:f32): void => {pads[3].note = value;}), | |
changetype<usize>((value:f32): void => {pads[4].note = value;}), | |
changetype<usize>((value:f32): void => {pads[5].note = value;}), | |
changetype<usize>((value:f32): void => {pads[6].note = value;}), | |
changetype<usize>((value:f32): void => {pads[7].note = value;}), | |
changetype<usize>((value:f32): void => {pads[8].note = value;}), | |
changetype<usize>((value:f32): void => {pads[9].note = value;}), | |
changetype<usize>((value:f32): void => { | |
if(value > 0) { | |
padsVolume = value / 100.0; | |
} | |
}), | |
changetype<usize>((value:f32): void => {drivelead.note = value;}), | |
changetype<usize>((value:f32): void => { | |
if(value > 0) { | |
drivelead.setPitchbend((value - 64) / 32); | |
} | |
}) | |
]; | |
changetype<(val: f32) => void>(setChannelValueFunctions[channel])(value); | |
} | |
const mainline = new StereoSignal(); | |
const reverbline = new StereoSignal(); | |
const freeverb = new Freeverb(); | |
const delayframes = (SAMPLERATE * (6/8) * 60 / 120) as usize; | |
let delayLeft: DelayLine = new DelayLine(delayframes); | |
let delayRight: DelayLine = new DelayLine(delayframes); | |
let echoline = new StereoSignal(); | |
let eqbandl = new EQBand(20, 19500); | |
let eqbandr = new EQBand(20, 19500); | |
export function mixernext(leftSampleBufferPtr: usize, rightSampleBufferPtr: usize): void { | |
let left: f32 = 0; | |
let right: f32 = 0; | |
mainline.clear(); | |
reverbline.clear(); | |
echoline.clear(); | |
bass.next(); | |
mainline.addStereoSignal(bass.signal, 1.0, 0.5); | |
reverbline.addStereoSignal(bass.signal, 0.0, 0.5); | |
lead.next(); | |
mainline.addStereoSignal(lead.signal, 0.8, 0.5); | |
echoline.addStereoSignal(lead.signal, 0.8, 0.5); | |
drivelead.next(); | |
mainline.addStereoSignal(drivelead.signal, 0.1, 0.5); | |
echoline.addStereoSignal(drivelead.signal, 0.4, 0.5); | |
sinelead.next(); | |
mainline.addStereoSignal(sinelead.signal, 1.0, 0.5); | |
echoline.addStereoSignal(sinelead.signal, 1.2, 0.5); | |
kick.next(); | |
mainline.addStereoSignal(kick.signal, 0.8, 0.5); | |
snare.next(); | |
mainline.addStereoSignal(snare.signal, 0.8, 0.5); | |
hihat.next(); | |
mainline.addStereoSignal(hihat.signal, 0.8, 0.5); | |
pads.forEach(pad => { | |
pad.next(); | |
mainline.addStereoSignal(pad.signal, 0.45 * padsVolume, 0.5); | |
}); | |
echoline.left += delayRight.read() * 0.7; | |
echoline.right += delayLeft.read() * 0.7; | |
delayLeft.write_and_advance(echoline.left); | |
delayRight.write_and_advance(echoline.right); | |
freeverb.tick(reverbline); | |
left = gain * (mainline.left + reverbline.left + echoline.left); | |
right = gain * (mainline.right + reverbline.right + echoline.right); | |
if (ENABLE_MULTIBAND_COMPRESSOR) { | |
tribandstereocompressor.process(left,right,0.45, 0.6, 0.9 , 1.20, 1.05, 1.0); | |
left = tribandstereocompressor.stereosignal.left; | |
right = tribandstereocompressor.stereosignal.right; | |
} else { | |
left = eqbandl.process(left); | |
right = eqbandr.process(right); | |
} | |
store<f32>(leftSampleBufferPtr, left); | |
store<f32>(rightSampleBufferPtr, right); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment