// open MIDI channel to Q25
MidiIn min;
MidiMsg msg;
min.open(1);
//-------------------------------------------------------------
// define class X
class X {static int mononote;}
// initialize mononote
0 => X.mononote;
//-------------------------------------------------------------
// set parameters
// Moog filter
0.67 => float Q;
1.0 => float SweepRate;
20.0 => float Speed;
0.0 => float Depth;
0.4 => float VibFreq;
0.01 => float VibGain;
1.0 => float Volume;
//envelope
// attack
1::ms => dur A;
// decay
1::ms => dur D;
// sustain
0.9 => float S;
// release
30::ms => dur R;
// reverb mix
0.2 => float revmixmo;
0.3 => float revmixs;
// detune factor d
0.01 => float dmo;
0.013 => float ds;
// general gain
0.7 => float gainmo;
0.25 => float gains;
//-------------------------------------------------------------
// patches
Moog mo1 => ADSR e1 => NRev reverb1 => dac;
Moog mo2 => ADSR e2 => NRev reverb2 => dac;
SawOsc s1 => ADSR e3 => NRev reverb3 => dac;
SqrOsc s2 => ADSR e4 => NRev reverb4 => dac;
//-------------------------------------------------------------
// initialize mo1
Q => mo1.filterQ;
SweepRate => mo1.filterSweepRate;
Speed => mo1.lfoSpeed;
Depth => mo1.lfoDepth;
VibFreq => mo1.vibratoFreq;
VibGain => mo1.vibratoGain;
Volume => mo1.volume;
// initialize mo2
Q => mo2.filterQ;
SweepRate => mo2.filterSweepRate;
Speed => mo2.lfoSpeed;
Depth => mo2.lfoDepth;
VibFreq => mo2.vibratoFreq;
VibGain => mo2.vibratoGain;
Volume => mo2.volume;
// initialize envelopes e1, e2, e3, e4
e1.set( 0::second, 0::second, 1, R );
e2.set( 0::second, 0::second, 1, R );
e3.set( A, D, S, R );
e4.set( A, D, S, R );
// initialize reverb mix's
revmixmo => reverb1.mix;
revmixmo => reverb2.mix;
revmixs => reverb3.mix;
revmixs => reverb4.mix;
//-------------------------------------------------------------
// infinite time-loop
while( true )
{
//receive MIDI messages
min => now;
// if-loop received messages
if( min.recv(msg) )
{
// monophonic note
if (msg.data1 == 144 && X.mononote == 0) {msg.data2 => X.mononote;}
if (msg.data1 == 128 && msg.data2 == X.mononote) {0 => X.mononote;}
if (msg.data1==144 && msg.data2 == X.mononote)
{
// set frequencies mo1, mo2; and s1,s2
Std.mtof(msg.data2) => mo1.freq;
Std.mtof(msg.data2) * (1 + dmo) => mo2.freq;
Std.mtof(msg.data2) => s1.freq;
Std.mtof(msg.data2) * (1 + ds) => s2.freq;
// set velocities mo1, mo2; and s1, s2
gainmo*(msg.data3/127.0) => mo1.noteOn;
gainmo*(msg.data3/127.0) => mo2.noteOn;
gains*(msg.data3/127.0) => s1.gain;
gains*(msg.data3/127.0) => s2.gain;
// keyOn e1, e2, e3, e4
e1.keyOn();
e2.keyOn();
e3.keyOn();
e4.keyOn();
}
if (msg.data1==128 && X.mononote == 0)
{
// noteOff mo1 and mo2; keyOff e1, e2, e3, e4
1 => mo1.noteOff;
1 => mo2.noteOff;
e1.keyOff();
e2.keyOff();
e3.keyOff();
e4.keyOff();
}
// end if-loop received messages
}
// allow e1, e2, e3, e4 to ramp down to 0
e1.releaseTime() => now;
e2.releaseTime() => now;
// return infinite time-loop
}