////////////////////////////////////////////////////////////////////////////// // Copyright 2011 Alex Leffelman // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. ////////////////////////////////////////////////////////////////////////////// package com.leff.midi.event.meta; import java.io.IOException; import java.io.OutputStream; import com.leff.midi.event.MidiEvent; import com.leff.midi.util.VariableLengthInt; public class TimeSignature extends MetaEvent { public static final int METER_EIGHTH = 12; public static final int METER_QUARTER = 24; public static final int METER_HALF = 48; public static final int METER_WHOLE = 96; public static final int DEFAULT_METER = METER_QUARTER; public static final int DEFAULT_DIVISION = 8; private int mNumerator; private int mDenominator; private int mMeter; private int mDivision; public TimeSignature() { this(0, 0, 4, 4, DEFAULT_METER, DEFAULT_DIVISION); } public TimeSignature(long tick, long delta, int num, int den, int meter, int div) { super(tick, delta, MetaEvent.TIME_SIGNATURE, new VariableLengthInt(4)); setTimeSignature(num, den, meter, div); } public void setTimeSignature(int num, int den, int meter, int div) { mNumerator = num; mDenominator = log2(den); mMeter = meter; mDivision = div; } public int getNumerator() { return mNumerator; } public int getDenominatorValue() { return mDenominator; } public int getRealDenominator() { return (int) Math.pow(2, mDenominator); } public int getMeter() { return mMeter; } public int getDivision() { return mDivision; } @Override protected int getEventSize() { return 7; } @Override public void writeToFile(OutputStream out) throws IOException { super.writeToFile(out); out.write(4); out.write(mNumerator); out.write(mDenominator); out.write(mMeter); out.write(mDivision); } public static MetaEvent parseTimeSignature(long tick, long delta, MetaEventData info) { if(info.length.getValue() != 4) { return new GenericMetaEvent(tick, delta, info); } int num = info.data[0]; int den = info.data[1]; int met = info.data[2]; int fps = info.data[3]; den = (int) Math.pow(2, den); return new TimeSignature(tick, delta, num, den, met, fps); } private int log2(int den) { switch(den) { case 2: return 1; case 4: return 2; case 8: return 3; case 16: return 4; case 32: return 5; } return 0; } @Override public String toString() { return super.toString() + " " + mNumerator + "/" + getRealDenominator(); } @Override public int compareTo(MidiEvent other) { if(mTick != other.getTick()) { return mTick < other.getTick() ? -1 : 1; } if(mDelta.getValue() != other.getDelta()) { return mDelta.getValue() < other.getDelta() ? 1 : -1; } if(!(other instanceof TimeSignature)) { return 1; } TimeSignature o = (TimeSignature) other; if(mNumerator != o.mNumerator) { return mNumerator < o.mNumerator ? -1 : 1; } if(mDenominator != o.mDenominator) { return mDenominator < o.mDenominator ? -1 : 1; } return 0; } }