1 /* 2 *This program interprets melodic lines given in ABC notation as a 3 * chromesthete might. 4 * 5 * A Pitch class will be defined, and will take center stage in the 6 * processing. 7 * 8 * Interpreting a melody in ABC notation will amount to flashing 9 * colored rectangles for prescribed durations, while sounding 10 * the pitch! The color of the rectangle will correspond to pitch 11 * class. The duration will correspond to the duration of the note. 12 * 13 * For this first version of the program, the duration will be held 14 * constant at 1 beat. 15 * 16 * Three sorts of images will appear on the screen, the chromesthetic 17 * output box, a text input box, and an error message box. Simplicity 18 * of design is rendered by permitting only one box to be on the screen 19 * at a time. 20 * 21 * ABC represents notes in a manner consistent with these examples: 22 * C,D,E, C D E c d e 23 * 24 * Google ABC music representation if you would like to know more about it 25 */ 26 package chromesthesia0; 27 import java.util.Scanner; 28 import javax.swing.JOptionPane; 29 import javax.swing.SwingUtilities; 30 import painter.SPainter; 31 public class Chromesthesia { 32 //INFRASTRUCTURE FOR THE PROGRAM --- LAUNCHING A "GRAPHICS" THREAD 33 public static void main(String[] args) { 34 SwingUtilities.invokeLater(new ThreadForGUI()); 35 } 36 private static class ThreadForGUI implements Runnable { 37 @Override 38 public void run() { 39 new Chromesthesia(); 40 } 41 } 42 public Chromesthesia(){ 43 interpreter(); 44 } 45 //FEATURED VARIABLES 46 private static SPainter miro; 47 private static Pitch[] pitches; 48 //THE INTERPRETER 49 public static void interpreter() { 50 initialization(); //miro and pitches 51 while (true) { 52 String input = getInput(); 53 if(input.equalsIgnoreCase("EXIT")) { 54 break; 55 }else { 56 try { 57 playMelody(input,pitches); 58 }catch (Exception ex) { 59 showErrorMessage(ex.toString()); 60 } 61 } 62 } 63 cleanup(); //miro has to go 64 } 65 // METHODS PERTAINING TO THE CHROMESTHETIC PITCHES 66 private static Pitch[] establishPitches(SPainter painter) { 67 Pitch[] pitches = new Pitch[9]; 68 Pitch pitchMiddleC = new Pitch("C", painter); 69 pitches[0] = pitchMiddleC; 70 Pitch pitchLowC = new Pitch("C,", painter); 71 pitches[1] = pitchLowC; 72 Pitch pitchHighC = new Pitch("c", painter); 73 pitches[2] = pitchHighC; 74 Pitch pitchMiddleD = new Pitch("D", painter); 75 pitches[3] = pitchMiddleD; 76 Pitch pitchLowD = new Pitch("D,", painter); 77 pitches[4] = pitchLowD; 78 Pitch pitchHighD = new Pitch("d", painter); 79 pitches[5] = pitchHighD; 80 Pitch pitchMiddleE = new Pitch("E", painter); 81 pitches[6] = pitchMiddleE; 82 Pitch pitchLowE = new Pitch("E,", painter); 83 pitches[7] = pitchLowE; 84 Pitch pitchHighE = new Pitch("e", painter); 85 pitches[8] = pitchHighE; 86 return pitches; 87 } 88 private static Pitch find(String token, Pitch[] pitches) throws Exception { 89 for (int i = 0; i < pitches.length; i = i + 1) { 90 Pitch pitch = pitches[i]; 91 if (pitch.abcName().equals(token)) { 92 return pitch; 93 } 94 } 95 throw new Exception("### PITCH" + token + "NOT FOUND"); 96 } 97 private static void display (Pitch[] pitches) { 98 for (int i = 0; i < pitches.length; i = i + 1) { 99 System.out.println(pitches[i].toString()); 100 } 101 } 102 103 private static void playMelody(String input, Pitch[] pitches) throws Exception { 104 Scanner scanner = new Scanner(input); 105 while (scanner.hasNext()) { 106 String token = scanner.next(); 107 Pitch pitch = find(token,pitches); 108 pitch.play("1"); 109 } 110 } 111 //INITIALIZATION, CLEANUP, GETTING INPUT, ERROR MESSAGING 112 113 static private void showErrorMessage(String message) { 114 miro.setVisible(false); 115 JOptionPane.showMessageDialog(null, message); 116 } 117 private static void initialization() { 118 //ESTABLISH THE PAINTER AND GIVE IT A SUBSTANTIAL BRUSH WIDTH 119 miro = new SPainter("Chromesthesia",500,500); 120 miro.setVisible(false); 121 miro.setBrushWidth(7); 122 //ESTABLISH THE CHROMESTHETIC PITCH CLASS OBJECTS 123 pitches = establishPitches(miro); 124 display(pitches); 125 } 126 private static String getInput() { 127 miro.setVisible(false); 128 String label = "Please enter a melody in ABC notation, or EXIT... "; 129 String input = JOptionPane.showInputDialog(null, label); 130 miro.setVisible(true); 131 if (input == null) { 132 input = ""; 133 } 134 return input; 135 136 } 137 static private void cleanup() { 138 System.exit(0); 139 } 140 }