diff --git a/LED_Panel_arduino/LED_Panel_arduino.ino b/LED_Panel_arduino/LED_Panel_arduino.ino index bd3cb9e..03b96a3 100644 --- a/LED_Panel_arduino/LED_Panel_arduino.ino +++ b/LED_Panel_arduino/LED_Panel_arduino.ino @@ -2,7 +2,7 @@ #define PIN 3 PololuLedStrip leds; -#define LED_COUNT 256 +#define LED_COUNT 512 #define BAUD 1000000 rgb_color colors[LED_COUNT]; @@ -20,14 +20,14 @@ void loop() { byte buf[1]; unsigned int c=0; do{ - c++; - - if(Serial.readBytes(buf, 1) == 0) { - for (uint16_t i = 0; i < LED_COUNT; i++){ - colors[i] = rgb_color(0, 0, 0); + c++; + + if(Serial.readBytes(buf, 1) == 0) { + for (uint16_t i = 0; i < LED_COUNT; i++){ + colors[i] = rgb_color(0, 0, 0); + } + leds.write(colors, LED_COUNT); } - leds.write(colors, LED_COUNT); - } }while(buf[0] != 255); if(c>1){ diff --git a/LED_Panel_arduino_fastled/LED_Panel_arduino_fastled.ino b/LED_Panel_arduino_fastled/LED_Panel_arduino_fastled.ino new file mode 100644 index 0000000..3f9f248 --- /dev/null +++ b/LED_Panel_arduino_fastled/LED_Panel_arduino_fastled.ino @@ -0,0 +1,46 @@ +#include + +#define PIN 3 +#define LED_COUNT 512 +#define BAUD 1000000 + +CRGB leds[LED_COUNT]; + + +void setup() { + FastLED.addLeds(leds, LED_COUNT); + Serial.begin(BAUD); + Serial.setTimeout(500); +} + +// main program +void loop() { + + byte buf[1]; + unsigned int c=0; + + while(Serial.read() != 255){ + if(c > 100000){ + for (uint16_t i = 0; i < LED_COUNT; i++){ + leds[i] = CRGB(0,0,0); + } + FastLED.show(); + + } + c++; + } + + if(c>1){ + } + + + for (uint16_t i = 0; i < LED_COUNT; i++) + { + char col[3]; + Serial.readBytes(col, 3); + leds[i] = CRGB(col[0], col[1], col[2]); + } + + FastLED.show(); + +} diff --git a/LED_Panel_arduino_neopixel/LED_Panel_arduino_neopixel.ino b/LED_Panel_arduino_neopixel/LED_Panel_arduino_neopixel.ino new file mode 100644 index 0000000..bac6076 --- /dev/null +++ b/LED_Panel_arduino_neopixel/LED_Panel_arduino_neopixel.ino @@ -0,0 +1,44 @@ +#include + +#define PIN 3 +#define LED_COUNT 512 +#define BAUD 1000000 + +Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, PIN, NEO_GRB + NEO_KHZ800); + +void setup() { + strip.begin(); + strip.show(); + Serial.begin(BAUD); + Serial.setTimeout(500); +} + +// main program +void loop() { + + byte buf[1]; + unsigned int c=0; + + while(Serial.read() != 255){ + if(c > 100000){ + for (uint16_t i = 0; i < LED_COUNT; i++){ + strip.setPixelColor(i, strip.Color(0,0,0)); + } + strip.show(); + } + c++; + } + + if(c>1){ + } + + + for (uint16_t i = 0; i < LED_COUNT; i++) + { + char col[3]; + Serial.readBytes(col, 3); + strip.setPixelColor(i, strip.Color(col[0], col[1], col[2])); + } + + strip.show(); +} diff --git a/src/main/java/de/zuim/ledcontrol/EffectManager.java b/src/main/java/de/zuim/ledcontrol/EffectManager.java index 51dc09e..3bb60b3 100644 --- a/src/main/java/de/zuim/ledcontrol/EffectManager.java +++ b/src/main/java/de/zuim/ledcontrol/EffectManager.java @@ -16,19 +16,19 @@ public class EffectManager { private boolean sweep = false; - private final LEDEffect[] effects = new LEDEffect[]{new ClockEffect(),new AudioVolumeEffect(), new NetworkSpeedEffect(), new SineEffect(), new AudioFFTEffect(), new ColorSweepEffect()}; - private int activeId = 0; + private final LEDEffect[] effects = new LEDEffect[]{new ClockEffect(), new AudioVolumeEffect(), new NetworkSpeedEffect(), new SineEffect(), new AudioFFTEffect(), new ColorSweepEffect()}; + private int activeId = 4; private final TrayIcon trayIcon; public EffectManager() { final SystemTray tray = SystemTray.getSystemTray(); - trayIcon = new TrayIcon(new ImageIcon(getClass().getResource("/icon.png")).getImage(), "LEDEffects"); + trayIcon = new TrayIcon(new ImageIcon(getClass().getResource("/icon.png")).getImage(), "LEDEffects"); trayIcon.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent e) { - switch (e.getButton()){ + switch (e.getButton()) { case MouseEvent.BUTTON1: loadNext(); break; @@ -65,20 +65,26 @@ public class EffectManager { } new Timer(30 * 1000, e -> { - if(sweep) + if (sweep) loadNext(); }).start(); - loadNext(); + loadNext(true); } private void loadNext() { - getActiveEffect().unload(); - activeId++; - if (activeId == effects.length) - activeId = 0; + loadNext(false); + } + + private void loadNext(boolean first) { + if (!first) { + getActiveEffect().unload(); + activeId++; + if (activeId == effects.length) + activeId = 0; + } getActiveEffect().load(); - trayIcon.setToolTip("LEDEffects - " + getActiveEffect().getDescription()+ (sweep?" (autoswitch)":"")); + trayIcon.setToolTip("LEDEffects - " + getActiveEffect().getDescription() + (sweep ? " (autoswitch)" : "")); } public LEDEffect getActiveEffect() { diff --git a/src/main/java/de/zuim/ledcontrol/LEDControl.java b/src/main/java/de/zuim/ledcontrol/LEDControl.java index a7de024..6589973 100644 --- a/src/main/java/de/zuim/ledcontrol/LEDControl.java +++ b/src/main/java/de/zuim/ledcontrol/LEDControl.java @@ -11,10 +11,11 @@ import java.awt.image.BufferedImage; import java.nio.charset.StandardCharsets; public class LEDControl { - public static final int WIDTH = 16; + public static final int WIDTH = 32; public static final int HEIGHT = 16; public static final int LED_NUM = WIDTH * HEIGHT; public static final int BAUD = 1000000; + private static final int FRAME_MS = 40; private SerialPort port; @@ -37,7 +38,8 @@ public class LEDControl { long iteration = 0; long minTimeDelta = Long.MAX_VALUE, - maxTimeDelta = 0; + maxTimeDelta = 0, + avgTimeDelta = 0; while (true) { if (port == null || !port.isOpen()) { @@ -48,10 +50,11 @@ public class LEDControl { } long timeDelta = System.nanoTime() - time; - if(timeDelta > maxTimeDelta) + if (timeDelta > maxTimeDelta) maxTimeDelta = timeDelta; - if(timeDelta < minTimeDelta) + if (timeDelta < minTimeDelta) minTimeDelta = timeDelta; + avgTimeDelta += timeDelta; time = System.nanoTime(); renderFrame(timeDelta); @@ -68,12 +71,13 @@ public class LEDControl { } } - sleep(10); + sleep(FRAME_MS);//(int) (FRAME_MS) - ((System.nanoTime()-time)/1000000))); - if (iteration % 1000 == 1) { - System.out.println("Frametime: " + (Math.round(timeDelta) / 100000) / 10.0 + "ms ("+(Math.round(minTimeDelta) / 100000) / 10.0+"ms - "+(Math.round(maxTimeDelta) / 100000) / 10.0+"ms) " + iteration + " Frames"); + if (iteration % 1000 == 0 && iteration > 0) { + System.out.println("Frametime: " + (Math.round(avgTimeDelta / 1000.0) / 100000) / 10.0 + "ms (" + (Math.round(minTimeDelta) / 100000) / 10.0 + "ms - " + (Math.round(maxTimeDelta) / 100000) / 10.0 + "ms) " + iteration + " Frames"); minTimeDelta = Long.MAX_VALUE; maxTimeDelta = 0; + avgTimeDelta = 0; } iteration++; } @@ -113,7 +117,7 @@ public class LEDControl { } private void renderFrame(long timeDelta) { - BufferedImage image = new BufferedImage(16 * eff.getActiveEffect().getScale(), 16 * eff.getActiveEffect().getScale(), BufferedImage.TYPE_INT_ARGB); + BufferedImage image = new BufferedImage(WIDTH * eff.getActiveEffect().getScale(), HEIGHT * eff.getActiveEffect().getScale(), BufferedImage.TYPE_INT_ARGB); Graphics g = image.getGraphics(); eff.getActiveEffect().render(timeDelta, g); g.dispose(); 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..f4d9663 --- /dev/null +++ b/src/main/java/de/zuim/ledcontrol/effects/AudioEffect.java @@ -0,0 +1,167 @@ +package de.zuim.ledcontrol.effects; + +import com.tagtraum.jipes.math.FFTFactory; +import com.tagtraum.jipes.math.Transform; +import de.zuim.ledcontrol.LEDEffect; + +import javax.sound.sampled.*; +import java.util.ArrayList; +import java.util.List; + +public abstract class AudioEffect implements LEDEffect { + + private final List cachedAudioData = new ArrayList<>(); + private final static int BUFFERSIZE = 4096; + private 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(); + System.out.println(mixerInfo); + + for (Line.Info li : lines) { + try { + if (li instanceof DataLine.Info && mixerInfo.toString().contains("default")) { + 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[64]; + + + System.out.println("SELECTED: " + format); + + + final DataLine.Info info = new DataLine.Info(TargetDataLine.class, format); + final AudioInputStream audioStream; + + //verbesserung: https://stackoverflow.com/a/51240462 + 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) { + int read = audioStream.read(buf); + + float[] fBuf = decode(buf, format); + + final float[][] transformed = fft.transform(fBuf); + final float[] realPart = transformed[0]; + final float[] imaginaryPart = transformed[1]; + double[] magnitudes = toMagnitudes(realPart, imaginaryPart); + cachedAudioData.add(new AudioData(magnitudes, targetLine.getLevel())); + + /*System.out.println("M"+ Arrays.toString(magnitudes)); + float max = 0, avg = 0, min = 11111111; + for (float m : fBuf) { + avg += m; + if (m > max) + max = (int) m; + if (m < min) + min = (int) m; + } + System.out.println("M"+ max+" "+min+" "+avg/fBuf.length+ " "+read+" "+fBuf.length);*/ + + } + + audioStream.close(); + targetLine.close(); + } catch (Exception e) { + e.printStackTrace(); + } + }; + + audioThread = new Thread(audioRunnable); + audioThread.start(); + } + + @Override + public void unload() { + if (audioThread != null && audioThread.isAlive()) + audioThread = null; + } + + public List getData() { + return cachedAudioData; + } + + public int getMagnitudeLength() { + return cachedAudioData.isEmpty() ? 0 : cachedAudioData.get(0).magnitudes.length; + } + + 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] + fbuf[pos / format.getFrameSize()] = sample / (Short.MAX_VALUE + 1.0f); + } + 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; + } + + static class AudioData { + public double[] magnitudes; + public float level; + + public AudioData(double[] magnitudes, float level) { + this.magnitudes = magnitudes; + this.level = level; + } + } +} diff --git a/src/main/java/de/zuim/ledcontrol/effects/AudioFFTEffect.java b/src/main/java/de/zuim/ledcontrol/effects/AudioFFTEffect.java index aca8603..33b7ec8 100644 --- a/src/main/java/de/zuim/ledcontrol/effects/AudioFFTEffect.java +++ b/src/main/java/de/zuim/ledcontrol/effects/AudioFFTEffect.java @@ -1,193 +1,63 @@ package de.zuim.ledcontrol.effects; -import com.tagtraum.jipes.math.FFTFactory; -import com.tagtraum.jipes.math.Transform; -import de.zuim.ledcontrol.LEDEffect; - -import javax.sound.sampled.*; import java.awt.*; -import java.util.ArrayList; -import java.util.List; +import java.util.Arrays; import static de.zuim.ledcontrol.LEDControl.HEIGHT; import static de.zuim.ledcontrol.LEDControl.WIDTH; -public class AudioFFTEffect implements LEDEffect { +public class AudioFFTEffect extends AudioEffect { @Override public String getDescription() { return "Audio FFT"; } - final static int BUFFERSIZE = 2048; - float[] fbuf = null; - 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(); - System.out.println(mixerInfo); - - 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; - - //verbesserung: https://stackoverflow.com/a/51240462 - 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) { - int read = audioStream.read(buf); - - 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)); - - 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); - } - - audioStream.close(); - targetLine.close(); - } 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; + double[] avg = null; + if (!getData().isEmpty()) { + avg = new double[getMagnitudeLength()]; + for (int i = 0; i < getMagnitudeLength(); i++) { + for (int j = 0; j < getData().size(); j++) { + avg[i] += getData().get(j).magnitudes[i]; + } + avg[i] = avg[i] / getData().size(); + } + getData().clear(); + getData().add(new AudioData(avg, -1)); - if (magnitudes != null) { - double base = Math.exp(Math.log(magnitudes.length/2)/(WIDTH+3)); + for (int x = 0; x < WIDTH; x++) { + double val = 0; - int intervalStart = (int) Math.pow(base,x+3), - intervalEnd = (int) Math.pow(base,x+4); + int ignoreMagnitudes = 6; + double base = Math.exp(Math.log(avg.length ) / (WIDTH + ignoreMagnitudes)); + + int intervalStart = (int) Math.pow(base, x + ignoreMagnitudes), + intervalEnd = (int) Math.pow(base, x + ignoreMagnitudes + 1); //System.out.println(x+" "+intervalStart+"-"+intervalEnd); - for(int magPos = intervalStart; magPos < intervalEnd; magPos++){ - val += magnitudes[magPos]; + for (int magPos = intervalStart; magPos < intervalEnd; magPos++) { + val += avg[magPos]; } - val /= intervalEnd-intervalStart; + val /= intervalEnd - intervalStart; /* - int magnitudesInPixel = (magnitudes.length / WIDTH) / 20; - + int magnitudesInPixel = (avg.length / WIDTH) / 2; for (int sample = 0; sample < magnitudesInPixel; sample++) { - val += magnitudes[x * magnitudesInPixel + sample]; + val += avg[x * magnitudesInPixel + sample]; } - val /= (double) magnitudes.length / WIDTH;*/ + val /= (double) avg.length / WIDTH;*/ + val*=1+Math.pow(2, x/((double)WIDTH*.5)); + + int y = (int) Math.min(HEIGHT, Math.round(Math.max(1, val + 10)) / 30); + g.setColor(new Color(Math.abs(y) + 1, 2, 0)); + g.drawRect(x, HEIGHT - y, 0, HEIGHT); + g.setColor(new Color(Math.abs(y), 0, 0)); + g.drawRect(x, HEIGHT - y, 0, 0); } - int y = (int) Math.min(HEIGHT,Math.round(Math.max(1, val+10))/10); - g.setColor(new Color(Math.abs(y) + 1, 2, 0)); - g.drawRect(x, HEIGHT - y, 0, HEIGHT); - g.setColor(new Color(Math.abs(y), 0, 0)); - g.drawRect(x, HEIGHT - y, 0, 0); } } - 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] - fbuf[pos / format.getFrameSize()] = sample / (Short.MAX_VALUE + 1.0f); - } - 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; - } } diff --git a/src/main/java/de/zuim/ledcontrol/effects/AudioVolumeEffect.java b/src/main/java/de/zuim/ledcontrol/effects/AudioVolumeEffect.java index 762c5e1..37686ef 100644 --- a/src/main/java/de/zuim/ledcontrol/effects/AudioVolumeEffect.java +++ b/src/main/java/de/zuim/ledcontrol/effects/AudioVolumeEffect.java @@ -21,17 +21,19 @@ public class AudioVolumeEffect extends AudioFFTEffect { public void render(long timeDelta, Graphics g) { timeDeltaSum += timeDelta; - if (fbuf != null) { - float avg = 0; + if (!getData().isEmpty()) { + /*float avg = 0; float max = 0; - for (float v : fbuf) { + for (double v : getData().get(0)) { avg += Math.abs(v); if (v > max) { - max = v; + max = (float) v; } } - avg /= fbuf.length; - volHistory.add((int) (5 * avg)); + avg /= cachedMagnitudes.get(0).length;*/ + System.out.println(getData().get(0).level); + volHistory.add((int) (getData().get(0).level * 100)); + getData().clear(); } if (volHistory.size() > WIDTH) { @@ -41,7 +43,7 @@ public class AudioVolumeEffect extends AudioFFTEffect { for (int x = 0; x < volHistory.size(); x++) { g.setColor(new Color((int) ((Math.abs(volHistory.get(x)) + 1) * ((WIDTH - x) / (float) WIDTH)), 2, 0)); - g.drawRect(WIDTH - x - 1, HEIGHT - volHistory.get(x), 0, HEIGHT); + g.drawRect(x, HEIGHT - volHistory.get(x), 0, HEIGHT); } } diff --git a/src/main/java/de/zuim/ledcontrol/effects/ClockEffect.java b/src/main/java/de/zuim/ledcontrol/effects/ClockEffect.java index 4bfae57..b93ee8e 100644 --- a/src/main/java/de/zuim/ledcontrol/effects/ClockEffect.java +++ b/src/main/java/de/zuim/ledcontrol/effects/ClockEffect.java @@ -9,39 +9,40 @@ import java.util.Date; import static de.zuim.ledcontrol.LEDControl.HEIGHT; public class ClockEffect implements LEDEffect { - private Font font = new Font("Calibri", Font.BOLD, 12*getScale()); - private double posOffset = 0; + private Font font = new Font("crosextra-carlito", Font.BOLD, 10 * getScale()); + private double posOffset = 3; - @Override - public String getDescription() { - return "LED Clock"; - } + @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()); - } - } + int iteration = 0; - public void render(long timeDelta, Graphics g) { - //fontSwitcher(); + 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()); + } + } - 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); + public void render(long timeDelta, Graphics g) { + fontSwitcher(); - 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, HEIGHT/2*getScale()); - g.setColor(new Color(10-date.getSeconds()/6,date.getSeconds()/6,0)); - g.drawString(text2, 2, HEIGHT*getScale()); - if(posOffset<-g.getFontMetrics().stringWidth(text)) - posOffset=0; - } + 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.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, HEIGHT / 2 * getScale()); + g.setColor(new Color(10 - date.getSeconds() / 6, date.getSeconds() / 6, 0)); + g.drawString(text2, 5, HEIGHT * getScale()); + if (posOffset < -g.getFontMetrics().stringWidth(text)) + posOffset = 0; + } } diff --git a/src/main/java/de/zuim/ledcontrol/effects/ColorSweepEffect.java b/src/main/java/de/zuim/ledcontrol/effects/ColorSweepEffect.java index de48bdc..9e34826 100644 --- a/src/main/java/de/zuim/ledcontrol/effects/ColorSweepEffect.java +++ b/src/main/java/de/zuim/ledcontrol/effects/ColorSweepEffect.java @@ -8,19 +8,20 @@ import static de.zuim.ledcontrol.LEDControl.HEIGHT; import static de.zuim.ledcontrol.LEDControl.WIDTH; public class ColorSweepEffect implements LEDEffect { - @Override - public String getDescription() { - return "Solid Color"; - } + @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; + float step = 0; - gr.setColor(Color.getHSBColor(step,1f,15f/255f)); - gr.fillRect(0,0,WIDTH,HEIGHT); - } + @Override + public void render(long timeDelta, Graphics gr) { + step += timeDelta * 0.0000000001d; + if (step > 1) + step = 0; + + gr.setColor(Color.getHSBColor(step, 1f, 5f / 255f)); + gr.fillRect(0, 0, WIDTH, HEIGHT); + } } diff --git a/src/main/java/de/zuim/ledcontrol/effects/NetworkSpeedEffect.java b/src/main/java/de/zuim/ledcontrol/effects/NetworkSpeedEffect.java index 7e84926..c57cf4f 100644 --- a/src/main/java/de/zuim/ledcontrol/effects/NetworkSpeedEffect.java +++ b/src/main/java/de/zuim/ledcontrol/effects/NetworkSpeedEffect.java @@ -13,8 +13,8 @@ import static de.zuim.ledcontrol.LEDControl.WIDTH; public class NetworkSpeedEffect implements LEDEffect { - private static final int MAX_UPLOAD_MBIT_S = 33; - private static final int MAX_DOWNLOAD_MBIT_S = 330; + private static final int MAX_UPLOAD_MBIT_S = 290; + private static final int MAX_DOWNLOAD_MBIT_S = 500; private static final long NANOS_PER_PIXEL = 1000000000; @Override @@ -26,14 +26,14 @@ public class NetworkSpeedEffect implements LEDEffect { @Override public void load() { - if(network == null){ + if (network == null) { SystemInfo si = new SystemInfo(); HardwareAbstractionLayer hal = si.getHardware(); - network = hal.getNetworkIFs().get(0); + network = hal.getNetworkIFs().get(2); } } - private final Font font = new Font("Calibri", Font.BOLD, 9*getScale()); + private final Font font = new Font("crosextra-carlito", Font.BOLD, 7 * getScale()); long lastDownBytes = 0, lastUpBytes = 0; private final List history = new ArrayList<>(); @@ -42,39 +42,39 @@ public class NetworkSpeedEffect implements LEDEffect { @Override public void render(long timeDelta, Graphics g) { - nanosElapsed+=timeDelta; + nanosElapsed += timeDelta; - if(network != null && nanosElapsed > NANOS_PER_PIXEL){ + if (network != null && nanosElapsed > NANOS_PER_PIXEL) { network.updateAttributes(); - double factor_MBit = (8*1000000000.0)/(1000*1000*nanosElapsed); + double factor_MBit = (8 * 1000000000.0) / (1000 * 1000 * nanosElapsed); - double up_speed = ((network.getBytesSent() - lastUpBytes)*(factor_MBit)); - double down_speed = ((network.getBytesRecv() - lastDownBytes)*(factor_MBit)); + double up_speed = ((network.getBytesSent() - lastUpBytes) * (factor_MBit)); + double down_speed = ((network.getBytesRecv() - lastDownBytes) * (factor_MBit)); lastUpBytes = network.getBytesSent(); lastDownBytes = network.getBytesRecv(); - history.add(new Measurement((int) (Math.round((HEIGHT*up_speed) / MAX_UPLOAD_MBIT_S)), (int) (Math.round((HEIGHT*down_speed) / MAX_DOWNLOAD_MBIT_S)))); - if(history.size()>WIDTH){ + history.add(new Measurement((int) (Math.round((HEIGHT * up_speed) / MAX_UPLOAD_MBIT_S)), (int) (Math.round((HEIGHT * down_speed) / MAX_DOWNLOAD_MBIT_S)))); + if (history.size() > WIDTH) { history.remove(0); } - uploadText = Math.round(up_speed)+"↑"; - downloadText = Math.round(down_speed)+"↓"; + uploadText = Math.round(up_speed) + "↑"; + downloadText = Math.round(down_speed) + "↓"; //System.out.println(up_speed+" "+down_speed); nanosElapsed = 0; } - if(history.size() > 1){ + if (history.size() > 1) { g.setFont(font); g.setColor(new Color(1, 0, 0)); - g.drawString(downloadText, WIDTH-g.getFontMetrics().stringWidth(downloadText), HEIGHT*getScale()-3); + g.drawString(downloadText, WIDTH - g.getFontMetrics().stringWidth(downloadText), HEIGHT * getScale() - 3); g.setColor(new Color(0, 1, 0)); - g.drawString(uploadText, WIDTH-g.getFontMetrics().stringWidth(uploadText), HEIGHT/2*getScale()-2); + g.drawString(uploadText, WIDTH - g.getFontMetrics().stringWidth(uploadText), HEIGHT / 2 * getScale() - 2); - for(int x = 0; x < WIDTH && x < history.size(); x++){ + for (int x = 0; x < WIDTH && x < history.size(); x++) { boolean firstUp = history.get(x).upY > history.get(x).downY; drawMeasurement(g, x, firstUp); drawMeasurement(g, x, !firstUp); @@ -82,16 +82,15 @@ public class NetworkSpeedEffect implements LEDEffect { } } - private void drawMeasurement(Graphics g, int x, boolean up){ + private void drawMeasurement(Graphics g, int x, boolean up) { int offset = WIDTH - history.size(); - if(up){ + if (up) { g.setColor(new Color(0, 1, 0)); g.drawLine(x + offset, HEIGHT - history.get(x).upY, x + offset, HEIGHT - 1); g.setColor(new Color(0, 7, 0)); g.drawRect(x + offset, HEIGHT - 1 - history.get(x).upY, 0, 0); //g.drawLine(x + offset, HEIGHT - 1 - history.get(x).upY, x + offset + 1, HEIGHT - 1 - history.get(x+1).upY); - } - else{ + } else { g.setColor(new Color(1, 0, 0)); g.drawLine(x + offset, HEIGHT - history.get(x).downY, x + offset, HEIGHT - 1); g.setColor(new Color(7, 0, 0)); @@ -100,7 +99,7 @@ public class NetworkSpeedEffect implements LEDEffect { } } - static class Measurement{ + static class Measurement { public int upY; public int downY; diff --git a/src/main/java/de/zuim/ledcontrol/effects/SineEffect.java b/src/main/java/de/zuim/ledcontrol/effects/SineEffect.java index 5c88498..ce554f9 100644 --- a/src/main/java/de/zuim/ledcontrol/effects/SineEffect.java +++ b/src/main/java/de/zuim/ledcontrol/effects/SineEffect.java @@ -10,44 +10,45 @@ import static de.zuim.ledcontrol.LEDControl.WIDTH; public class SineEffect implements LEDEffect { - private Random r = new Random(); - private double[][] seeds = new double[10][7]; + private final Random r = new Random(); + private final 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(); - } - } - } + @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) { + double steps = 0; - steps += timeDelta*0.000000001; + @Override + public void render(long timeDelta, Graphics g) { - 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)); - } - } - } + steps += timeDelta * 0.000000001; - 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); - } + 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)); + } + } + } - @Override - public String getDescription() { - return "SineEffect"; - } + 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 int getScale() { - return 1; - } + @Override + public String getDescription() { + return "SineEffect"; + } + + @Override + public int getScale() { + return 1; + } }