// Listing 9.20 Smart mandolin instrument and player class
// Four Mando "strings", plus some smarts
// by Perry R. Cook, March 2013
public class MandoPlayer { // (1) Public MandoPlayer class definition.
// make an array of four mandolin strings and connect them up
Mandolin m[4]; // (2) Contains four Mandolin UGens.
m[0] => JCRev rev => dac; // (3) Hooks them all up so you can hear them.
m[1] => rev;
m[2] => rev;
m[3] => rev;
0.25 => rev.gain;
0.02 => rev.mix;
// set all four string frequencies in one function
fun void freqs(float gStr, float dStr, float aStr, float eStr)
{ // (4) Sets all four string frequencies.
m[0].freq(gStr);
m[1].freq(aStr);
m[2].freq(dStr);
m[3].freq(eStr);
}
// set all four string notes in one function
fun void notes(int gNote, int dNote, int aNote, int eNote) {
m[0].freq(Std.mtof(gNote)); // (5) Sets all four string note numbers...
m[1].freq(Std.mtof(dNote)); // (6) ...using .mtof.
m[2].freq(Std.mtof(aNote));
m[3].freq(Std.mtof(eNote));
}
// a few named chords to get you started, add your own!!
fun void chord(string which) { // (7) Chords by name.
if (which == "G") this.notes(55,62,71,79); // (8) G Chord is G3, D4, B4, G5.
else if (which == "C") this.notes(55,64,72,79);
else if (which == "D") this.notes(57,62,69,78);
else <<< "I don't know this chord: ", which >>>;
}
// roll a chord from lowest note to highest at rate
fun void roll(string chord, dur rate)
{ // (9) Chord roll (arpeggiate) function.
this.chord(chord); // (10) Sets chord by string using MandoPlayer .chord function.
for (0 => int i; i < 4; i++) {
1 => m[i].noteOn; // (11) Plays notes one at a time...
rate => now; // (12) ...with rate duration between.
}
}
// Archetypical tremolo strumming
fun void strum(int note, dur howLong)
{ // (13) Strumming function (tremolo).
int whichString;
if (note < 62) 0 => whichString; // (14) Figures out which string to strum.
else if (note < 69) 1 => whichString;
else if (note < 76) 2 => whichString;
else 3 => whichString;
Std.mtof(note) => m[whichString].freq; // (15) Sets frequency.
now + howLong => time stop; // (16) Time to stop strumming...
while (now < stop) { // (17) ...do it until you get to that time.
Std.rand2f(0.5,1.0) => m[whichString].noteOn; // (18) Somewhat random volume.
Std.rand2f(0.06,0.09) :: second => now; // (19) Somewhat random time.
}
}
// Damp all strings by amount
// 0.0 = lots of damping, 1.0 = none
fun void damp(float amount) { // (20) Damping function.
for (0 => int i; i < 4; i++) {
amount => m[i].stringDamping;
}
}
// END the MandoPlayer Class Definition
// (21) Whew! Finished defining the smart Mandolin player class.
}