diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/artifacts/LEDControl_jar.xml b/.idea/artifacts/LEDControl_jar.xml
new file mode 100644
index 0000000..a2e19f5
--- /dev/null
+++ b/.idea/artifacts/LEDControl_jar.xml
@@ -0,0 +1,15 @@
+
+
+ $PROJECT_DIR$/out/artifacts/LEDControl_jar
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..fdf34bc
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..e6ee860
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LEDControl.iml b/LEDControl.iml
new file mode 100644
index 0000000..78b2cc5
--- /dev/null
+++ b/LEDControl.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..135b37e
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,33 @@
+
+
+ 4.0.0
+
+ org.example
+ LEDControl
+ 1.0-SNAPSHOT
+
+
+ 15
+ 15
+
+
+
+
+ com.fazecast
+ jSerialComm
+ [2.0.0,3.0.0)
+
+
+ com.profesorfalken
+ jSensors
+ 2.2.1
+
+
+ com.tagtraum
+ jipes
+ 0.9.17
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/zuim/ledcontrol/EffectManager.java b/src/main/java/de/zuim/ledcontrol/EffectManager.java
new file mode 100644
index 0000000..3f007e2
--- /dev/null
+++ b/src/main/java/de/zuim/ledcontrol/EffectManager.java
@@ -0,0 +1,57 @@
+package de.zuim.ledcontrol;
+
+import de.zuim.ledcontrol.effects.*;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+public class EffectManager {
+
+ int activeId=4;
+ private final LEDEffect[] effects = new LEDEffect[]{new TemperatureEffect(), new ClockEffect(), new SineEffect(), new AudioEffect(), new ColorSweep()};
+
+ public EffectManager(){
+
+ final SystemTray tray = SystemTray.getSystemTray();
+ final TrayIcon trayIcon = new TrayIcon(new ImageIcon(getClass().getResource("/icon.png")).getImage(),"LEDEffects");
+
+ trayIcon.addMouseListener(new MouseListener() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if(e.getButton()!=MouseEvent.BUTTON1)
+ System.exit(0);
+ getActiveEffect().unload();
+ activeId++;
+ if(activeId==effects.length)
+ activeId=0;
+ getActiveEffect().load();
+ trayIcon.setToolTip("LEDEffects - " + getActiveEffect().getDescription());
+ }
+
+ @Override
+ public void mousePressed(MouseEvent e) {}
+
+ @Override
+ public void mouseReleased(MouseEvent e) {}
+
+ @Override
+ public void mouseEntered(MouseEvent e) {}
+
+ @Override
+ public void mouseExited(MouseEvent e) {}
+ });
+ try {
+ tray.add(trayIcon);
+ } catch (AWTException e) {
+ e.printStackTrace();
+ }
+
+ getActiveEffect().load();
+ }
+
+ public LEDEffect getActiveEffect() {
+ return effects[activeId];
+ }
+}
diff --git a/src/main/java/de/zuim/ledcontrol/LEDControl.java b/src/main/java/de/zuim/ledcontrol/LEDControl.java
new file mode 100644
index 0000000..f762618
--- /dev/null
+++ b/src/main/java/de/zuim/ledcontrol/LEDControl.java
@@ -0,0 +1,108 @@
+package de.zuim.ledcontrol;
+
+import com.fazecast.jSerialComm.SerialPort;
+
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.AffineTransformOp;
+import java.awt.image.BufferedImage;
+
+public class LEDControl {
+ public static final int WIDTH=16;
+ public static final int HEIGHT=16;
+ public static final int LED_NUM = WIDTH*HEIGHT;
+ public static final int BAUD = 1000000;
+
+
+ private SerialPort port;
+ private byte[][][] leds = new byte[WIDTH][HEIGHT][3];
+ private EffectManager eff;
+ private BufferedImage scaledImage;
+
+ public LEDControl(){
+ eff = new EffectManager();
+
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> port.closePort()));
+
+ connect();
+
+ sendLoop();
+ }
+
+ private void sendLoop(){
+ long time = System.nanoTime();
+ long iteration = 0;
+
+ while(true){
+ if(port == null || !port.isOpen()){
+ sleep(1000);
+ connect();
+ continue;
+ }
+
+ long timeDelta = System.nanoTime()-time;
+ time = System.nanoTime();
+
+ renderFrame(timeDelta);
+
+ port.writeBytes(new byte[]{(byte) 255}, 1); //start of new frame
+
+ for(int x=0;x>16)&0xff),254);
+ leds[x][y][1] = (byte) Math.min((col>>8)&0xff,254);
+ leds[x][y][2] = (byte) Math.min(((col)&0xff),254);
+ port.writeBytes(leds[x][y], 3);
+ }
+ }
+
+ sleep(10);
+
+ if(iteration%1000==1){
+ System.out.println("Frametime: "+ (Math.round(timeDelta)/100000)/10.0 + "ms ("+iteration+" Frames)");
+ }
+ iteration++;
+ }
+ }
+
+ private void connect(){
+ SerialPort[] ports = SerialPort.getCommPorts();
+ if(ports.length > 0){
+ port = SerialPort.getCommPorts()[0];
+ System.out.println("Connect to " + port.getDescriptivePortName()+" "+port.getSystemPortName()+" ");
+ port.setComPortParameters(BAUD,8,1,0);
+ port.openPort();
+ }
+ }
+
+ private void sleep(int ms){
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void renderFrame(long timeDelta) {
+ BufferedImage image = new BufferedImage(16*eff.getActiveEffect().getScale(),16*eff.getActiveEffect().getScale(),BufferedImage.TYPE_INT_ARGB);
+ Graphics g = image.getGraphics();
+ eff.getActiveEffect().render(timeDelta, g);
+ g.dispose();
+
+ if(eff.getActiveEffect().getScale()==1){
+ scaledImage = image;
+ }else{
+ scaledImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB);
+ AffineTransform at = new AffineTransform();
+ at.scale(1.0/eff.getActiveEffect().getScale(), 1.0/eff.getActiveEffect().getScale());
+ AffineTransformOp scaleOp =
+ new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
+ scaledImage = scaleOp.filter(image, scaledImage);
+ }
+ }
+
+ public static void main(String[] args) {
+ new LEDControl();
+ }
+}
diff --git a/src/main/java/de/zuim/ledcontrol/LEDEffect.java b/src/main/java/de/zuim/ledcontrol/LEDEffect.java
new file mode 100644
index 0000000..f79f228
--- /dev/null
+++ b/src/main/java/de/zuim/ledcontrol/LEDEffect.java
@@ -0,0 +1,12 @@
+package de.zuim.ledcontrol;
+
+import java.awt.*;
+
+public interface LEDEffect {
+
+ String getDescription();
+ default int getScale() {return 1; }
+ default void load() {}
+ default void unload() {}
+ void render(long timeDelta, Graphics g);
+}
diff --git a/src/main/java/de/zuim/ledcontrol/effects/AudioEffect.java b/src/main/java/de/zuim/ledcontrol/effects/AudioEffect.java
new file mode 100644
index 0000000..996b183
--- /dev/null
+++ b/src/main/java/de/zuim/ledcontrol/effects/AudioEffect.java
@@ -0,0 +1,179 @@
+package de.zuim.ledcontrol.effects;
+
+import com.tagtraum.jipes.math.FFTFactory;
+import com.tagtraum.jipes.math.Transform;
+import de.zuim.ledcontrol.LEDControl;
+import de.zuim.ledcontrol.LEDEffect;
+
+import javax.sound.sampled.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static de.zuim.ledcontrol.LEDControl.HEIGHT;
+import static de.zuim.ledcontrol.LEDControl.WIDTH;
+
+public class AudioEffect implements LEDEffect {
+ @Override
+ public String getDescription() {
+ return "Audio Effect";
+ }
+
+ final static int BUFFERSIZE = 2048;
+ double[] magnitudes = null;
+ Thread audioThread = null;
+
+ @Override
+ public void load() {
+ Runnable audioRunnable = () -> {
+
+
+ Mixer.Info[] mixers = AudioSystem.getMixerInfo();
+ List availableTargetLines = new ArrayList<>();
+ for (Mixer.Info mixerInfo : mixers){
+
+ Mixer m = AudioSystem.getMixer(mixerInfo);
+
+ Line.Info[] lines = m.getTargetLineInfo();
+
+ for (Line.Info li : lines)
+ {
+ try
+ {
+ if(li instanceof DataLine.Info && mixerInfo.toString().contains("mix"))
+ {
+ m.open();
+ System.out.println("("+availableTargetLines.size()+") Found target line: " + li+" "+mixerInfo + "("+li.getClass()+")");
+ availableTargetLines.add(li);
+ m.close();
+ }
+ } catch (LineUnavailableException e){
+ System.out.println("Line unavailable.");
+ }
+ }
+ }
+
+ DataLine.Info targetLineInfo = (DataLine.Info) availableTargetLines.get(0);
+
+ System.out.println("SUPPORTED TARGET FORMATS: ");
+ AudioFormat[] formats = (targetLineInfo).getFormats();
+ for(int i=0; i decode
+
+ float[] fbuf = decode(buf,format);
+
+ final float[][] transformed = fft.transform(fbuf);
+ final float[] realPart = transformed[0];
+ final float[] imaginaryPart = transformed[1];
+ magnitudes = toMagnitudes(realPart, imaginaryPart);
+
+ //System.out.println("M"+ Arrays.toString(magnitudes));
+ // do something with magnitudes...
+ int max = 0, avg = 0,min=11111111;
+ for(double m : magnitudes){
+ avg += m;
+ if(m>max)
+ max= (int) m;
+ if(m 1)
+ step=0;
+
+ gr.setColor(Color.getHSBColor(step,1f,15f/255f));
+ gr.fillRect(0,0,WIDTH,HEIGHT);
+ }
+}
diff --git a/src/main/java/de/zuim/ledcontrol/effects/SineEffect.java b/src/main/java/de/zuim/ledcontrol/effects/SineEffect.java
new file mode 100644
index 0000000..5c88498
--- /dev/null
+++ b/src/main/java/de/zuim/ledcontrol/effects/SineEffect.java
@@ -0,0 +1,53 @@
+package de.zuim.ledcontrol.effects;
+
+import de.zuim.ledcontrol.LEDEffect;
+
+import java.awt.*;
+import java.util.Random;
+
+import static de.zuim.ledcontrol.LEDControl.HEIGHT;
+import static de.zuim.ledcontrol.LEDControl.WIDTH;
+
+public class SineEffect implements LEDEffect {
+
+ private Random r = new Random();
+ private double[][] seeds = new double[10][7];
+
+ @Override
+ public void load() {
+ for(double[] seed : seeds){
+ for(int i = 0; i < seed.length; i++){
+ seed[i] = r.nextDouble();
+ }
+ }
+ }
+
+ double steps = 0;
+ @Override
+ public void render(long timeDelta, Graphics g) {
+
+ steps += timeDelta*0.000000001;
+
+ for(int i = 0; i < 6; i++){
+ g.setColor(new Color((int) (15*seeds[i][0]), (int) (10*seeds[i][3]),(int)(4*seeds[i][4])));
+ for (int x = 0; x < WIDTH*getScale(); x++){
+ g.drawLine(x, calc(i, x),x+1,calc(i, x+1));
+ }
+ }
+ }
+
+ private int calc(int i, int x){
+ return (int) (Math.sin(((x+2*seeds[i][2])*0.5*seeds[i][1])/getScale()+steps*seeds[i][6])*7*getScale()*(seeds[i][5]+0.2) + (getScale()*HEIGHT)/2);
+ }
+
+ @Override
+ public String getDescription() {
+ return "SineEffect";
+ }
+
+ @Override
+ public int getScale() {
+ return 1;
+ }
+
+}
diff --git a/src/main/java/de/zuim/ledcontrol/effects/TemperatureEffect.java b/src/main/java/de/zuim/ledcontrol/effects/TemperatureEffect.java
new file mode 100644
index 0000000..786aa1a
--- /dev/null
+++ b/src/main/java/de/zuim/ledcontrol/effects/TemperatureEffect.java
@@ -0,0 +1,58 @@
+package de.zuim.ledcontrol.effects;
+
+import com.profesorfalken.jsensors.JSensors;
+import com.profesorfalken.jsensors.model.components.Component;
+import com.profesorfalken.jsensors.model.components.Components;
+import com.profesorfalken.jsensors.model.components.Cpu;
+import com.profesorfalken.jsensors.model.sensors.Fan;
+import com.profesorfalken.jsensors.model.sensors.Load;
+import com.profesorfalken.jsensors.model.sensors.Temperature;
+import de.zuim.ledcontrol.LEDEffect;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class TemperatureEffect implements LEDEffect {
+ @Override
+ public String getDescription() {
+ return "Temperatur Sensoren";
+ }
+
+ @Override
+ public void render(long timeDelta, Graphics g) {
+ /*Components components = JSensors.get.components();
+
+ List comps = new ArrayList<>(components.cpus);
+ comps.addAll(components.disks);
+ comps.addAll(components.gpus);
+ comps.addAll(components.mobos);
+
+ if (comps != null) {
+ for (final Component c : comps) {
+ System.out.println("Found component: " + c.name);
+ if (c.sensors != null) {
+ System.out.println("Sensors: ");
+
+ //Print temperatures
+ List temps = c.sensors.temperatures;
+ for (final Temperature temp : temps) {
+ System.out.println(temp.name + ": " + temp.value + " C");
+ }
+
+ //Print fan speed
+ List fans = c.sensors.fans;
+ for (final Fan fan : fans) {
+ System.out.println(fan.name + ": " + fan.value + " RPM");
+ }
+ //Print fan speed
+ List loads = c.sensors.loads;
+ for (final Load load : loads) {
+ System.out.println(load.name + ": " + load.value + " %");
+ }
+ }
+ }
+ }*/
+ }
+}
diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..8f32fa0
--- /dev/null
+++ b/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: de.zuim.ledcontrol.LEDControl
+
diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png
new file mode 100644
index 0000000..35cbec2
Binary files /dev/null and b/src/main/resources/icon.png differ