]> ruin.nu Git - moosique.git/blobdiff - Moosique.java
no message
[moosique.git] / Moosique.java
index 68bfd1799fd4ed00e07d1e2cc6e9aa891a3b285d..160380d5bb88be74d642efcc222d9d4cad88b411 100644 (file)
@@ -13,6 +13,7 @@ import java.util.*;
  
 public class Moosique {
 
+       // GUI and MIDI device variables
        private static MooGUI gui;
        private static Sequence seq;
        private static Sequencer sequencer;
@@ -20,18 +21,28 @@ public class Moosique {
        private static Receiver receiver;
        private static MidiChannel[] channels;
        private static MidiChannel activeChannel;
+
+       // Recording variables
        private static Track recordTrack = null;
        private static MooTrackView recordTrackView = null;
+       private static boolean[] quantizers = {false, false, false};
+       private static int quantizeResolution;
 
+       // Collections
        private static ArrayList copyBuffer, emptyTracks, timeSignatures, tempoChanges;
        private static TreeSet selection;
        private static Map trackMute = new HashMap();
        private static Map trackSolo = new HashMap();
-       private static Thread player;
 
+       // Various...
        private static File file = null;
        private static long editPosition;
+       private static Thread player;
+
+       // Preferences
        private static boolean makeGUI = true, initSound = true, edited = false, drawEmptyTracks = false;
+
+       // Constants
        public static final int DEFAULT_RESOLUTION = 96, DEFAULT_TRACKS = 4;
        public static final int WHOLE_NOTE = 16, HALF_NOTE = 8, QUARTER_NOTE = 4, EIGHTH_NOTE = 2, SIXTEENTH_NOTE = 1;
 
@@ -284,22 +295,6 @@ public class Moosique {
                editPosition = ticks;
        }
 
-       /** 
-        * Sets the current editing position of the sequencer.
-        * @param ticks         the tick position
-        */
-       public static void setTempo(int bpm) {
-               // tempoMsg
-       }
-
-       /** 
-        * Sets the current editing position of the sequencer.
-        * @param ticks         the tick position
-        */
-       public static void setTimeSig(int bpm) {
-               // timeSigMsg
-       }
-       
        /** 
         * Sets the solo setting of the given track.
         * @param on    true for solo, false for not
@@ -475,26 +470,34 @@ public class Moosique {
                        recordTrackView.disableKeyboardRecording();
                        sequencer.stopRecording();
                        sequencer.recordDisable(recordTrack);
-//                     if (quantize) recordTrackView.placeNewNotes(quantize(
-//                             convertTrack(recordTrack), SIXTEENTH_NOTE, true, true));
-//                     else recordTrackView.placeNewNotes(Moosique.convertTrack(recordTrack));
+                       if (quantizers[0]) recordTrackView.placeNewNotes(quantize(
+                               convertTrack(recordTrack), quantizeResolution, quantizers[1], quantizers[2]));
+                       else recordTrackView.placeNewNotes(Moosique.convertTrack(recordTrack));
                }
        }
 
        /** 
         * Enables recording to the given track.
+        * @param track         the track in which to store the recorded data
+        * @param tempo         the channel from which to record data
+        * @param quantizers    an array of booleans where 0 = quantize?, 1 = location, 2 = duration
+        * @param resolution    the note size to round each note to
+        * @return if the recording was initialised successfully
         */
-       public static boolean record(Track track) {
-/*             try {
+       public static boolean record(Track track, int channel, boolean[] quants, int resolution) {
+               try {
                        sequencer.recordEnable(track, channel);
                        sequencer.startRecording();
                } catch(Exception e) {
+                       e.printStackTrace();
                        return false;
                }
+               quantizers = quants;
+               quantizeResolution = resolution;
+               recordTrack = track;
                recordTrackView = gui.getView().getTrackView(track);
                recordTrackView.enableKeyboardRecording();
                Moosique.setEdited(); 
-*/
                return true;
        }
 
@@ -557,6 +560,36 @@ public class Moosique {
                return decodeTempo(((MetaMessage)tempoEvent.getMessage()).getData());
        }
 
+       /** 
+        * Sets the tempo at the given tick position.
+        * @param ticks         the tick position
+        */
+       public static void setTempo(long tick, int bpm) {
+               // Checks for a tempo event at the given tick position. 
+               MidiEvent tempoEvent = null;
+               Iterator it = tempoChanges.iterator();
+               while(it.hasNext()) {
+                       MidiEvent nextTempoEvent = (MidiEvent)it.next();
+                       if (nextTempoEvent.getTick() == tick) {
+                               tempoEvent = nextTempoEvent;
+                               break;
+                       }
+               }
+
+               // If none was found, creates and adds a new one.
+               if (tempoEvent == null) {
+                       tempoEvent = new MidiEvent(new MetaMessage(), tick);
+                       (seq.getTracks())[0].add(tempoEvent);
+                       tempoChanges.add(tempoEvent);
+                       Collections.sort(tempoChanges, new MidiEventComparator());
+               }
+
+               // Sets the tempo of the event (found or created).
+               try {
+                       ((MetaMessage)tempoEvent.getMessage()).setMessage(81, encodeTempo(bpm), 3);
+               } catch (InvalidMidiDataException e) {}
+       }
+
        /** 
         * Returns the byte array for the given time signature.
         * @param numerator     the numerator of the time signature
@@ -597,13 +630,43 @@ public class Moosique {
                if (timeSignatures.size() > 1) {
                        for (int i = 1; i < timeSignatures.size(); i++) {
                                MidiEvent nextTimeSigEvent = (MidiEvent)timeSignatures.get(i);
-                               if (nextTimeSigEvent.getTick() < tick && nextTimeSigEvent.getTick() > timeSigEvent.getTick())
+                               if (nextTimeSigEvent.getTick() <= tick && nextTimeSigEvent.getTick() > timeSigEvent.getTick())
                                        timeSigEvent = nextTimeSigEvent;
                        }
                }
                return decodeTimeSig(((MetaMessage)timeSigEvent.getMessage()).getData());
        }
 
+       /** 
+        * Sets the time signature at the given tick position.
+        * @param ticks         the tick position
+        */
+       public static void setTimeSig(long tick, int numerator, int denominator) {
+               // Checks for a time signature event at the given tick position. 
+               MidiEvent timeSigEvent = null;
+               Iterator it = timeSignatures.iterator();
+               while(it.hasNext()) {
+                       MidiEvent nextTimeSigEvent = (MidiEvent)it.next();
+                       if (nextTimeSigEvent.getTick() == tick) {
+                               timeSigEvent = nextTimeSigEvent;
+                               break;
+                       }
+               }
+
+               // If none was found, creates and adds a new one.
+               if (timeSigEvent == null) {
+                       timeSigEvent = new MidiEvent(new MetaMessage(), tick);
+                       (seq.getTracks())[0].add(timeSigEvent);
+                       timeSignatures.add(timeSigEvent);
+                       Collections.sort(timeSignatures, new MidiEventComparator());
+               }
+
+               // Sets the time signature of the event (found or created).
+               try {
+                       ((MetaMessage)timeSigEvent.getMessage()).setMessage(88, encodeTimeSig(numerator, denominator), 4);
+               } catch (InvalidMidiDataException e) {}
+       }
+       
        /**
         * Calculates the position (measures, beats, ticks) in the current sequence for the given tick position.
         * @param tickPosition the tick position for which to calculate the position
@@ -709,20 +772,18 @@ public class Moosique {
         * Replaces the current sequence with a new one, holding three empty tracks.
         */
        public static void clearSequence() {
+               // Reinitializes sequence variables
+               file = null;
+               reinitializeLists();
+
                try {
                        // Creates a new sequence.
                        seq = new Sequence(Sequence.PPQ, DEFAULT_RESOLUTION, DEFAULT_TRACKS);
                        Track[] tracks = seq.getTracks();
 
-                       // Creates messages for default tempo (120) and time signature (4/4), and adds them to track 0.
-                       MetaMessage timeSigMsg = new MetaMessage();
-                       MetaMessage tempoMsg = new MetaMessage();
-                       try {
-                               timeSigMsg.setMessage(88, encodeTimeSig(4, 4), 4);
-                               tempoMsg.setMessage(81, encodeTempo(120), 3);
-                       } catch (InvalidMidiDataException e) {}
-                       tracks[0].add(new MidiEvent(timeSigMsg, (long)0));
-                       tracks[0].add(new MidiEvent(tempoMsg, (long)0));
+                       // Sets default tempo (120) and time signature (4/4) at the beginning of the sequence.
+                       setTempo(0, 120);
+                       setTimeSig(0, 4, 4);
 
                        // Sets program and title for the tracks.
                        initializeTrack(tracks[1], 0, 24, "Guitar");
@@ -730,10 +791,6 @@ public class Moosique {
                        initializeTrack(tracks[3], 9, 0, "Drums");
                } catch (InvalidMidiDataException e) {}
 
-               // Reinitializes sequence variables
-               file = null;
-               reinitializeLists();
-
                // Sends the sequence to the GUI.
                if (gui != null) gui.setSequence(seq, null);
        }