public class MusicPattern { /* Pattern definition : * 0 : low time * 1 : rise time * 2 : high time * 3 : fall time * 4 : low time */ private int[] pattern; // in ms private int totalLength; private int[] patternTiming = new int[5]; // in ms private long begin; // in ms private long stop; // in ms private int repeat; public MusicPattern(int[] pattern, int repeat, long begin) { if(pattern.length != 5) throw new InvalidPatternException(); this.pattern = pattern; this.totalLength = pattern[0] + pattern[1] + pattern[2] + pattern[3] + pattern[4]; this.patternTiming[0] = pattern[0]; for(int i=1; i<5; i++) this.patternTiming[i] = this.patternTiming[i-1] + pattern[i]; this.begin = begin; this.stop = repeat * totalLength + begin; this.repeat = repeat; } public int[] getPattern() { return pattern; } public int[] getPatternTiming() { return patternTiming; } public long getStop() { return stop; } public long getBegin() { return begin; } public int getRepeat() { return repeat; } public int getTotalLength () { return totalLength; } public double render(long tick) { // tick in ms if(tick <= begin) return 0; if(tick >= stop) return 0; int tickMod = (int) (tick % totalLength); if(tickMod < patternTiming[0]) return 0; if(tickMod < patternTiming[1]) return (double) (tickMod - patternTiming[0]) / (double) (pattern[1]); if(tickMod < patternTiming[2]) return 1; if(tickMod < patternTiming[3]) return 1 - ((double) (tickMod - patternTiming[2]) / (double) (pattern[3])); return 0; } }