Skip to content

Instantly share code, notes, and snippets.

@petersalomonsen
Created January 18, 2020 06:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petersalomonsen/a74d2d036b3ecaa01af4e0f6d03ae7c4 to your computer and use it in GitHub Desktop.
Save petersalomonsen/a74d2d036b3ecaa01af4e0f6d03ae7c4 to your computer and use it in GitHub Desktop.
/**
* "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);
/**
* 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