Commit a89c030dbaa060bff9805e64c059a5c98d311cec

Authored by pfrison
1 parent b191d7e7

VRGNYMusicLights visualizer Ok

VRGNYMusicLights/Sources/AnimationPlayer.java
@@ -10,14 +10,50 @@ import javax.swing.JPanel; @@ -10,14 +10,50 @@ import javax.swing.JPanel;
10 public class AnimationPlayer extends JPanel implements ActionListener { 10 public class AnimationPlayer extends JPanel implements ActionListener {
11 private static final long serialVersionUID = 1L; 11 private static final long serialVersionUID = 1L;
12 12
  13 + private LightCanvasJPanel lightCanvas;
  14 + private MusicList musicList;
  15 +
13 private JButton backward; 16 private JButton backward;
14 private JButton stop; 17 private JButton stop;
15 private JButton play; 18 private JButton play;
16 private JButton pause; 19 private JButton pause;
17 private JButton forward; 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 setLayout(new BoxLayout(this, direction)); 57 setLayout(new BoxLayout(this, direction));
22 58
23 add(Box.createHorizontalGlue()); 59 add(Box.createHorizontalGlue());
@@ -48,21 +84,26 @@ public class AnimationPlayer extends JPanel implements ActionListener { @@ -48,21 +84,26 @@ public class AnimationPlayer extends JPanel implements ActionListener {
48 add(forward); 84 add(forward);
49 85
50 add(Box.createHorizontalGlue()); 86 add(Box.createHorizontalGlue());
  87 +
  88 + tickClock.start();
51 } 89 }
52 90
53 @Override 91 @Override
54 public void actionPerformed(ActionEvent e) { 92 public void actionPerformed(ActionEvent e) {
55 // TODO player actions 93 // TODO player actions
56 if(e.getSource() == backward) { 94 if(e.getSource() == backward) {
57 - 95 + tick -= 500;
  96 + if(tick < 0)
  97 + tick = 0;
58 }else if(e.getSource() == stop) { 98 }else if(e.getSource() == stop) {
59 - 99 + go = false;
  100 + tick = 0;
60 }else if(e.getSource() == play) { 101 }else if(e.getSource() == play) {
61 - 102 + go = true;
62 }else if(e.getSource() == pause) { 103 }else if(e.getSource() == pause) {
63 - 104 + go = false;
64 }else if(e.getSource() == forward) { 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,7 +3,6 @@ import java.awt.Font;
3 import java.awt.event.WindowAdapter; 3 import java.awt.event.WindowAdapter;
4 import java.awt.event.WindowEvent; 4 import java.awt.event.WindowEvent;
5 5
6 -import javax.swing.BoxLayout;  
7 import javax.swing.JFrame; 6 import javax.swing.JFrame;
8 import javax.swing.JLabel; 7 import javax.swing.JLabel;
9 import javax.swing.JPanel; 8 import javax.swing.JPanel;
@@ -12,10 +11,13 @@ public class Interface extends JFrame{ @@ -12,10 +11,13 @@ public class Interface extends JFrame{
12 private static final long serialVersionUID = 1L; 11 private static final long serialVersionUID = 1L;
13 private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14); 12 private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
14 private static final Font defaultFont = new Font(new JLabel().getFont().getName(), Font.PLAIN, new JLabel().getFont().getSize()); 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 super("VRGNYMusicLights"); 19 super("VRGNYMusicLights");
18 - //this.actionList = actionList; 20 + this.musicList = musicList;
19 setResizable(false); 21 setResizable(false);
20 populateWindow(); 22 populateWindow();
21 pack(); 23 pack();
@@ -24,6 +26,8 @@ public class Interface extends JFrame{ @@ -24,6 +26,8 @@ public class Interface extends JFrame{
24 addWindowListener(new WindowAdapter() { 26 addWindowListener(new WindowAdapter() {
25 @Override 27 @Override
26 public void windowClosing(WindowEvent e) { 28 public void windowClosing(WindowEvent e) {
  29 + if(animPlayer != null)
  30 + animPlayer.stopTickClock();
27 if(executeOnClose != null) 31 if(executeOnClose != null)
28 executeOnClose.run(); 32 executeOnClose.run();
29 dispose(); 33 dispose();
@@ -34,6 +38,7 @@ public class Interface extends JFrame{ @@ -34,6 +38,7 @@ public class Interface extends JFrame{
34 private void populateWindow() { 38 private void populateWindow() {
35 JPanel mainPanel = new JPanel(new BorderLayout()); 39 JPanel mainPanel = new JPanel(new BorderLayout());
36 addPlayPanel(mainPanel); 40 addPlayPanel(mainPanel);
  41 + addTimeLine(mainPanel);
37 add(mainPanel); 42 add(mainPanel);
38 } 43 }
39 44
@@ -41,18 +46,23 @@ public class Interface extends JFrame{ @@ -41,18 +46,23 @@ public class Interface extends JFrame{
41 JPanel playPanel = new JPanel(new BorderLayout()); 46 JPanel playPanel = new JPanel(new BorderLayout());
42 47
43 // title 48 // title
44 - JLabel title = new JLabel("Player :"); 49 + JLabel title = new JLabel("Visualizer :");
45 title.setFont(titleFont); 50 title.setFont(titleFont);
46 playPanel.add(title, BorderLayout.NORTH); 51 playPanel.add(title, BorderLayout.NORTH);
47 52
48 // lights 53 // lights
49 - playPanel.add(new LightCanvasJPanel(), BorderLayout.CENTER); 54 + LightCanvasJPanel lightCanvas = new LightCanvasJPanel();
  55 + playPanel.add(lightCanvas, BorderLayout.CENTER);
50 56
51 // controls 57 // controls
52 - AnimationPlayer animPlayer = new AnimationPlayer(); 58 + animPlayer = new AnimationPlayer(lightCanvas, musicList);
53 animPlayer.setAlignmentX(CENTER_ALIGNMENT); 59 animPlayer.setAlignmentX(CENTER_ALIGNMENT);
54 playPanel.add(animPlayer, BorderLayout.SOUTH); 60 playPanel.add(animPlayer, BorderLayout.SOUTH);
55 61
56 parent.add(playPanel, BorderLayout.SOUTH); 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,33 +5,29 @@ import java.awt.Graphics;
5 import javax.swing.JPanel; 5 import javax.swing.JPanel;
6 6
7 public class LightCanvasJPanel extends JPanel { 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 private static final long serialVersionUID = 1L; 8 private static final long serialVersionUID = 1L;
18 private static final int WIDTH = 320; // = 300 + padding * 2 9 private static final int WIDTH = 320; // = 300 + padding * 2
19 private static final int HEIGHT = 220; // = 200 + padding * 2 10 private static final int HEIGHT = 220; // = 200 + padding * 2
20 private static final int LIGHT_RADIUS = 4; 11 private static final int LIGHT_RADIUS = 4;
21 private static final int PADDING = 10; 12 private static final int PADDING = 10;
22 private double[][] lightsCoords; 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 public LightCanvasJPanel(double[][] lightsCoords) { 17 public LightCanvasJPanel(double[][] lightsCoords) {
29 this.lightsCoords = lightsCoords; 18 this.lightsCoords = lightsCoords;
30 setPreferredSize(new Dimension(WIDTH, HEIGHT)); 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 @Override 27 @Override
34 protected void paintComponent(Graphics g) { 28 protected void paintComponent(Graphics g) {
  29 + super.paintComponent(g);
  30 +
35 // background 31 // background
36 g.setColor(Color.WHITE); 32 g.setColor(Color.WHITE);
37 g.fillRect(0, 0, WIDTH, HEIGHT); 33 g.fillRect(0, 0, WIDTH, HEIGHT);
@@ -47,5 +43,21 @@ public class LightCanvasJPanel extends JPanel { @@ -47,5 +43,21 @@ public class LightCanvasJPanel extends JPanel {
47 43
48 g.fillOval(centerX - LIGHT_RADIUS, centerY - LIGHT_RADIUS, LIGHT_RADIUS * 2, LIGHT_RADIUS * 2); 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 /* TODO list : 3 /* TODO list :
3 * - keyboard listener for animation player (play / pause = space, forward = semicolon, backward = comma, stop = backspace) 4 * - keyboard listener for animation player (play / pause = space, forward = semicolon, backward = comma, stop = backspace)
4 */ 5 */
5 public class Main { 6 public class Main {
6 public static void main(String[] args) throws InterruptedException { 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 try { 10 try {
11 serialPort = SerialPortChooserDialog.showSerialPortChooserDialog(); 11 serialPort = SerialPortChooserDialog.showSerialPortChooserDialog();
12 } catch (NoSerialPortException e) { 12 } catch (NoSerialPortException e) {
@@ -19,7 +19,14 @@ public class Main { @@ -19,7 +19,14 @@ public class Main {
19 // arduino need time before accepting serial data 19 // arduino need time before accepting serial data
20 Thread.sleep(1000);*/ 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 @Override 30 @Override
24 public void run() { 31 public void run() {
25 //serialCom.close(); 32 //serialCom.close();
VRGNYMusicLights/Sources/Music.java
1 1
2 public class Music { 2 public class Music {
3 private MusicPattern pattern; 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 this.pattern = pattern; 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,4 +8,24 @@ public class MusicList {
8 this.serialCom = serialCom; 8 this.serialCom = serialCom;
9 musics = new ArrayList<>(); 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 public class MusicPath { 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 private int animation; 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 this.animation = animation; 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,10 +7,35 @@ public class MusicPattern {
7 * 3 : fall time 7 * 3 : fall time
8 */ 8 */
9 private int[] pattern; // in ms 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 if(pattern.length != 4) 16 if(pattern.length != 4)
13 throw new InvalidPatternException(); 17 throw new InvalidPatternException();
14 this.pattern = pattern; 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 }