version 1.0
This commit is contained in:
parent
cb1ee48426
commit
683924d18c
19 changed files with 775 additions and 0 deletions
3
.idea/.gitignore
vendored
Normal file
3
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
15
.idea/artifacts/LEDControl_jar.xml
Normal file
15
.idea/artifacts/LEDControl_jar.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="LEDControl:jar">
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/LEDControl_jar</output-path>
|
||||
<root id="archive" name="LEDControl.jar">
|
||||
<element id="module-output" name="LEDControl" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/fazecast/jSerialComm/2.6.2/jSerialComm-2.6.2.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/profesorfalken/jPowerShell/3.0.4/jPowerShell-3.0.4.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-simple/1.7.25/slf4j-simple-1.7.25.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/tagtraum/jipes/0.9.17/jipes-0.9.17.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/profesorfalken/jSensors/2.2.1/jSensors-2.2.1.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/net/java/dev/jna/jna/5.2.0/jna-5.2.0.jar" path-in-jar="/" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
13
.idea/compiler.xml
Normal file
13
.idea/compiler.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="LEDControl" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
20
.idea/jarRepositories.xml
Normal file
20
.idea/jarRepositories.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
14
.idea/misc.xml
Normal file
14
.idea/misc.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_15" project-jdk-name="15" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
124
.idea/uiDesigner.xml
Normal file
124
.idea/uiDesigner.xml
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
2
LEDControl.iml
Normal file
2
LEDControl.iml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4" />
|
33
pom.xml
Normal file
33
pom.xml
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>LEDControl</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>15</maven.compiler.source>
|
||||
<maven.compiler.target>15</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fazecast</groupId>
|
||||
<artifactId>jSerialComm</artifactId>
|
||||
<version>[2.0.0,3.0.0)</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.profesorfalken</groupId>
|
||||
<artifactId>jSensors</artifactId>
|
||||
<version>2.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.tagtraum</groupId>
|
||||
<artifactId>jipes</artifactId>
|
||||
<version>0.9.17</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
57
src/main/java/de/zuim/ledcontrol/EffectManager.java
Normal file
57
src/main/java/de/zuim/ledcontrol/EffectManager.java
Normal file
|
@ -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];
|
||||
}
|
||||
}
|
108
src/main/java/de/zuim/ledcontrol/LEDControl.java
Normal file
108
src/main/java/de/zuim/ledcontrol/LEDControl.java
Normal file
|
@ -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<WIDTH;x++){
|
||||
for(int y=0;y<HEIGHT;y++){
|
||||
int col = scaledImage.getRGB(x,(x%2==1)?leds[0].length-y-1:y);
|
||||
leds[x][y][0] = (byte) Math.min(((col>>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();
|
||||
}
|
||||
}
|
12
src/main/java/de/zuim/ledcontrol/LEDEffect.java
Normal file
12
src/main/java/de/zuim/ledcontrol/LEDEffect.java
Normal file
|
@ -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);
|
||||
}
|
179
src/main/java/de/zuim/ledcontrol/effects/AudioEffect.java
Normal file
179
src/main/java/de/zuim/ledcontrol/effects/AudioEffect.java
Normal file
|
@ -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<Line.Info> 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<formats.length;i++)
|
||||
{
|
||||
System.out.println("("+i+")"+formats[i]);
|
||||
}
|
||||
AudioFormat format = formats[2];
|
||||
|
||||
|
||||
System.out.println("SELECTED: "+format);
|
||||
|
||||
|
||||
final DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
|
||||
final AudioInputStream audioStream;
|
||||
|
||||
try {
|
||||
TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(info);
|
||||
targetLine.open();
|
||||
targetLine.start();
|
||||
audioStream = new AudioInputStream(targetLine);
|
||||
|
||||
final byte[] buf = new byte[BUFFERSIZE];
|
||||
|
||||
final int numberOfSamples = buf.length / format.getFrameSize();
|
||||
final Transform fft = FFTFactory.getInstance().create(numberOfSamples);
|
||||
while (audioThread != null) {
|
||||
// in real impl, don't just ignore how many bytes you read
|
||||
int read = audioStream.read(buf);
|
||||
// the stream represents each sample as two bytes -> 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<min)
|
||||
min= (int) m;
|
||||
}
|
||||
//System.out.println("M"+ max+" "+min+" "+avg/magnitudes.length+ " "+read+" "+magnitudes.length);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
};
|
||||
|
||||
audioThread = new Thread(audioRunnable);
|
||||
audioThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
if(audioThread != null && audioThread.isAlive())
|
||||
audioThread = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(long timeDelta, Graphics g) {
|
||||
for(int x = 0; x< WIDTH; x++){
|
||||
double val = 0;
|
||||
if(magnitudes != null) {
|
||||
for (int sample = 0; sample < magnitudes.length / WIDTH; sample++) {
|
||||
val += magnitudes[x * (magnitudes.length / WIDTH) + sample];
|
||||
}
|
||||
val /= (double) magnitudes.length / WIDTH;
|
||||
}
|
||||
int y= (int) Math.round(Math.max(0,val-1)/10);
|
||||
g.setColor(new Color(Math.abs(y)+1,2,0));
|
||||
g.drawRect(x,0,1,y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static final float NORMALIZATION_FACTOR_2_BYTES = Short.MAX_VALUE + 1.0f;
|
||||
private static float[] decode(final byte[] buf, final AudioFormat format) {
|
||||
final float[] fbuf = new float[buf.length / format.getFrameSize()];
|
||||
for (int pos = 0; pos < buf.length; pos += format.getFrameSize()) {
|
||||
final int sample = format.isBigEndian()
|
||||
? byteToIntBigEndian(buf, pos, format.getFrameSize())
|
||||
: byteToIntLittleEndian(buf, pos, format.getFrameSize());
|
||||
// normalize to [0,1] (not strictly necessary, but makes things easier)
|
||||
fbuf[pos / format.getFrameSize()] = sample / NORMALIZATION_FACTOR_2_BYTES;
|
||||
}
|
||||
return fbuf;
|
||||
}
|
||||
|
||||
private static double[] toMagnitudes(final float[] realPart, final float[] imaginaryPart) {
|
||||
final double[] powers = new double[realPart.length / 2];
|
||||
for (int i = 0; i < powers.length; i++) {
|
||||
powers[i] = Math.sqrt(realPart[i] * realPart[i] + imaginaryPart[i] * imaginaryPart[i]);
|
||||
}
|
||||
return powers;
|
||||
}
|
||||
|
||||
private static int byteToIntLittleEndian(final byte[] buf, final int offset, final int bytesPerSample) {
|
||||
int sample = 0;
|
||||
for (int byteIndex = 0; byteIndex < bytesPerSample; byteIndex++) {
|
||||
final int aByte = buf[offset + byteIndex] & 0xff;
|
||||
sample += aByte << 8 * (byteIndex);
|
||||
}
|
||||
return sample;
|
||||
}
|
||||
|
||||
private static int byteToIntBigEndian(final byte[] buf, final int offset, final int bytesPerSample) {
|
||||
int sample = 0;
|
||||
for (int byteIndex = 0; byteIndex < bytesPerSample; byteIndex++) {
|
||||
final int aByte = buf[offset + byteIndex] & 0xff;
|
||||
sample += aByte << (8 * (bytesPerSample - byteIndex - 1));
|
||||
}
|
||||
return sample;
|
||||
}
|
||||
}
|
49
src/main/java/de/zuim/ledcontrol/effects/ClockEffect.java
Normal file
49
src/main/java/de/zuim/ledcontrol/effects/ClockEffect.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package de.zuim.ledcontrol.effects;
|
||||
|
||||
import de.zuim.ledcontrol.LEDEffect;
|
||||
|
||||
import java.awt.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import static de.zuim.ledcontrol.LEDControl.WIDTH;
|
||||
import static java.awt.image.ImageObserver.HEIGHT;
|
||||
|
||||
public class ClockEffect implements LEDEffect {
|
||||
private Font font = new Font("Calibri", Font.BOLD, 12*getScale());
|
||||
private double posOffset = 0;
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "LED Clock";
|
||||
}
|
||||
|
||||
int iteration = 0;
|
||||
public void fontSwitcher(){
|
||||
if(++iteration%100==0){
|
||||
Font[] allFonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
|
||||
font = new Font(allFonts[iteration/100].getFontName(), Font.PLAIN, 10*getScale());
|
||||
System.out.println(allFonts[iteration/100].getFontName());
|
||||
}
|
||||
}
|
||||
|
||||
public void render(long timeDelta, Graphics g) {
|
||||
//fontSwitcher();
|
||||
|
||||
Date date = new Date();
|
||||
SimpleDateFormat formatter = new SimpleDateFormat(" H:mm");
|
||||
String text = formatter.format(date);
|
||||
SimpleDateFormat formatter2 = new SimpleDateFormat("ss");
|
||||
String text2 = formatter2.format(date);
|
||||
|
||||
g.clearRect(0,0,WIDTH,HEIGHT);
|
||||
g.setFont(font);
|
||||
g.setColor(new Color(0,10-date.getMinutes()/6,date.getMinutes()/6));
|
||||
posOffset-=(4*getScale()*timeDelta)/1000000000.0;
|
||||
g.drawString(text, (int) posOffset, 8*getScale());
|
||||
g.setColor(new Color(10-date.getSeconds()/6,date.getSeconds()/6,0));
|
||||
g.drawString(text2, 2, 16*getScale());
|
||||
if(posOffset<-g.getFontMetrics().stringWidth(text))
|
||||
posOffset=0;
|
||||
}
|
||||
}
|
26
src/main/java/de/zuim/ledcontrol/effects/ColorSweep.java
Normal file
26
src/main/java/de/zuim/ledcontrol/effects/ColorSweep.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
package de.zuim.ledcontrol.effects;
|
||||
|
||||
import de.zuim.ledcontrol.LEDEffect;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import static de.zuim.ledcontrol.LEDControl.HEIGHT;
|
||||
import static de.zuim.ledcontrol.LEDControl.WIDTH;
|
||||
|
||||
public class ColorSweep implements LEDEffect {
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Solid Color";
|
||||
}
|
||||
|
||||
float step = 0;
|
||||
@Override
|
||||
public void render(long timeDelta, Graphics gr) {
|
||||
step += timeDelta*0.0000000001d;
|
||||
if(step > 1)
|
||||
step=0;
|
||||
|
||||
gr.setColor(Color.getHSBColor(step,1f,15f/255f));
|
||||
gr.fillRect(0,0,WIDTH,HEIGHT);
|
||||
}
|
||||
}
|
53
src/main/java/de/zuim/ledcontrol/effects/SineEffect.java
Normal file
53
src/main/java/de/zuim/ledcontrol/effects/SineEffect.java
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<Component> 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<Temperature> temps = c.sensors.temperatures;
|
||||
for (final Temperature temp : temps) {
|
||||
System.out.println(temp.name + ": " + temp.value + " C");
|
||||
}
|
||||
|
||||
//Print fan speed
|
||||
List<Fan> fans = c.sensors.fans;
|
||||
for (final Fan fan : fans) {
|
||||
System.out.println(fan.name + ": " + fan.value + " RPM");
|
||||
}
|
||||
//Print fan speed
|
||||
List<Load> loads = c.sensors.loads;
|
||||
for (final Load load : loads) {
|
||||
System.out.println(load.name + ": " + load.value + " %");
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
3
src/main/resources/META-INF/MANIFEST.MF
Normal file
3
src/main/resources/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,3 @@
|
|||
Manifest-Version: 1.0
|
||||
Main-Class: de.zuim.ledcontrol.LEDControl
|
||||
|
BIN
src/main/resources/icon.png
Normal file
BIN
src/main/resources/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
Loading…
Reference in a new issue