1 import javax.sound.midi.*;
6 * Moosique - The MIDI Tracker
8 * Main class that handles initiation, IO and sound FX.
10 * @author Andersson, Andreen, Lanneskog, Pehrson
14 public class Moosique {
16 private static MooGUI gui;
17 private static Sequence seq;
19 private static Sequencer sequencer = null;
20 private static Synthesizer synthesizer = null;
21 private static MidiChannel[] channels;
23 private static String filename;
24 private static long position;
27 * Starts the application.
29 public static void main (String[] args) {
30 System.out.println("Moosique version 1.0");
31 // Acquires MIDI devices and connects them.
33 sequencer = MidiSystem.getSequencer();
35 synthesizer = MidiSystem.getSynthesizer();
37 sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
38 } catch (MidiUnavailableException e) {
39 System.out.println("Unable to initialize MIDI devices.");
43 //If a filename is given as the command-line argument, attempts to load a sequence from the file.
44 if (args.length == 1) {
45 if (!load(args[0])) createSequence();
47 // Otherwise creates a new empty one.
51 // Sets up channels and GUI.
52 channels = synthesizer.getChannels();
53 gui = new MooGUI(seq);
57 * Returns a pointer to the current sequence.
58 * @return the current sequence
60 public static Sequence getSequence() {
65 * Returns a pointer to the current sequence.
66 * @return the current sequence
68 public static void createSequence() {
70 seq = new Sequence(Sequence.PPQ, 96);
71 } catch (InvalidMidiDataException e) {}
75 * Starts playback of the current sequence.
77 public static void play() {
79 sequencer.setSequence(seq);
80 sequencer.setTickPosition(position);
81 } catch (InvalidMidiDataException e) {}
86 * Pauses playback of the current sequence.
88 public static void pause() {
93 * Resumes playback of the current sequence.
95 public static void resume() {
100 * Stops playback of the current sequence.
102 public static void stop() {
104 sequencer.setTickPosition(position);
108 * Rewinds the current sequence the given number of measures.
109 * @param measures the number of measures to rewind
111 public static long getPosition() {
116 * Rewinds the current sequence the given number of measures.
117 * @param measures the number of measures to rewind
119 public static void setPosition(long ticks) {
124 * Rewinds the current sequence the given number of measures.
125 * @param measures the number of measures to rewind
127 public static void rewind(long ticks) {
132 * Fast forwards the current sequence the given number of measures.
133 * @param measures the number of measures to fast forward
135 public static void forward(long ticks) {
140 * Loads the MooSequence in the given file.
141 * @param filename the filename to use
143 public static boolean load(String file) {
144 // Loads sequence from file
147 seq = MidiSystem.getSequence(new File(filename));
148 } catch (InvalidMidiDataException e) {
150 } catch (IOException e) {
151 JOptionPane.showMessageDialog(null, "File", "alert", JOptionPane.ERROR_MESSAGE);
155 // Sends sequence to GUI
156 gui.setSequence(seq);
158 // Searches the sequence for NoteOn events
159 Track[] tracks = seq.getTracks();
160 MidiEvent noteOn, noteOff = null, nextEvent;
162 ShortMessage shortMsg;
163 for (int i = 0; i < tracks.length; i++) {
164 for (int j = 0; j < tracks[i].size(); j++) {
165 noteOn = tracks[i].get(j);
166 if (noteOn.getMessage() instanceof ShortMessage) {
167 if (((ShortMessage)noteOn.getMessage()).getCommand() == ShortMessage.NOTE_ON) {
168 // Finds the corresponding NoteOff event
169 for (int k = j + 1; k < tracks[i].size(); k++) {
170 nextEvent = tracks[i].get(k);
171 nextMsg = nextEvent.getMessage();
172 if (nextMsg instanceof ShortMessage) {
173 shortMsg = (ShortMessage) nextMsg;
174 if (shortMsg.getCommand() == ShortMessage.NOTE_OFF && shortMsg.getChannel() == ((ShortMessage)noteOn.getMessage()).getChannel() && shortMsg.getData1() == ((ShortMessage)noteOn.getMessage()).getData1()) {
180 // Replaces the NoteOn event with a MooNote, if possible with the corresponding NoteOff event
181 tracks[i].remove(noteOn);
182 if (noteOff != null) {
183 tracks[i].add(new MooNote(noteOn, noteOff));
185 tracks[i].add(new MooNote(noteOn));
195 * Saves the current sequence to the given filename
196 * @param filename the filename to use
198 public static void saveAs(String filename) throws IOException {
199 MidiSystem.write(seq, 1, new File(filename));
204 * Saves the current sequence to the previously given filename.
206 public static void save() throws IOException {
211 * Releases all reserved devices and exits the program.
213 public static void quit() {
214 if (sequencer.isOpen()) {
217 } catch (MidiUnavailableException e) {}