Commit a89c030dbaa060bff9805e64c059a5c98d311cec
1 parent
b191d7e7
VRGNYMusicLights visualizer Ok
Showing
8 changed files
with
277 additions
and
51 deletions
Show diff stats
VRGNYMusicLights/Sources/AnimationPlayer.java
... | ... | @@ -10,14 +10,50 @@ import javax.swing.JPanel; |
10 | 10 | public class AnimationPlayer extends JPanel implements ActionListener { |
11 | 11 | private static final long serialVersionUID = 1L; |
12 | 12 | |
13 | + private LightCanvasJPanel lightCanvas; | |
14 | + private MusicList musicList; | |
15 | + | |
13 | 16 | private JButton backward; |
14 | 17 | private JButton stop; |
15 | 18 | private JButton play; |
16 | 19 | private JButton pause; |
17 | 20 | private JButton forward; |
21 | + | |
22 | + private long tick = 0; | |
23 | + private boolean go = false; | |
24 | + private boolean stopClock = false; | |
25 | + private static final int TICK_JUMP = 20; | |
26 | + private Thread tickClock = new Thread(new Runnable() { | |
27 | + @Override | |
28 | + public void run() { | |
29 | + while(!stopClock) { | |
30 | + if(!go) { // pause | |
31 | + try { Thread.sleep(100); } | |
32 | + catch (InterruptedException ignored) {} | |
33 | + continue; | |
34 | + } | |
35 | + | |
36 | + long before = System.currentTimeMillis(); | |
37 | + lightCanvas.paintLights(musicList.render(tick)); | |
38 | + tick += TICK_JUMP; | |
39 | + long after = System.currentTimeMillis(); | |
40 | + | |
41 | + if(after - before < TICK_JUMP) { | |
42 | + try { Thread.sleep(10 - after + before);} | |
43 | + catch (InterruptedException ignored) {} | |
44 | + } else if(after - before > TICK_JUMP) { | |
45 | + System.err.println("Animation were slowed down by " + String.valueOf(after - before - 10) + " ticks !"); | |
46 | + } | |
47 | + } | |
48 | + } | |
49 | + }); | |
50 | + public void stopTickClock() {stopClock = true;} | |
18 | 51 | |
19 | - public AnimationPlayer() { this(BoxLayout.LINE_AXIS); } | |
20 | - public AnimationPlayer(int direction) { | |
52 | + public AnimationPlayer(LightCanvasJPanel lightCanvas, MusicList musicList) { this(lightCanvas, musicList, BoxLayout.LINE_AXIS); } | |
53 | + public AnimationPlayer(LightCanvasJPanel lightCanvas, MusicList musicList, int direction) { | |
54 | + this.lightCanvas = lightCanvas; | |
55 | + this.musicList = musicList; | |
56 | + | |
21 | 57 | setLayout(new BoxLayout(this, direction)); |
22 | 58 | |
23 | 59 | add(Box.createHorizontalGlue()); |
... | ... | @@ -48,21 +84,26 @@ public class AnimationPlayer extends JPanel implements ActionListener { |
48 | 84 | add(forward); |
49 | 85 | |
50 | 86 | add(Box.createHorizontalGlue()); |
87 | + | |
88 | + tickClock.start(); | |
51 | 89 | } |
52 | 90 | |
53 | 91 | @Override |
54 | 92 | public void actionPerformed(ActionEvent e) { |
55 | 93 | // TODO player actions |
56 | 94 | if(e.getSource() == backward) { |
57 | - | |
95 | + tick -= 500; | |
96 | + if(tick < 0) | |
97 | + tick = 0; | |
58 | 98 | }else if(e.getSource() == stop) { |
59 | - | |
99 | + go = false; | |
100 | + tick = 0; | |
60 | 101 | }else if(e.getSource() == play) { |
61 | - | |
102 | + go = true; | |
62 | 103 | }else if(e.getSource() == pause) { |
63 | - | |
104 | + go = false; | |
64 | 105 | }else if(e.getSource() == forward) { |
65 | - | |
106 | + tick += 500; | |
66 | 107 | } |
67 | 108 | } |
68 | 109 | } | ... | ... |
VRGNYMusicLights/Sources/Interface.java
... | ... | @@ -3,7 +3,6 @@ import java.awt.Font; |
3 | 3 | import java.awt.event.WindowAdapter; |
4 | 4 | import java.awt.event.WindowEvent; |
5 | 5 | |
6 | -import javax.swing.BoxLayout; | |
7 | 6 | import javax.swing.JFrame; |
8 | 7 | import javax.swing.JLabel; |
9 | 8 | import javax.swing.JPanel; |
... | ... | @@ -12,10 +11,13 @@ public class Interface extends JFrame{ |
12 | 11 | private static final long serialVersionUID = 1L; |
13 | 12 | private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14); |
14 | 13 | private static final Font defaultFont = new Font(new JLabel().getFont().getName(), Font.PLAIN, new JLabel().getFont().getSize()); |
14 | + | |
15 | + private MusicList musicList; | |
16 | + private AnimationPlayer animPlayer; | |
15 | 17 | |
16 | - public Interface(final Runnable executeOnClose) { | |
18 | + public Interface(MusicList musicList, final Runnable executeOnClose) { | |
17 | 19 | super("VRGNYMusicLights"); |
18 | - //this.actionList = actionList; | |
20 | + this.musicList = musicList; | |
19 | 21 | setResizable(false); |
20 | 22 | populateWindow(); |
21 | 23 | pack(); |
... | ... | @@ -24,6 +26,8 @@ public class Interface extends JFrame{ |
24 | 26 | addWindowListener(new WindowAdapter() { |
25 | 27 | @Override |
26 | 28 | public void windowClosing(WindowEvent e) { |
29 | + if(animPlayer != null) | |
30 | + animPlayer.stopTickClock(); | |
27 | 31 | if(executeOnClose != null) |
28 | 32 | executeOnClose.run(); |
29 | 33 | dispose(); |
... | ... | @@ -34,6 +38,7 @@ public class Interface extends JFrame{ |
34 | 38 | private void populateWindow() { |
35 | 39 | JPanel mainPanel = new JPanel(new BorderLayout()); |
36 | 40 | addPlayPanel(mainPanel); |
41 | + addTimeLine(mainPanel); | |
37 | 42 | add(mainPanel); |
38 | 43 | } |
39 | 44 | |
... | ... | @@ -41,18 +46,23 @@ public class Interface extends JFrame{ |
41 | 46 | JPanel playPanel = new JPanel(new BorderLayout()); |
42 | 47 | |
43 | 48 | // title |
44 | - JLabel title = new JLabel("Player :"); | |
49 | + JLabel title = new JLabel("Visualizer :"); | |
45 | 50 | title.setFont(titleFont); |
46 | 51 | playPanel.add(title, BorderLayout.NORTH); |
47 | 52 | |
48 | 53 | // lights |
49 | - playPanel.add(new LightCanvasJPanel(), BorderLayout.CENTER); | |
54 | + LightCanvasJPanel lightCanvas = new LightCanvasJPanel(); | |
55 | + playPanel.add(lightCanvas, BorderLayout.CENTER); | |
50 | 56 | |
51 | 57 | // controls |
52 | - AnimationPlayer animPlayer = new AnimationPlayer(); | |
58 | + animPlayer = new AnimationPlayer(lightCanvas, musicList); | |
53 | 59 | animPlayer.setAlignmentX(CENTER_ALIGNMENT); |
54 | 60 | playPanel.add(animPlayer, BorderLayout.SOUTH); |
55 | 61 | |
56 | 62 | parent.add(playPanel, BorderLayout.SOUTH); |
57 | 63 | } |
64 | + | |
65 | + private void addTimeLine(JPanel parent) { | |
66 | + JPanel timeLine = new JPanel(); | |
67 | + } | |
58 | 68 | } | ... | ... |
VRGNYMusicLights/Sources/LightCanvasJPanel.java
... | ... | @@ -5,33 +5,29 @@ import java.awt.Graphics; |
5 | 5 | import javax.swing.JPanel; |
6 | 6 | |
7 | 7 | public class LightCanvasJPanel extends JPanel { |
8 | - public static final double[][] DEFAULT_LIGHT_COORDS = new double[][] { | |
9 | - {0, 0} , {0.2, 0} , {0.4, 0} , {0.6 , 0}, {0.8, 0} , {1, 0} , | |
10 | - {0, 0.2}, {0.2, 0.2}, {0.4, 0.2}, {0.6, 0.2}, {0.8, 0.2}, {1, 0.2}, | |
11 | - {0, 0.4}, {0.2, 0.4}, {0.4, 0.4}, {0.6, 0.4}, {0.8, 0.4}, {1, 0.4}, | |
12 | - {0, 0.6}, {0.2, 0.6}, {0.4, 0.6}, {0.6, 0.6}, {0.8, 0.6}, {1, 0.6}, | |
13 | - {0, 0.8}, {0.2, 0.8}, {0.4, 0.8}, {0.6, 0.8}, {0.8, 0.8}, {1, 0.8}, | |
14 | - {0, 1} , {0.2, 1} , {0.4, 1} , {0.6, 1} , {0.8, 1} , {1, 1} , | |
15 | - }; | |
16 | - | |
17 | 8 | private static final long serialVersionUID = 1L; |
18 | 9 | private static final int WIDTH = 320; // = 300 + padding * 2 |
19 | 10 | private static final int HEIGHT = 220; // = 200 + padding * 2 |
20 | 11 | private static final int LIGHT_RADIUS = 4; |
21 | 12 | private static final int PADDING = 10; |
22 | 13 | private double[][] lightsCoords; |
14 | + private double[] lights = null; | |
23 | 15 | |
24 | - /** | |
25 | - * @param lightCoords : double[LightID][X = 0, Y = 1] = coordinates as a percentage [0, 1] | |
26 | - */ | |
27 | - public LightCanvasJPanel() {this(DEFAULT_LIGHT_COORDS);} | |
16 | + public LightCanvasJPanel() { this(MusicPath.LIGHT_COORDS); } | |
28 | 17 | public LightCanvasJPanel(double[][] lightsCoords) { |
29 | 18 | this.lightsCoords = lightsCoords; |
30 | 19 | setPreferredSize(new Dimension(WIDTH, HEIGHT)); |
31 | 20 | } |
32 | 21 | |
22 | + public void paintLights(double[] lights) { | |
23 | + this.lights = lights; | |
24 | + repaint(); | |
25 | + } | |
26 | + | |
33 | 27 | @Override |
34 | 28 | protected void paintComponent(Graphics g) { |
29 | + super.paintComponent(g); | |
30 | + | |
35 | 31 | // background |
36 | 32 | g.setColor(Color.WHITE); |
37 | 33 | g.fillRect(0, 0, WIDTH, HEIGHT); |
... | ... | @@ -47,5 +43,21 @@ public class LightCanvasJPanel extends JPanel { |
47 | 43 | |
48 | 44 | g.fillOval(centerX - LIGHT_RADIUS, centerY - LIGHT_RADIUS, LIGHT_RADIUS * 2, LIGHT_RADIUS * 2); |
49 | 45 | } |
46 | + | |
47 | + // lights values | |
48 | + if(lights == null || lights.length != lightsCoords.length) | |
49 | + return; | |
50 | + g.setColor(Color.YELLOW); | |
51 | + for(int i=0; i<lights.length; i++) { | |
52 | + if(lightsCoords[i].length != 2) | |
53 | + throw new MalformedCoordinates(); | |
54 | + int centerX = (int) (lightsCoords[i][0] * (WIDTH - PADDING * 2)) + PADDING; | |
55 | + int centerY = (int) (lightsCoords[i][1] * (HEIGHT - PADDING * 2)) + PADDING; | |
56 | + | |
57 | + g.fillOval((int) (centerX - (LIGHT_RADIUS * lights[i])), | |
58 | + (int) (centerY - (LIGHT_RADIUS * lights[i])), | |
59 | + (int) (LIGHT_RADIUS * lights[i] * 2), | |
60 | + (int) (LIGHT_RADIUS * lights[i] * 2)); | |
61 | + } | |
50 | 62 | } |
51 | 63 | } | ... | ... |
VRGNYMusicLights/Sources/Main.java
1 | +import javax.swing.JOptionPane; | |
1 | 2 | |
2 | 3 | /* TODO list : |
3 | 4 | * - keyboard listener for animation player (play / pause = space, forward = semicolon, backward = comma, stop = backspace) |
4 | 5 | */ |
5 | 6 | public class Main { |
6 | 7 | public static void main(String[] args) throws InterruptedException { |
7 | - /* FIXME interface testing in progress | |
8 | - | |
9 | - String serialPort = null; | |
8 | + // FIXME interface testing in progress | |
9 | + /*String serialPort = null; | |
10 | 10 | try { |
11 | 11 | serialPort = SerialPortChooserDialog.showSerialPortChooserDialog(); |
12 | 12 | } catch (NoSerialPortException e) { |
... | ... | @@ -19,7 +19,14 @@ public class Main { |
19 | 19 | // arduino need time before accepting serial data |
20 | 20 | Thread.sleep(1000);*/ |
21 | 21 | |
22 | - Interface i = new Interface(new Runnable() { | |
22 | + MusicList musicList = new MusicList(null); | |
23 | + musicList.addMusic( | |
24 | + new Music( | |
25 | + new MusicPattern(new int[] {1000, 0, 0, 1000}, 1000, 0), | |
26 | + new MusicPath(MusicPath.CENTER_IN, 1000), | |
27 | + 1)); | |
28 | + | |
29 | + Interface i = new Interface(musicList, new Runnable() { | |
23 | 30 | @Override |
24 | 31 | public void run() { |
25 | 32 | //serialCom.close(); | ... | ... |
VRGNYMusicLights/Sources/Music.java
1 | 1 | |
2 | 2 | public class Music { |
3 | 3 | private MusicPattern pattern; |
4 | - private MusicPath path; | |
5 | - private long startDelai; // in ms | |
6 | - private long length; // in ms | |
4 | + private int[] lightTickDelais; | |
5 | + private double volume; | |
7 | 6 | |
8 | - public Music(MusicPattern pattern, MusicPath path, long startDelai, long length) { | |
7 | + public Music(MusicPattern pattern, MusicPath path, double volume) { | |
9 | 8 | this.pattern = pattern; |
10 | - this.path = path; | |
11 | - this.startDelai = startDelai; | |
12 | - this.length = length; | |
13 | - | |
14 | - //call MusicPath transform() | |
9 | + this.lightTickDelais = path.calculateTickDelais(); | |
10 | + this.volume = volume; | |
11 | + } | |
12 | + | |
13 | + public double[] render(long tick) { | |
14 | + double[] lights = new double[lightTickDelais.length]; | |
15 | + for(int i=0; i<lights.length; i++) | |
16 | + lights[i] = pattern.render(lightTickDelais[i] + tick) * volume; | |
17 | + return lights; | |
15 | 18 | } |
16 | 19 | } | ... | ... |
VRGNYMusicLights/Sources/MusicList.java
... | ... | @@ -8,4 +8,24 @@ public class MusicList { |
8 | 8 | this.serialCom = serialCom; |
9 | 9 | musics = new ArrayList<>(); |
10 | 10 | } |
11 | + | |
12 | + public void addMusic(Music music) { musics.add(music); } | |
13 | + public void deleteMusic(int index) { musics.remove(index); } | |
14 | + | |
15 | + public double[] render(long tick) { | |
16 | + if(musics.size() == 0) | |
17 | + return null; | |
18 | + double[] lights = musics.get(0).render(tick); | |
19 | + for(int i=1; i<musics.size(); i++) { | |
20 | + double[] tmpRender = musics.get(i).render(tick); | |
21 | + for(int j=0; j<lights.length; j++) { | |
22 | + lights[j] += tmpRender[j]; | |
23 | + if(lights[j] < 0) | |
24 | + lights[j] = 0; | |
25 | + if(lights[j] > 1) | |
26 | + lights[j] = 1; | |
27 | + } | |
28 | + } | |
29 | + return lights; | |
30 | + } | |
11 | 31 | } | ... | ... |
VRGNYMusicLights/Sources/MusicPath.java
1 | 1 | |
2 | 2 | public class MusicPath { |
3 | - private static final int VERTICAL_DOWN = 0; | |
4 | - private static final int VERTICAL_UP = 1; | |
5 | - private static final int HORIZONTAL_DOWN = 2; | |
6 | - private static final int HORIZONTAL_UP = 3; | |
7 | - private static final int DIAGONAL_TOP_RIGHT_DOWN_LEFT = 4; | |
8 | - private static final int DIAGONAL_TOP_LEFT_DOWN_RIGHT = 5; | |
9 | - private static final int CENTER_OUT = 6; | |
10 | - private static final int CENTER_IN = 7; | |
3 | + public static final double[][] LIGHT_COORDS = new double[][] { | |
4 | + // Planche 1 | |
5 | + {0.0383, 0}, {0.0766, 0}, {0.115, 0}, {0.1533, 0}, {0.1916, 0}, {0.23, 0}, //M1L1 | |
6 | + {0.2683, 0}, {0.306, 0}, {0.345, 0}, {0.383, 0}, {0.4216, 0}, {0.46, 0}, {0.4983, 0}, //M1L2 | |
7 | + {0.0333, 0.25}, {0.0666, 0.25}, {0.0999, 0.25}, {0.1333, 0.25}, //P1-1 | |
8 | + {0.3016, 0.25}, {0.3366, 0.25}, {0.3733, 0.25}, {0.4099, 0.25}, {0.4466, 0.25}, {0.4833, 0.25}, {0.5199, 0.25}, //P1-2 | |
9 | + {0.3366, 0.3}, {0.3366, 0.35}, //P1-3 | |
10 | + {0, 0.3075}, {0, 0.365}, {0, 0.4225}, //M1l1 | |
11 | + | |
12 | + // Planche 2 | |
13 | + {0.5366, 0}, {0.575, 0}, {0.6133, 0}, {0.6516, 0}, {0.69, 0}, {0.7283, 0}, {0.7666, 0}, //M2L1 | |
14 | + {0.805, 0}, {0.8433, 0}, {0.8816, 0}, {0.92, 0}, {0.9583, 0}, //M2L2 | |
15 | + {0.5566, 0.25}, {0.5933, 0.25}, {0.6299, 0.25}, {0.6666, 0.25}, //P2-1 | |
16 | + {0.8366, 0.25}, {0.8699, 0.25}, {0.9032, 0.25}, {0.9366, 0.25}, {0.9699, 0.25}, //P2-2 | |
17 | + {1, 0.06}, {1, 0.115}, {1, 0.17}, {1, 0.225}, {1, 0.28}, {1, 0.335}, {1, 0.39}, //M2l1 | |
18 | + | |
19 | + // Planche 3 | |
20 | + {0.3366, 0.4}, {0.3366, 0.45}, {0.3366, 0.5}, //P3-1 | |
21 | + {0.3366, 0.75}, {0.3366, 0.8}, //P3-2 | |
22 | + {0, 0.48}, {0, 0.5375}, {0, 0.595}, {0, 0.6525}, {0, 0.71}, {0, 0.7675}, //M3l1 | |
23 | + | |
24 | + // Planche 4 | |
25 | + {1, 0.445}, {1, 0.5}, {1, 0.555}, {1, 0.61}, {1, 0.665}, {1, 0.72}, {1, 0.775}, //M4l1 | |
26 | + | |
27 | + // Planche 5 | |
28 | + {0.0383, 1}, {0.0766, 1}, {0.115, 1}, {0.1533, 1}, {0.1916, 1}, {0.23, 1}, //M5L1 | |
29 | + {0.2683, 1}, {0.306, 1}, {0.345, 1}, {0.383, 1}, {0.4216, 1}, {0.46, 1}, {0.4983, 1}, //M5L2 | |
30 | + {0.3366, 0.85}, {0.3366, 0.9}, {0.3366, 0.95}, //P5-1 | |
31 | + {0, 0.8255}, {0, 0.8835}, {0, 0.9415}, //M5l1 | |
32 | + | |
33 | + // Planche 6 | |
34 | + {0.5366, 1}, {0.575, 1}, {0.6133, 1}, {0.6516, 1}, {0.69, 1}, {0.7283, 1}, {0.7666, 1}, //M6L1 | |
35 | + {0.805, 1}, {0.8433, 1}, {0.8816, 1}, {0.92, 1}, {0.9583, 1}, //M6L2 | |
36 | + {1, 0.83}, {1, 0.885}, {1, 0.94} //M6l1 | |
37 | + }; | |
38 | + | |
39 | + public static final int VERTICAL_DOWN = 0; | |
40 | + public static final int VERTICAL_UP = 1; | |
41 | + public static final int HORIZONTAL_TO_LEFT = 2; | |
42 | + public static final int HORIZONTAL_TO_RIGHT = 3; | |
43 | + public static final int DIAGONAL_TOP_RIGHT_DOWN_LEFT = 4; | |
44 | + public static final int DIAGONAL_DOWN_LEFT_TOP_RIGHT = 5; | |
45 | + public static final int DIAGONAL_TOP_LEFT_DOWN_RIGHT = 6; | |
46 | + public static final int DIAGONAL_DOWN_RIGHT_TOP_LEFT = 7; | |
47 | + public static final int CENTER_OUT = 8; | |
48 | + public static final int CENTER_IN = 9; | |
49 | + public static final int ALL = 10; | |
11 | 50 | |
12 | 51 | private int animation; |
52 | + private int effectDuration; | |
53 | + private double[][] lightsCoords; | |
13 | 54 | |
14 | - public MusicPath(int animation) { | |
55 | + public MusicPath(int animation, int effectDuration) { this(animation, effectDuration, LIGHT_COORDS); } | |
56 | + public MusicPath(int animation, int effectDuration, double[][] lightsCoords) { | |
15 | 57 | this.animation = animation; |
58 | + this.effectDuration = effectDuration; | |
59 | + this.lightsCoords = lightsCoords; | |
16 | 60 | } |
17 | 61 | |
18 | - // TODO transform music according to animation | |
19 | - // what format ? int[nled][pattern] (ms) ? | |
62 | + public int[] calculateTickDelais() { // tick in ms | |
63 | + int[] ticksDelais = new int[lightsCoords.length]; | |
64 | + for(int i=0; i<ticksDelais.length; i++) { | |
65 | + ticksDelais[i] = 0; | |
66 | + if(animation == VERTICAL_DOWN | |
67 | + || animation == VERTICAL_UP | |
68 | + || animation == HORIZONTAL_TO_LEFT | |
69 | + || animation == HORIZONTAL_TO_RIGHT | |
70 | + || animation == DIAGONAL_TOP_RIGHT_DOWN_LEFT | |
71 | + || animation == DIAGONAL_DOWN_LEFT_TOP_RIGHT | |
72 | + || animation == DIAGONAL_TOP_LEFT_DOWN_RIGHT | |
73 | + || animation == DIAGONAL_DOWN_RIGHT_TOP_LEFT | |
74 | + || animation == CENTER_OUT | |
75 | + || animation == CENTER_IN) { | |
76 | + switch (animation) { | |
77 | + case VERTICAL_DOWN: | |
78 | + ticksDelais[i] += tickLateVerticalDown(LIGHT_COORDS[i][1]); | |
79 | + break; | |
80 | + case VERTICAL_UP: | |
81 | + ticksDelais[i] += tickLateVerticalUp(LIGHT_COORDS[i][1]); | |
82 | + break; | |
83 | + case HORIZONTAL_TO_LEFT: | |
84 | + ticksDelais[i] += tickLateHorizontalToLeft(LIGHT_COORDS[i][0]); | |
85 | + break; | |
86 | + case HORIZONTAL_TO_RIGHT: | |
87 | + ticksDelais[i] += tickLateHorizontalToRight(LIGHT_COORDS[i][0]); | |
88 | + break; | |
89 | + case DIAGONAL_TOP_RIGHT_DOWN_LEFT: | |
90 | + ticksDelais[i] += tickLateDiagTRDL(LIGHT_COORDS[i][0], LIGHT_COORDS[i][1]); | |
91 | + break; | |
92 | + case DIAGONAL_DOWN_LEFT_TOP_RIGHT: | |
93 | + ticksDelais[i] += tickLateDiagDLTR(LIGHT_COORDS[i][0], LIGHT_COORDS[i][1]); | |
94 | + break; | |
95 | + case DIAGONAL_TOP_LEFT_DOWN_RIGHT: | |
96 | + ticksDelais[i] += tickLateDiagTLDR(LIGHT_COORDS[i][0], LIGHT_COORDS[i][1]); | |
97 | + break; | |
98 | + case DIAGONAL_DOWN_RIGHT_TOP_LEFT: | |
99 | + ticksDelais[i] += tickLateDiagDRTL(LIGHT_COORDS[i][0], LIGHT_COORDS[i][1]); | |
100 | + break; | |
101 | + case CENTER_OUT: | |
102 | + ticksDelais[i] += tickLateCenterOut(LIGHT_COORDS[i][0], LIGHT_COORDS[i][1]); | |
103 | + break; | |
104 | + case CENTER_IN: | |
105 | + ticksDelais[i] += tickLateCenterIn(LIGHT_COORDS[i][0], LIGHT_COORDS[i][1]); | |
106 | + break; | |
107 | + } | |
108 | + } | |
109 | + else if(animation == ALL); | |
110 | + } | |
111 | + return ticksDelais; | |
112 | + } | |
113 | + | |
114 | + private int tickLateVerticalDown(double y) {return (int) ((1-y) * effectDuration);} | |
115 | + private int tickLateVerticalUp(double y) {return (int) (y * effectDuration);} | |
116 | + private int tickLateHorizontalToRight(double x) {return (int) ((1-x) * effectDuration);} | |
117 | + private int tickLateHorizontalToLeft(double x) {return (int) (x * effectDuration);} | |
118 | + private int tickLateDiagTRDL(double x, double y) {return (int) ((x - y) / 2d * (double) effectDuration);} | |
119 | + private int tickLateDiagDLTR(double x, double y) {return (int) ((-x + y) / 2d * (double) effectDuration);} | |
120 | + private int tickLateDiagDRTL(double x, double y) {return (int) ((x + y) / 2d * (double) effectDuration);} | |
121 | + private int tickLateDiagTLDR(double x, double y) {return (int) ((-x - y) / 2d * (double) effectDuration);} | |
122 | + private int tickLateCenterOut(double x, double y) {return (int) ((1 - (x-0.5)*(x-0.5) - (y-0.5)*(y-0.5)) * 2 * (double) effectDuration);} | |
123 | + private int tickLateCenterIn(double x, double y) {return (int) (((x-0.5)*(x-0.5) + (y-0.5)*(y-0.5)) * 2 * (double) effectDuration);} | |
124 | + | |
125 | + public int getNumberOfLights() { | |
126 | + return this.lightsCoords.length; | |
127 | + } | |
20 | 128 | } | ... | ... |
VRGNYMusicLights/Sources/MusicPattern.java
... | ... | @@ -7,10 +7,35 @@ public class MusicPattern { |
7 | 7 | * 3 : fall time |
8 | 8 | */ |
9 | 9 | private int[] pattern; // in ms |
10 | + private int totalLentgh; | |
11 | + private int[] patternTiming = new int[4]; // in ms | |
12 | + private long begin; // in ms | |
13 | + private long stop; // in ms | |
10 | 14 | |
11 | - public MusicPattern(int[] pattern) { | |
15 | + public MusicPattern(int[] pattern, int repeat, long begin) { | |
12 | 16 | if(pattern.length != 4) |
13 | 17 | throw new InvalidPatternException(); |
14 | 18 | this.pattern = pattern; |
19 | + this.totalLentgh = pattern[0] + pattern[1] + pattern[2] + pattern[3]; | |
20 | + this.patternTiming[0] = pattern[0]; | |
21 | + for(int i=1; i<4; i++) | |
22 | + this.patternTiming[i] = this.patternTiming[i-1] + pattern[i]; | |
23 | + this.begin = begin; | |
24 | + this.stop = repeat * totalLentgh; | |
25 | + } | |
26 | + | |
27 | + public double render(long tick) { // tick in ms | |
28 | + if(tick <= begin) | |
29 | + return 0; | |
30 | + if(tick >= stop) | |
31 | + return 0; | |
32 | + int tickMod = (int) (tick % totalLentgh); | |
33 | + if(tickMod < patternTiming[0]) | |
34 | + return 0; | |
35 | + if(tickMod < patternTiming[1]) | |
36 | + return (double) (tickMod - patternTiming[0]) / (double) (pattern[1]); | |
37 | + if(tickMod < patternTiming[2]) | |
38 | + return 1; | |
39 | + return 1 - ((double) (tickMod - patternTiming[2]) / (double) (pattern[3])); | |
15 | 40 | } |
16 | 41 | } | ... | ... |