1 import javax.sound.midi.*;
6 Killed superfluous exportMIDI method.
7 Added public static void quit()
8 Removed Sequence seq property.
9 Changed forward(int measures) and rewind(int measures) to forward(long ticks) and rewind(long ticks).
10 Added public static long getPosition()
11 Added public static void setPosition(long ticks)
12 Added public static void resume()
16 * Moosique - The MIDI Tracker
18 * Main class that handles initiation, IO and sound FX.
20 * @author Andersson, Andreen, Lanneskog, Pehrson
24 public class Moosique {
26 private static MooGUI gui;
27 private static Sequence seq;
29 private static Sequencer sequencer = null;
30 private static Synthesizer synthesizer = null;
31 private static MidiChannel[] channels;
33 private static String filename;
34 private static long position;
37 * Starts the application.
39 public static void main (String[] args) {
40 System.out.println("Moosique version 1.0");
41 // Acquires MIDI devices and connects them.
43 sequencer = MidiSystem.getSequencer();
45 synthesizer = MidiSystem.getSynthesizer();
47 sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
48 } catch (MidiUnavailableException e) {
49 System.out.println("Unable to initialize MIDI devices.");
53 //If a filename is given as the command-line argument, attempts to load a sequence from the file.
55 if (args.length == 1) {
56 if (!load(args[0])) seq = new Sequence(Sequence.PPQ, 96);
58 // Otherwise creates a new empty one.
59 seq = new Sequence(Sequence.PPQ, 96);
61 } catch (InvalidMidiDataException e) {}
63 // Sets up channels and GUI.
64 channels = synthesizer.getChannels();
69 * Returns a pointer to the current sequence.
70 * @return the current sequence
72 public static Sequence getSequence() {
77 * Starts playback of the current sequence.
79 public static void play() {
81 sequencer.setSequence(seq);
82 } catch (InvalidMidiDataException e) {}
83 sequencer.setTickPosition(position);
88 * Pauses playback of the current sequence.
90 public static void pause() {
95 * Resumes playback of the current sequence.
97 public static void resume() {
102 * Stops playback of the current sequence.
104 public static void stop() {
106 sequencer.setTickPosition(position);
110 * Rewinds the current sequence the given number of measures.
111 * @param measures the number of measures to rewind
113 public static long getPosition() {
118 * Rewinds the current sequence the given number of measures.
119 * @param measures the number of measures to rewind
121 public static void setPosition(long ticks) {
126 * Rewinds the current sequence the given number of measures.
127 * @param measures the number of measures to rewind
129 public static void rewind(long ticks) {
134 * Fast forwards the current sequence the given number of measures.
135 * @param measures the number of measures to fast forward
137 public static void forward(long ticks) {
142 * Loads the MooSequence in the given file.
143 * @param filename the filename to use
145 public static boolean load(String file) {
146 // Loads sequence from file
149 seq = MidiSystem.getSequence(new File(filename));
150 } catch (InvalidMidiDataException e) {
152 } catch (IOException e) {
153 JOptionPane.showMessageDialog(null, "File", "alert", JOptionPane.ERROR_MESSAGE);
157 // Sends sequence to GUI
158 gui.setSequence(seq);
160 // Searches the sequence for NoteOn events
161 Track[] tracks = seq.getTracks();
162 MidiEvent noteOn, noteOff = null, nextEvent;
164 ShortMessage shortMsg;
165 for (int i = 0; i < tracks.length; i++) {
166 for (int j = 0; j < tracks[i].size(); j++) {
167 noteOn = tracks[i].get(j);
168 if (noteOn.getMessage() instanceof ShortMessage) {
169 if (((ShortMessage)noteOn.getMessage()).getCommand() == ShortMessage.NOTE_ON) {
170 // Finds the corresponding NoteOff event
171 for (int k = j + 1; k < tracks[i].size(); k++) {
172 nextEvent = tracks[i].get(k);
173 nextMsg = nextEvent.getMessage();
174 if (nextMsg instanceof ShortMessage) {
175 shortMsg = (ShortMessage) nextMsg;
176 if (shortMsg.getCommand() == ShortMessage.NOTE_OFF && shortMsg.getChannel() == ((ShortMessage)noteOn.getMessage()).getChannel() && shortMsg.getData1() == ((ShortMessage)noteOn.getMessage()).getData1()) {
182 // Replaces the NoteOn event with a MooNote, if possible with the corresponding NoteOff event
183 tracks[i].remove(noteOn);
184 if (noteOff != null) {
185 tracks[i].add(new MooNote(noteOn, noteOff));
187 tracks[i].add(new MooNote(noteOn));
197 * Saves the current sequence to the given filename
198 * @param filename the filename to use
200 public static void saveAs(String filename) throws IOException {
201 MidiSystem.write(seq, 1, new File(filename));
206 * Saves the current sequence to the previously given filename.
208 public static void save() throws IOException {
213 * Releases all reserved devices and exits the program.
215 public static void quit() {
216 if (sequencer.isOpen()) {
219 } catch (MidiUnavailableException e) {}