+ public static Sequence getSequence() {
+ return seq;
+ }
+
+ /**
+ * Returns the current sequencer.
+ * @return the current sequencer
+ */
+ public static Sequencer getSequencer() {
+ return sequencer;
+ }
+
+ /**
+ * Returns the tempo in the given tick position.
+ * @param tick the tick position for which to return the tempo
+ * @return the tempo at the specified tick position
+ */
+ public static int getTempo(long tick) {
+ if (tempoChanges.size() == 0) return 120;
+ MidiEvent tempoEvent = (MidiEvent)tempoChanges.get(0);
+ if (tempoChanges.size() > 1) {
+ for (int i = 1; i < tempoChanges.size(); i++) {
+ MidiEvent nextTempoEvent = (MidiEvent)tempoChanges.get(i);
+ if (nextTempoEvent.getTick() < tick && nextTempoEvent.getTick() > tempoEvent.getTick())
+ tempoEvent = nextTempoEvent;
+ }
+ }
+ return decodeTempo(((MetaMessage)tempoEvent.getMessage()).getData());
+ }
+
+ /**
+ * Calculates the tick position in the current sequence for the given position (measures, beats, ticks).
+ * @return the tick position.
+ */
+ public static long getTicksForPosition(int measures, int beats, int ticks) {
+ int res = seq.getResolution();
+ long tickPos = 0;
+ switch (timeSignatures.size()) {
+ case 0:
+ tickPos = (4 * measures + beats) * res + ticks;
+ case 1:
+ MidiEvent TSEvent = (MidiEvent)timeSignatures.get(0);
+ int[] ts = decodeTimeSig(((MetaMessage)TSEvent.getMessage()).getData());
+ int beatsPerMeasure = ts[0] * (4 / ts[1]);
+ tickPos = (beatsPerMeasure * measures + beats) * res + ticks;
+ default:
+ Iterator it = timeSignatures.iterator();
+ MidiEvent lastTSEvent = (MidiEvent)it.next();
+ if (lastTSEvent.getTick() != 0) tickPos += (int)lastTSEvent.getTick();
+ while(it.hasNext()) {
+ MidiEvent nextTSEvent = (MidiEvent)it.next();
+ long tickDiff = nextTSEvent.getTick() - lastTSEvent.getTick();
+ ts = decodeTimeSig(((MetaMessage)lastTSEvent.getMessage()).getData());
+ beatsPerMeasure = ts[0] * (4 / ts[1]);
+ tickPos += ((beatsPerMeasure * measures + beats) * res + ticks);
+ }
+ }
+ return tickPos;
+ }
+
+ /**
+ * Returns the time signature in the given tick position.
+ * @param tick the tick position for which to return the time signature
+ * @return an array of two integers where [0] is the numerator and [1] the denominator
+ */
+ public static int[] getTimeSig(long tick) {
+ int[] ts = {4, 4};
+ if (timeSignatures.size() == 0) return ts;
+ MidiEvent timeSigEvent = (MidiEvent)timeSignatures.get(0);
+ 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())
+ timeSigEvent = nextTimeSigEvent;
+ }
+ }
+ return decodeTimeSig(((MetaMessage)timeSigEvent.getMessage()).getData());
+ }
+
+ /**
+ * Returns true if the current sequence has been edited.
+ * @return the tick position
+ */
+ public static boolean isEdited() {
+ return edited;
+ }
+
+ /**
+ * Returns whether the given track should be drawn
+ * @return true if the given track should be drawn
+ */
+ public static boolean shouldBeDrawn(Track track) {
+ if (drawEmptyTracks) return true;
+ else return (!emptyTracks.contains(track));
+ }
+
+
+
+
+
+
+
+
+ /* ***
+ ** MUTATOR METHODS **
+ *** */
+
+
+
+
+
+
+
+
+ /**
+ * Fast forwards the current sequence the given number of measures.
+ * @param measures the number of measures to fast forward
+ */
+ public static void forward(long ticks) {
+ editPosition += ticks;
+ }
+
+ /**
+ * Rewinds the current sequence the given number of measures.
+ * @param measures the number of measures to rewind
+ */
+ public static void rewind(long ticks) {
+ editPosition -= ticks;
+ }
+
+ /**
+ * Sets the currently active MidiChannel.
+ * @param channel the number of the MidiChannel to activate
+ */
+ public static void setActiveChannel(int channel) {
+ activeChannel = channels[channel];
+ }
+
+ /**
+ * Sets the current copy buffer.
+ * @param the copy buffer
+ */
+ public static void setCopyBuffer(ArrayList buffer) {
+ copyBuffer = buffer;
+ }
+
+ /**
+ * Sets whether empty tracks should be drawn
+ * @param state true if empty tracks should be drawn
+ */
+ public static void setDrawEmptyTracks(boolean state) {
+ drawEmptyTracks = state;
+ }
+
+ /**
+ * Sets the current sequence as edited, which implies prompts when loading a new sequence.
+ */
+ public static void setEdited() {
+ edited = true;
+ }
+
+ /**
+ * Sets the current editing position of the sequencer.
+ * @param ticks the tick position
+ */
+ public static void setEditPosition(long ticks) {
+ 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
+ }