/* UD Music Theory Test JApplet */ import java.applet.Applet; import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.sound.midi.*; import java.io.*; import java.util.*; import java.net.*; public class UdmtIntvEarTraining extends JApplet implements ActionListener { private JButton setupButton, playButton, stopButton, submitButton, hintButton, giveUpButton; private JComboBox midiInComboBox, midiOutComboBox, intervalTypeCombo, intervalSizeCombo; private JComboBox startNoteCombo, indivChordCombo, upDownCombo, imntCombo; private JLabel midiInComboLabel, midiOutComboLabel, answerLabel; private String[] midiInDevices, midiOutDevices; private int[] midiInDeviceNums, midiOutDeviceNums; private int currentMidiInDeviceNum, currentMidiOutDeviceNum; private int prevMidiInDeviceNum, prevMidiOutDeviceNum; private MidiDevice.Info[] myMidiDeviceInfo; private MidiDevice myMidiInDevice, myMidiOutDevice; private Sequencer mySequencer; private Synthesizer mySynth ; private Receiver myReceiver; private Transmitter myTransmitter; private boolean midiInActive, midiOutActive; private UdmtMidiOutQueue myUdmtMidiOutQueue; private String[] StartingNote = {"C","C#","D","D#","E","F","F#","G","G#","A","A#","B","Random"}; private String[] UpDown = {"Up","Down"}; private String[] indivChord = {"Individually","Together (as a chord)"}; private String[] IntervalTypes = {"Perfect","Major","Minor","Augmented","Diminished"}; private String[] IntervalSizes = {"2nd","3rd","4th","5th","6th","7th"}; private int[] Perfect = { -1, -1, 5, 7, -1, -1 }; private int[] Major = { 2, 4, -1, -1, 9, 11 }; private int[] Minor = { 1, 3, -1, -1, 8, 10 }; private int[] Aug = { 3, 5, 6, 8, 10, 12 }; private int[] Dim = { 0, 2, 4, 6, 7, 9 }; private String[] DefaultIntvName = {"Perfect Unison", "Minor 2nd", "Major 2nd", "Minor 3rd", "Major 3rd", "Perfect 4th", "Augmented 4th", "Perfect 5th", "Minor 6th", "Major 6th", "Minor 7th", "Major 7th"}; private JLabel userScore, feedback1, feedback2, feedback3, feedback4; final int middlec = 60; int userStartNote, userUpDown, userIndivChord, userIntvType, userIntvSize, userImnt, userAnswer; int userNumCorrect = 0, userNumQues = 0, userPercent = 0; int interval, startNote, endNote; private String userStatus = "READY"; boolean userFirstGuess = false; //--------------------------------------------------------------------------------------------- public void init() { //the following line is suggested in the Java Tutorial p.459 for JDK 1.1 getRootPane().putClientProperty("defeatSystemEventQueueCheck",Boolean.TRUE); myUdmtMidiOutQueue = new UdmtMidiOutQueue(); Container content = getContentPane(); content.setLayout(new BorderLayout()); JPanel msgPanel = new JPanel(); msgPanel.setLayout (new FlowLayout() ); msgPanel.add(new JLabel("Midi In Device : "+ myUdmtMidiOutQueue.getCurrMidiInDeviceName())); msgPanel.add(new JLabel(" ")); msgPanel.add(new JLabel("Midi Out Device : "+ myUdmtMidiOutQueue.getCurrMidiOutDeviceName())); msgPanel.add(new JLabel(" ")); setupButton = new JButton("MIDI Setup"); setupButton.addActionListener(this); setupButton.setEnabled(false); msgPanel.add(setupButton); imntCombo = new JComboBox (myUdmtMidiOutQueue.GMImntList); imntCombo.addActionListener(this); msgPanel.add(imntCombo); content.add("North",msgPanel); JPanel parmPanel = new JPanel(); parmPanel.setLayout( new GridLayout(9,6) ); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel("Starting Note: ")); startNoteCombo = new JComboBox (StartingNote); startNoteCombo.addActionListener(this); parmPanel.add(startNoteCombo); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel("Up or Down: ")); upDownCombo = new JComboBox (UpDown); upDownCombo.addActionListener(this); parmPanel.add(upDownCombo); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel("Play the 2 notes: ")); indivChordCombo = new JComboBox (indivChord); indivChordCombo.addActionListener(this); parmPanel.add(indivChordCombo); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add(new JLabel("Your Score:")); userScore = new JLabel ("0 / 0 = 0%"); parmPanel.add(userScore); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); feedback1 = new JLabel(" "); feedback2 = new JLabel(" "); feedback3 = new JLabel(" "); feedback4 = new JLabel(" "); parmPanel.add (new JLabel(" ")); parmPanel.add (new JLabel(" ")); parmPanel.add (feedback1); parmPanel.add (feedback2); parmPanel.add (feedback3); parmPanel.add (feedback4); content.add("Center",parmPanel); JPanel intervalPanel = new JPanel(); intervalPanel.setLayout( new FlowLayout() ); playButton = new JButton("Play Interval"); playButton.addActionListener(this); playButton.setEnabled(true); intervalPanel.add(playButton); stopButton = new JButton("Stop Playback"); stopButton.addActionListener(this); stopButton.setEnabled(true); intervalPanel.add(stopButton); answerLabel = new JLabel("Your Answer:"); intervalPanel.add(answerLabel); intervalTypeCombo = new JComboBox (IntervalTypes); intervalTypeCombo.addActionListener(this); intervalPanel.add(intervalTypeCombo); intervalSizeCombo = new JComboBox (IntervalSizes); intervalSizeCombo.addActionListener(this); intervalPanel.add(intervalSizeCombo); submitButton = new JButton("Submit Answer"); submitButton.addActionListener(this); intervalPanel.add(submitButton); intervalPanel.add(new JLabel(" ")); hintButton = new JButton("Hint"); hintButton.addActionListener(this); intervalPanel.add(hintButton); giveUpButton = new JButton("I Give Up"); giveUpButton.addActionListener(this); intervalPanel.add(giveUpButton); content.add("South",intervalPanel); } //--------------------------------------------------------------------------------------------- public void actionPerformed(ActionEvent event) { if(event.getActionCommand().equals("Play Interval")) { if (userStatus == "READY") { pickRandomInterval(); feedback1.setText(""); feedback2.setText(""); feedback3.setText(""); feedback4.setText(""); userNumQues++; userFirstGuess = true; userStatus = "GUESSING"; } playInterval(); } else if(event.getActionCommand().equals("Stop Playback")) { myUdmtMidiOutQueue.stopSequence(); } else if (event.getActionCommand().equals("comboBoxChanged")) { // grab the current values from each combobox userStartNote = startNoteCombo.getSelectedIndex(); userUpDown = upDownCombo.getSelectedIndex(); userIndivChord = indivChordCombo.getSelectedIndex(); userIntvType = intervalTypeCombo.getSelectedIndex(); userIntvSize = intervalSizeCombo.getSelectedIndex(); userImnt = imntCombo.getSelectedIndex(); } else if (event.getActionCommand().equals("Submit Answer")) { if (checkAnswer()) { //user got it correct: if (userFirstGuess) { userNumCorrect++; } showUserScore(); userStatus = "READY"; userFirstGuess = false; playCorrect(); } else { showUserScore(); userFirstGuess = false; playIncorrect(); } } else if (event.getActionCommand().equals("Hint")) { feedback1.setText(""); feedback2.setText(""); feedback3.setText(""); feedback4.setText("Notes: " + StartingNote[startNote % 12] + " , " + StartingNote[endNote % 12]); } else if (event.getActionCommand().equals("I Give Up")) { feedback1.setText(""); feedback2.setText("The answer was:"); feedback3.setText( DefaultIntvName[interval] ); feedback4.setText("Notes: " + StartingNote[startNote % 12] + " , " + StartingNote[endNote % 12]); showUserScore(); userStatus = "READY"; playGiveUp(); } } //--------------------------------------------------------------------------------------------- private void pickRandomInterval() { interval = (int)((Math.random() * 11) + 1); if (userStartNote == 12) // Random startNote = middlec + (int)((Math.random() * 11) + 1); else startNote = middlec + userStartNote; if (userUpDown == 0) // Up endNote = startNote + interval; else endNote = startNote - interval; } //--------------------------------------------------------------------------------------------- private void playInterval() { myUdmtMidiOutQueue.createSequence(); if (userIndivChord == 0) // individual notes { myUdmtMidiOutQueue.addProgChg ( 0, userImnt ); // play 2 half notes myUdmtMidiOutQueue.addNoteOn ( 0, startNote ); myUdmtMidiOutQueue.addNoteOff ( 40, startNote ); myUdmtMidiOutQueue.addNoteOn ( 48, endNote ); myUdmtMidiOutQueue.addNoteOff ( 88, endNote ); } else // chord { myUdmtMidiOutQueue.addProgChg ( 0, userImnt ); // play whole note chord myUdmtMidiOutQueue.addNoteOn ( 0, startNote ); myUdmtMidiOutQueue.addNoteOn ( 0, endNote ); myUdmtMidiOutQueue.addNoteOff ( 88, startNote ); myUdmtMidiOutQueue.addNoteOff ( 88, endNote ); } myUdmtMidiOutQueue.addEndOfTrack ( 96 ); myUdmtMidiOutQueue.playSequence ( 120 ); } //--------------------------------------------------------------------------------------------- private boolean checkAnswer() { boolean correct = false; switch (userIntvType) { case 0: userAnswer = Perfect[userIntvSize]; break; case 1: userAnswer = Major[userIntvSize]; break; case 2: userAnswer = Minor[userIntvSize]; break; case 3: userAnswer = Aug[userIntvSize]; break; case 4: userAnswer = Dim[userIntvSize]; break; } if (userAnswer == -1) { feedback1.setText(""); feedback2.setText("Invalid Interval Name:"); feedback3.setText( IntervalTypes[userIntvType] +" "+ IntervalSizes[userIntvSize] ); feedback4.setText(""); correct = false; } else if (userAnswer == interval) { feedback1.setText(""); feedback2.setText("CORRECT!!!"); feedback3.setText(IntervalTypes[userIntvType] +" "+ IntervalSizes[userIntvSize] ); feedback4.setText("Notes: " + StartingNote[startNote % 12] + " , " + StartingNote[endNote % 12]); correct = true; } else { feedback1.setText(""); feedback2.setText("Incorrect - Try Again."); feedback3.setText("Click HINT for help."); feedback4.setText(""); correct = false; } return(correct); } //--------------------------------------------------------------------------------------------- private void showUserScore() { String score; userPercent = (int)(userNumCorrect * 100 / userNumQues); score = userNumCorrect + " / " + userNumQues + " = " + userPercent + "%"; userScore.setText(score); } //--------------------------------------------------------------------------------------------- private void playCorrect() { myUdmtMidiOutQueue.createSequence(); myUdmtMidiOutQueue.addProgChg ( 0, 126 ); // applause myUdmtMidiOutQueue.addNoteOn ( 0, 60 ); myUdmtMidiOutQueue.addNoteOff ( 88, 60 ); // middle C whole note myUdmtMidiOutQueue.addEndOfTrack ( 96 ); myUdmtMidiOutQueue.playSequence ( 120 ); } //--------------------------------------------------------------------------------------------- private void playIncorrect() { myUdmtMidiOutQueue.createSequence(); myUdmtMidiOutQueue.addProgChg ( 0, 39 ); // synth bass 2 myUdmtMidiOutQueue.addNoteOn ( 0, 48 ); myUdmtMidiOutQueue.addNoteOff ( 18, 48 ); // low C dotted 8th note myUdmtMidiOutQueue.addNoteOn ( 18, 50 ); myUdmtMidiOutQueue.addNoteOff ( 24, 50 ); // D 16th note myUdmtMidiOutQueue.addNoteOn ( 24, 51 ); myUdmtMidiOutQueue.addNoteOff ( 30, 51 ); // Eb 16th note, 16th rest myUdmtMidiOutQueue.addNoteOn ( 36, 48 ); myUdmtMidiOutQueue.addNoteOff ( 42, 48 ); // C 16th note, 16th rest myUdmtMidiOutQueue.addEndOfTrack ( 48 ); myUdmtMidiOutQueue.playSequence ( 120 ); } //--------------------------------------------------------------------------------------------- private void playGiveUp() { myUdmtMidiOutQueue.createSequence(); myUdmtMidiOutQueue.addProgChg ( 0, 123 ); // bird tweet myUdmtMidiOutQueue.addNoteOn ( 0, 60 ); myUdmtMidiOutQueue.addNoteOff ( 88, 60 ); // middle C whole note myUdmtMidiOutQueue.addEndOfTrack ( 96 ); myUdmtMidiOutQueue.playSequence ( 120 ); } //--------------------------------------------------------------------------------------------- } // END OF CLASS UdmtIntvEarTraining //---------------------------------------------------------------------------------------------