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])); } }