// 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. }