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