import javax.sound.midi.*;
import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
/*
* Moosique's graphical user interface.
*
- * @author Andersson, Andreen, Lanneskog, Pehrson
- * @version 1
+ * @author Mikael Andreen
*/
-public class MooGUI {
+public class MooGUI extends JFrame implements WindowListener {
Sequence seq;
/*
* Creates the GUI.
*/
- public MooGUI (Sequence seq) {
-
+ public MooGUI(Sequence seq) {
+ super("Moosique");
+ MooInstrumentList m = new MooInstrumentList();
+ getContentPane().add(m);
+ m.addKeyListener(new MooKeyboard());
+ pack();
+ Dimension bounds = new Dimension(300,70);
+// setSize(bounds.width,bounds.height);
+ setLocation((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - (bounds.width / 2), (Toolkit.getDefaultToolkit().getScreenSize().height / 2) - (bounds.height / 2));
+// setResizable(false);
+ setBackground(Color.white);
+ setVisible(true);
}
/*
public void setSequence(Sequence sequence) {
seq = sequence;
}
+
+ public void windowOpened(WindowEvent e) {}
+ public void windowClosing(WindowEvent e) {}
+ public void windowClosed(WindowEvent e) {Moosique.quit();}
+ public void windowIconified(WindowEvent e) {}
+ public void windowDeiconified(WindowEvent e) {}
+ public void windowActivated(WindowEvent e) {}
+ public void windowDeactivated(WindowEvent e) {}
}
\ No newline at end of file
--- /dev/null
+import javax.sound.midi.*;
+import javax.swing.*;
+import java.awt.event.*;
+
+/*
+ * A Combo Box where the instrument of the currently active channel can be selected.
+ *
+ * @author Einar Pehrson
+ */
+
+public class MooInstrumentList extends JComboBox implements ActionListener {
+
+ public MooInstrumentList() {
+ super(instruments);
+ addActionListener(this);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ JComboBox box = (JComboBox)e.getSource();
+ int instrument = box.getSelectedIndex();
+ Moosique.getActiveChannel().programChange(instrument);
+ }
+
+ public static final String[] instruments = {
+ " 0 Acoustic Grand Piano",
+ " 1 Bright Acoustic Piano",
+ " 2 Electric Grand Piano",
+ " 3 Honky-Tonk Piano",
+ " 4 Rhodes Piano",
+ " 5 Chorused Piano",
+ " 6 Harpischord",
+ " 7 Clavinet",
+ " 8 Celesta",
+ " 9 Glockenspiel",
+ " 10 Music Box",
+ " 11 Vibraphone",
+ " 12 Marimba",
+ " 13 Xylophone",
+ " 14 Tubular Bells",
+ " 15 Dulcimer",
+ " 16 Hammond Organ",
+ " 17 Percussive Organ",
+ " 18 Rock Organ",
+ " 19 Church Organ",
+ " 20 Reed Organ",
+ " 21 Accordion",
+ " 22 Harmonica",
+ " 23 Tango Accordion",
+ " 24 Acoustic Nylon Guitar",
+ " 25 Acoustic Steel Guitar",
+ " 26 Electric Jazz Guitar",
+ " 27 Electric Clean Guitar",
+ " 28 Electric Muted Guitar",
+ " 29 Overdriven Guitar",
+ " 30 Distortion Guitar",
+ " 31 Guitar Harmonics",
+ " 32 Acoustic Bass",
+ " 33 Electric Bass Fingered",
+ " 34 Electric Bass Picked",
+ " 35 Fretless Bass",
+ " 36 Slap Bass 1",
+ " 37 Slap Bass 2",
+ " 38 Synth Bass 1",
+ " 39 Synth Bass 2",
+ " 40 Violin",
+ " 41 Viola",
+ " 42 Cello",
+ " 43 Contrabass",
+ " 44 Tremolo Strings",
+ " 45 Pizzicato Strings",
+ " 46 Orchestral Harp",
+ " 47 Timpani",
+ " 48 String Ensemble 1",
+ " 49 String Ensemble 2",
+ " 50 Synth Strings 1",
+ " 51 Synth Strings 2",
+ " 52 Choir Aahs",
+ " 53 Voice Oohs",
+ " 54 Synth Voice",
+ " 55 Orchestral Hit",
+ " 56 Trumpet",
+ " 57 Trombone",
+ " 58 Tuba",
+ " 59 Muted Trumpet",
+ " 60 French Horn",
+ " 61 Brass Section",
+ " 62 Synth Brass 1",
+ " 63 Synth Brass 2",
+ " 64 Soprano Sax",
+ " 65 Alto Sax",
+ " 66 Tenor Sax",
+ " 67 Baritone Sax",
+ " 68 Oboe",
+ " 69 English Horn",
+ " 70 Bassoon",
+ " 71 Clarinet",
+ " 72 Piccolo",
+ " 73 Flute",
+ " 74 Recorder",
+ " 75 Pan Flute",
+ " 76 Bottle Blow",
+ " 77 Shakuhachi",
+ " 78 Whistle",
+ " 79 Ocarina",
+ " 80 Synth Lead 1 Square Wave Lead",
+ " 81 Synth Lead 2 Sawtooth Wave Lead",
+ " 82 Synth Lead 3 Caliope Lead",
+ " 83 Synth Lead 4 Chiff Lead",
+ " 84 Synth Lead 5 Charang",
+ " 85 Synth Lead 6 Solo Synth Voice",
+ " 86 Synth Lead 7 Bright Saw Wave",
+ " 87 Synth Lead 8 Brass and Lead",
+ " 88 Synth Pad 1 Fantasia Pad",
+ " 89 Synth Pad 2 Warm Pad",
+ " 90 Synth Pad 3 Poly Synth Pad",
+ " 91 Synth Pad 4 Space Voice Pad",
+ " 92 Synth Pad 5 Bowed Glass Pad",
+ " 93 Synth Pad 6 Metal Pad",
+ " 94 Synth Pad 7 Halo Pad",
+ " 95 Synth Pad 8 Sweep Pad",
+ " 96 Synth SFX 1 Ice Rain",
+ " 97 Synth SFX 2 Sound Track",
+ " 98 Synth SFX 3 Crystal",
+ " 99 Synth SFX 4 Atmosphere",
+ " 100 Synth SFX 5 Brightness",
+ " 101 Synth SFX 6 Goblin",
+ " 102 Synth SFX 7 Echo Drops",
+ " 103 Synth SFX 8 Star Theme",
+ " 104 Sitar",
+ " 105 Banjo",
+ " 106 Shamisen",
+ " 107 Koto",
+ " 108 Kalimba",
+ " 109 Bagpipe",
+ " 110 Fiddle",
+ " 111 Shanai",
+ " 112 Tinkle Bells",
+ " 113 Agogo",
+ " 114 Steel Drums",
+ " 115 Woodblock",
+ " 116 Taiko Drum",
+ " 117 Melodic Tom",
+ " 118 Synth Drum",
+ " 119 Reverse Cymbal",
+ " 120 Guitar Fret Noise",
+ " 121 Breath Noise",
+ " 122 Seashore",
+ " 123 Bird Tweet",
+ " 124 Telephone Ring",
+ " 125 Helicopter",
+ " 126 Applause",
+ " 127 Gunshot"
+ };
+}
\ No newline at end of file
--- /dev/null
+import javax.sound.midi.*;
+import java.awt.event.*;
+
+/*
+ * Functional representation of a MIDI note, which contains two MIDI events, note on and note off.
+ *
+ * @author Einar Pehrson
+ */
+
+public class MooKeyboard extends KeyAdapter {
+
+ private boolean[] isOn = new boolean[120];
+ private static final int startNote = 48;
+ private static final int[] keyToNote = new int[120];
+
+ /*
+ * Plays the appropriate MIDI NoteOn event.
+ */
+ public void keyPressed(KeyEvent e) {
+ try {
+ // Retrieves the notenumber from the conversion array.
+ int noteNumber = keyToNote[e.getKeyCode()];
+ // If note is not already on and the key is mapped to a note, sends the NoteOn event.
+ if (!isOn[noteNumber] && noteNumber > 0) Moosique.getActiveChannel().noteOn(noteNumber, 127);
+ isOn[noteNumber] = true;
+ } catch (ArrayIndexOutOfBoundsException x) {
+ return;
+ }
+ }
+
+ /*
+ * Plays the appropriate MIDI NoteOff event.
+ */
+ public void keyReleased(KeyEvent e) {
+ try {
+ // Retrieves the notenumber from the conversion array.
+ int noteNumber = keyToNote[e.getKeyCode()];
+ // Sends the NoteOff event.
+ Moosique.getActiveChannel().noteOff(noteNumber);
+ isOn[noteNumber] = false;
+ } catch (ArrayIndexOutOfBoundsException x) {
+ return;
+ }
+ }
+
+ /* Maps keycodes (array indices) to MIDI note numbers using the following layout:
+ *
+ * 2 3 5 6 7 9 0 => # # # # # # #
+ * q w e r t y u i o p => c d e f g a b c d e
+ * s d g h j l => # # # # # #
+ * z x c v b n m , . => c d e f g a b c d
+ */
+ static {
+ keyToNote[90] = startNote;
+ keyToNote[83] = startNote + 1;
+ keyToNote[88] = startNote + 2;
+ keyToNote[68] = startNote + 3;
+ keyToNote[67] = startNote + 4;
+ keyToNote[86] = startNote + 5;
+ keyToNote[71] = startNote + 6;
+ keyToNote[66] = startNote + 7;
+ keyToNote[72] = startNote + 8;
+ keyToNote[78] = startNote + 9;
+ keyToNote[74] = startNote + 10;
+ keyToNote[77] = startNote + 11;
+ keyToNote[44] = startNote + 12;
+ keyToNote[76] = startNote + 13;
+ keyToNote[46] = startNote + 14;
+ keyToNote[81] = startNote + 12;
+ keyToNote[50] = startNote + 13;
+ keyToNote[87] = startNote + 14;
+ keyToNote[51] = startNote + 15;
+ keyToNote[69] = startNote + 16;
+ keyToNote[82] = startNote + 17;
+ keyToNote[53] = startNote + 18;
+ keyToNote[84] = startNote + 19;
+ keyToNote[54] = startNote + 20;
+ keyToNote[89] = startNote + 21;
+ keyToNote[55] = startNote + 22;
+ keyToNote[85] = startNote + 23;
+ keyToNote[73] = startNote + 24;
+ keyToNote[57] = startNote + 25;
+ keyToNote[79] = startNote + 26;
+ keyToNote[48] = startNote + 27;
+ keyToNote[80] = startNote + 28;
+ }
+}
\ No newline at end of file
import javax.sound.midi.*;
/*
- * Functional representation of a MIDI note, which contains two MIDI events, note on and note off.
+ * Functional representation of a MIDI note, which adds functionality to the existent MidiEvent class.
+ * Also provides a reference to the corresponding NoteOff event.
*
- * @author Andersson, Andreen, Lanneskog, Pehrson
- * @version 2.0
+ * @author Einar Pehrson
*/
public class MooNote extends MidiEvent {
- private MidiEvent noteOffEvent;
- private ShortMessage noteOnMsg, noteOffMsg;
+ protected MidiEvent noteOffEvent;
+ protected ShortMessage noteOnMsg, noteOffMsg;
/*
* Creates a MooNote from the given NoteOn event in the current track.
/*
* Moosique - The MIDI Tracker
*
- * Main class that handles initiation, IO and sound FX.
+ * Main class that handles initiation, IO and sound.
*
- * @author Andersson, Andreen, Lanneskog, Pehrson
- * @version 1
+ * @author Einar Pehrson
*/
public class Moosique {
- private static MooGUI gui;
- private static Sequence seq;
+ protected static MooGUI gui;
+ protected static Sequence seq;
- private static Sequencer sequencer = null;
- private static Synthesizer synthesizer = null;
- private static MidiChannel[] channels;
+ protected static Sequencer sequencer = null;
+ protected static Synthesizer synthesizer = null;
+ protected static MidiChannel[] channels;
+ protected static MidiChannel activeChannel;
- private static String filename;
- private static long position;
+ protected static String filename;
+ protected static long position;
/*
* Starts the application.
sequencer = MidiSystem.getSequencer();
System.out.print(".");
sequencer.open();
- System.out.print(".");
synthesizer = MidiSystem.getSynthesizer();
System.out.print(".");
synthesizer.open();
- System.out.print(".");
sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
+ channels = synthesizer.getChannels();
+ setActiveChannel(0);
} catch (MidiUnavailableException e) {
System.out.println("Failed, quitting.");
quit();
// Sets up channels and GUI.
System.out.print("Creating GUI...");
- channels = synthesizer.getChannels();
gui = new MooGUI(seq);
System.out.println("Done");
}
}
/*
- * Returns a pointer to the current sequence.
- * @return the current sequence
+ * Returns a pointer to the MidiChannels of the selected synthesizer.
+ * @return the available MidiChannels
+ */
+ public static MidiChannel[] getChannels() {
+ return channels;
+ }
+
+ /*
+ * Returns a pointer to the currently active MidiChannel.
+ * @return the active MidiChannel
+ */
+ public static MidiChannel getActiveChannel() {
+ return activeChannel;
+ }
+
+ /*
+ * Sets the currently active MidiChannel.
+ * @param channel the number of the MidiChannel to activate
+ */
+ public static void setActiveChannel(int channel) {
+ activeChannel = channels[channel];
+ }
+
+ /*
+ * Replaces the current sequence with a new one, holding three empty tracks.
*/
public static void clearSequence() {
// Creates sequence.
try {
- seq = new Sequence(Sequence.PPQ, 96);
+ seq = new Sequence(Sequence.PPQ, 96, 3);
} catch (InvalidMidiDataException e) {}
// Sends sequence to GUI.
if (gui != null) gui.setSequence(seq);
* Inställningar
- MIDI-enhet Öppna en dialogruta med innehållet i getMidiDeviceInfo() och låt användaren välja.
-* Keyjazz
- MidiChannel: noteOn, programChange etc.
-
* Referenser eller objekt?!?
tracks.get(tracks.indexOf(noteOffEvent) ???
* Kanalinställning
Hur sparas i spår?
-* Rolle är dum // Einar
\ No newline at end of file
+* Global KeyListener
+ Görs uppenbarligen så här:
+
+ JFrame someFrame = new JFrame();
+
+ JComponent rootPane = someFrame.getRootPane();
+ ActionMap am = rootPane.getActionMap();
+
+ Action helpAction = new AbstractAction() {
+ public void actionPerformed(ActionEvent ae) {
+ showHelpWindow();
+ }};
+ am.put("help", helpAction);
+
+ InputMap im = rootPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ KeyStroke helpKey = KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0);
+ im.put(helpKey, "help");
\ No newline at end of file