package com.leff.midi.util; import com.leff.midi.event.MidiEvent; import com.leff.midi.event.meta.TimeSignature; /** * An event specifically for MidiProcessor to broadcast metronome ticks so that * observers need not rely on time conversions or measure tracking */ public class MetronomeTick extends MidiEvent { private int mResolution; private TimeSignature mSignature; private int mCurrentMeasure; private int mCurrentBeat; private double mMetronomeProgress; private int mMetronomeFrequency; public MetronomeTick(TimeSignature sig, int resolution) { super(0, 0); mResolution = resolution; setTimeSignature(sig); mCurrentMeasure = 1; } public void setTimeSignature(TimeSignature sig) { mSignature = sig; mCurrentBeat = 0; setMetronomeFrequency(sig.getMeter()); } public boolean update(double ticksElapsed) { mMetronomeProgress += ticksElapsed; if(mMetronomeProgress >= mMetronomeFrequency) { mMetronomeProgress %= mMetronomeFrequency; mCurrentBeat = (mCurrentBeat + 1) % mSignature.getNumerator(); if(mCurrentBeat == 0) { mCurrentMeasure++; } return true; } return false; } public void setMetronomeFrequency(int meter) { switch(meter) { case TimeSignature.METER_EIGHTH: mMetronomeFrequency = mResolution / 2; break; case TimeSignature.METER_QUARTER: mMetronomeFrequency = mResolution; break; case TimeSignature.METER_HALF: mMetronomeFrequency = mResolution * 2; break; case TimeSignature.METER_WHOLE: mMetronomeFrequency = mResolution * 4; break; } } public int getBeatNumber() { return mCurrentBeat + 1; } public int getMeasure() { return mCurrentMeasure; } @Override public String toString() { return "Metronome: " + mCurrentMeasure + "\t" + getBeatNumber(); } @Override public int compareTo(MidiEvent o) { return 0; } @Override protected int getEventSize() { return 0; } @Override public int getSize() { return 0; } }