
public class MusicPattern {
	/* Pattern definition :
	 *  0 : low  time
	 *  1 : rise time
	 *  2 : high time
	 *  3 : fall time
	 */
	private int[] pattern; // in ms
	private int totalLentgh;
	private int[] patternTiming = new int[4]; // in ms
	private long begin; // in ms
	private long stop; // in ms

	public MusicPattern(int[] pattern, int repeat, long begin) {
		if(pattern.length != 4)
			throw new InvalidPatternException();
		this.pattern = pattern;
		this.totalLentgh = pattern[0] + pattern[1] + pattern[2] + pattern[3];
		this.patternTiming[0] = pattern[0];
		for(int i=1; i<4; i++)
			this.patternTiming[i] = this.patternTiming[i-1] + pattern[i];
		this.begin = begin;
		this.stop = repeat * totalLentgh;
	}
	
	public double render(long tick) { // tick in ms
		if(tick <= begin)
			return 0;
		if(tick >= stop)
			return 0;
		int tickMod = (int) (tick % totalLentgh);
		if(tickMod < patternTiming[0])
			return 0;
		if(tickMod < patternTiming[1])
			return (double) (tickMod - patternTiming[0]) / (double) (pattern[1]);
		if(tickMod < patternTiming[2])
			return 1;
		return 1 - ((double) (tickMod - patternTiming[2]) / (double) (pattern[3]));
	}
}
