1 package chromesthesia2; 2 3 4 import java.util.Scanner; 5 import javax.swing.JOptionPane; 6 import javax.swing.SwingUtilities; 7 8 import chromesthesia2.Pitch; 9 import painter.SPainter; 10 11 public class Chromesthesia { 12 13 14 // INFRASTRUCTURE FOR THE PROGRAM -- LAUNCHING A "GRAPHICS" THREAD 15 16 17 public static void main(String[] args) { 18 SwingUtilities.invokeLater(new ThreadForGUI()); 19 } 20 21 private static class ThreadForGUI implements Runnable { 22 @Override 23 public void run() { 24 new Chromesthesia(); 25 } 26 } 27 28 public Chromesthesia() { 29 interpreter(); 30 } 31 // FEATURED VARIABLES 32 33 private static SPainter miro; 34 private static Pitch[] pitches; 35 36 // THE INTERPRETER 37 38 public static void interpreter () { 39 initialization(); 40 String again = ""; 41 42 // miro and pitches 43 44 while (true) { 45 String input = getInput(); 46 if (input.equalsIgnoreCase("EXIT")) { 47 break; 48 } else if (input.equalsIgnoreCase("AGAIN")) { 49 try { 50 playMelody(again, pitches); 51 } catch (Exception e) { 52 e.printStackTrace(); 53 } 54 } else { 55 try { 56 playMelody(input, pitches); 57 again = input; 58 } catch (Exception ex) { 59 showErrorMessage(ex.toString()); 60 } 61 62 63 } 64 65 } 66 67 cleanup(); // miro has to go 68 } 69 70 71 72 // METHODS PERTAINING TO THE CHROMESTHETIC PITCHES 73 74 private static chromesthesia2.Pitch[] establishPitches(SPainter painter) { 75 Pitch[] pitches = new Pitch[21]; 76 chromesthesia2.Pitch pitchMiddleC = new chromesthesia2.Pitch("C", painter); 77 pitches[0] = pitchMiddleC; 78 chromesthesia2.Pitch pitchLowC = new chromesthesia2.Pitch("C,", painter); 79 pitches[1] = pitchLowC; 80 chromesthesia2.Pitch pitchHighC = new chromesthesia2.Pitch("c", painter); 81 pitches[2] = pitchHighC; 82 83 chromesthesia2.Pitch pitchMiddleD = new chromesthesia2.Pitch("D", painter); 84 pitches[3] = pitchMiddleD; 85 chromesthesia2.Pitch pitchLowD = new chromesthesia2.Pitch("D,", painter); 86 pitches[4] = pitchLowD; 87 chromesthesia2.Pitch pitchHighD = new chromesthesia2.Pitch("d", painter); 88 pitches[5] = pitchHighD; 89 90 chromesthesia2.Pitch pitchMiddleE = new chromesthesia2.Pitch("E", painter); 91 pitches[6] = pitchMiddleE; 92 chromesthesia2.Pitch pitchLowE = new chromesthesia2.Pitch("E,", painter); 93 pitches[7] = pitchLowE; 94 chromesthesia2.Pitch pitchHighE = new chromesthesia2.Pitch("e", painter); 95 pitches[8] = pitchHighE; 96 97 chromesthesia2.Pitch pitchMiddleF = new chromesthesia2.Pitch("F", painter); 98 pitches[9] = pitchMiddleF; 99 chromesthesia2.Pitch pitchLowF = new chromesthesia2.Pitch("F,", painter); 100 pitches[10] = pitchLowF; 101 chromesthesia2.Pitch pitchHighF = new chromesthesia2.Pitch("f", painter); 102 pitches[11] = pitchHighF; 103 104 chromesthesia2.Pitch pitchMiddleG = new chromesthesia2.Pitch("G", painter); 105 pitches[12] = pitchMiddleG; 106 chromesthesia2.Pitch pitchLowG = new chromesthesia2.Pitch("G,", painter); 107 pitches[13] = pitchLowG; 108 chromesthesia2.Pitch pitchHighG = new chromesthesia2.Pitch("g", painter); 109 pitches[14] = pitchHighG; 110 111 chromesthesia2.Pitch pitchMiddleA = new chromesthesia2.Pitch("A", painter); 112 pitches[15] = pitchMiddleA; 113 chromesthesia2.Pitch pitchLowA = new chromesthesia2.Pitch("A,", painter); 114 pitches[16] = pitchLowA; 115 chromesthesia2.Pitch pitchHighA = new chromesthesia2.Pitch("a", painter); 116 pitches[17] = pitchHighA; 117 118 chromesthesia2.Pitch pitchMiddleB = new chromesthesia2.Pitch("B", painter); 119 pitches[18] = pitchMiddleB; 120 chromesthesia2.Pitch pitchLowB = new chromesthesia2.Pitch("B,", painter); 121 pitches[19] = pitchLowB; 122 chromesthesia2.Pitch pitchHighB = new chromesthesia2.Pitch("b", painter); 123 pitches[20] = pitchHighB; 124 125 return pitches; 126 127 } 128 129 private static chromesthesia2.Pitch find(String token, chromesthesia2.Pitch[] pitches) throws Exception { 130 for (int i = 0; i < pitches.length; i = i + 1) { 131 chromesthesia2.Pitch pitch = pitches[i]; 132 if (pitch.abcName().equals(token)) { 133 return pitch; 134 } 135 } 136 throw new Exception("### PITCH " + token + " NOT FOUND"); 137 } 138 139 private static void display(chromesthesia2.Pitch[] pitches) { 140 for (int i = 0; i < pitches.length; i = i + 1) { 141 System.out.println(pitches[i].toString()); 142 } 143 } 144 145 private static void playMelody(String input, Pitch[] pitches) throws Exception { 146 Scanner scanner = new Scanner(input); 147 while (scanner.hasNext()) { 148 String token = scanner.next(); 149 String pitchName; 150 String duration = ""; 151 if ( token.indexOf(",") < 0 ) { 152 pitchName = token.substring(0,1); 153 duration = token.substring(1); 154 } else { 155 pitchName = token.substring(0,2); 156 duration = token.substring(2); 157 } 158 if ( duration.length() == 0 ) { duration = "1"; } 159 Pitch pitch = find(pitchName,pitches); 160 pitch.play("1"); 161 pitch.play(duration); 162 } 163 } 164 165 166 167 168 // INITIALIZATION, CLEANUP, GETTING INPUT, ERROR MESSAGING 169 170 static private void showErrorMessage(String message) { 171 miro.setVisible(false); 172 JOptionPane.showMessageDialog(null, message); 173 } 174 175 private static void initialization() { 176 // ESTABLISH THE PAINTER AND GIVE IT A SUBSTANTIAL BRUSH WIDTH 177 miro = new SPainter("Chromesthesia", 500, 500); 178 miro.setVisible(false); 179 miro.setBrushWidth(7); 180 // ESTABLISH THE CHROMESTITIC PITCH CLASS OBJECTS 181 pitches = establishPitches(miro); 182 display(pitches); 183 } 184 185 private static String getInput() { 186 miro.setVisible(false); 187 String label = "Please enter a melody in ABC notation, or EXIT ... "; 188 String input = JOptionPane.showInputDialog(null, label); 189 miro.setVisible(true); 190 if (input == null) { 191 input = ""; 192 } 193 return input; 194 } 195 196 static private void cleanup() { 197 System.exit(0); 198 } 199 200 } 201 202