/****************************************************************** * * PROGRESSION * v1.0 * Jonathan Hey * * Created Dec 26th, 2007 * Modified Dec 26th, 2007 * * Required by the Chord Progression Generator * Requires KeyTranslator * * Description: * Generates and populates a chord progression according to the * chord leading rules. * * Future enhancements: * select a progression type to apply different rules e.g. * major/minor/harmonic/natural * * Related classes: * KeyTranslator: translates the chord numbers to their names * ********************************************************************/ class Progression { int progressionLength = 100; // good up to 100 long chord sequences int progressionCounter = 1; // start at 1 because we preload the first chord String progressionKey = "C"; boolean end = false; boolean earlyEnd = false; int chordNumber = 1; int[] chord = new int[progressionLength]; KeyTranslator k = new KeyTranslator(); // Constructor used by chord progression Progression(int l, String y){ progressionLength = l; progressionKey = y; progressionCounter = 1; k.setKey(progressionKey); chord[0] = chordNumber; //preload the first slot with the start //confirm to the screen println("Progression created :: Length " + progressionLength + " Key " + progressionKey); while(!end){ setNewChordNumber(chordNumber); chord[progressionCounter] = chordNumber; progressionCounter = progressionCounter + 1; checkEnd(); } } // blank constructor Progression(){ } // applies the chord leading rules to generate the next chord number void setNewChordNumber (int currentChordNumber){ Random r = new Random(); int pick = 0; if (currentChordNumber==1){ // can go to any chord except I // generate from 0-5 and add 2 to get 2-6 chordNumber = r.nextInt(6)+2; } else if (currentChordNumber==2){ // can go to IV, V, vii // pick 1,2, or 3 then assign 1.IV 2.V 3.vii pick = r.nextInt(3); if (pick ==0){chordNumber = 4;} else if (pick ==1){chordNumber = 5;} else if (pick ==2){chordNumber = 7;} } else if (currentChordNumber==3){ // can go to 1.ii, 2.IV, 3.vi pick = r.nextInt(3); if (pick ==0){chordNumber = 2;} else if (pick ==1){chordNumber = 4;} else if (pick ==2){chordNumber = 6;} } else if (currentChordNumber==4){ // can go to 1.I, 2.iii, 3.V, 4.vii pick = r.nextInt(4); if (pick ==0){chordNumber = 1;} else if (pick ==1){chordNumber = 3;} else if (pick ==2){chordNumber = 5;} else if (pick ==3){chordNumber = 7;} } else if (currentChordNumber==5){ // can only go to I chordNumber = 1; } else if (currentChordNumber==6){ // can go to 1.ii, 2.IV, 3.V, 4.I pick = r.nextInt(4); if (pick ==0){chordNumber = 2;} else if (pick ==1){chordNumber = 4;} else if (pick ==2){chordNumber = 5;} else if (pick ==3){chordNumber = 1;} } else if (currentChordNumber==7){ // can go to 1.I, 2.iii pick = r.nextInt(2); if (pick ==0){chordNumber = 1;} else if (pick ==1){chordNumber = 3;} } } // checks if chord progression is complete or should finish early void checkEnd(){ if (progressionCounter>=progressionLength){ end=true; } // this checks if we landed on the tonic after at least 3 chords and ends early if ((chordNumber==1) && (progressionCounter>=3)){ println("Ended early on tonic"); earlyEnd=true; end=true; } } //==================== // SET METHODS //==================== void setProgressionKey(String a){ progressionKey = a; } //==================== // GET METHODS //==================== int getChord(int n) { return chord[n]; } String getLetter(int n) { String letter = k.getLetter(chord[n]-1); return letter; } int getLength() { int returnValue = 1; if (!earlyEnd){ returnValue = progressionLength; } // if we ended early we return the counter length rather than the ideal length else if (earlyEnd){ returnValue = progressionCounter; } return returnValue; } String getProgressionKey() { return progressionKey; } }