/* * Copyright (C) 2012 Gyver * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.gyver.matrixmover.generator; import com.gyver.matrixmover.core.Controller; import com.gyver.matrixmover.core.MatrixData; import com.gyver.matrixmover.generator.enums.AnalyserDirection; import com.gyver.matrixmover.generator.enums.GeneratorName; import java.awt.Color; import java.util.concurrent.CopyOnWriteArrayList; /** * * @author Gyver */ public class Analyser extends ColorMapAwareGenerator { private AnalyserDirection analyserDirection = null; private float[] decayedSpectrum = null; private float gain = 1F; /** * Instantiates a new null generator. * * @param matrix the MatrixData of the matrix. */ public Analyser(MatrixData matrix) { super(GeneratorName.ANALYSER, matrix, null); // set default color CopyOnWriteArrayList<Color> defaultColorMap = new CopyOnWriteArrayList<Color>(); defaultColorMap.add(new Color(0, 0, 255)); defaultColorMap.add(new Color(255, 0, 0)); this.setColorMap(defaultColorMap); analyserDirection = AnalyserDirection.LEFT_TO_RIGHT; } @Override public void update() { switch (getAnalyserDirection()) { case LEFT_TO_RIGHT: leftToRight(); break; case RIGHT_TO_LEFT: rightToLeft(); break; case TOP_TO_BOTTOM: topDown(); break; case BOTTOM_TO_TOP: bottomUp(); break; } } @Override public void init() { // do nothing } private void leftToRight(){ int bands = internalBufferHeight; float[] spectrum = Controller.getControllerInstance().getSpectrum(bands); if(spectrum == null){ return; } if (decayedSpectrum == null || decayedSpectrum.length != bands) { decayedSpectrum = new float[bands]; } for (int i = 0; i < bands; i++) { spectrum[i] *= internalBufferWidth * gain; if (spectrum[i] >= decayedSpectrum[i]) { decayedSpectrum[i] = spectrum[i]; } else { decayedSpectrum[i] -= 0.5F; if (spectrum[i] >= decayedSpectrum[i]) { decayedSpectrum[i] = spectrum[i]; } } } for (int i = 0; i < this.internalBufferWidth; i++) { for (int j = 0; j < this.internalBufferHeight; j++) { if (decayedSpectrum[j] > i) { float rawColor = i / (float) Math.floor(decayedSpectrum[j]) * (colorMap.size()-1); int thisColor = (int) Math.floor(rawColor); int nextColor = (thisColor+1) % colorMap.size(); float ratio = rawColor - (float) thisColor; internalBuffer[i + (j * internalBufferWidth)] = getColor(thisColor, nextColor, ratio); } else { internalBuffer[i + (j * internalBufferWidth)] = 0x000000; } } } } private void rightToLeft(){ int bands = internalBufferHeight; float[] spectrum = Controller.getControllerInstance().getSpectrum(bands); if(spectrum == null){ return; } if (decayedSpectrum == null || decayedSpectrum.length != bands) { decayedSpectrum = new float[bands]; } for (int i = 0; i < bands; i++) { spectrum[i] *= internalBufferWidth * gain; if (spectrum[i] >= decayedSpectrum[i]) { decayedSpectrum[i] = spectrum[i]; } else { decayedSpectrum[i] -= 0.5F; if (spectrum[i] >= decayedSpectrum[i]) { decayedSpectrum[i] = spectrum[i]; } } } for (int i = 0; i < this.internalBufferWidth; i++) { for (int j = 0; j < this.internalBufferHeight; j++) { if (decayedSpectrum[j] > i) { float rawColor = i / (float) Math.floor(decayedSpectrum[j]) * (colorMap.size()-1); int thisColor = (int) Math.floor(rawColor); int nextColor = (thisColor+1) % colorMap.size(); float ratio = rawColor - (float) thisColor; internalBuffer[(internalBufferWidth - 1 - i) + (j * internalBufferWidth)] = getColor(thisColor, nextColor, ratio); } else { internalBuffer[(internalBufferWidth - 1 - i) + (j * internalBufferWidth)] = 0x000000; } } } } private void topDown(){ int bands = internalBufferWidth; float[] spectrum = Controller.getControllerInstance().getSpectrum(bands); if(spectrum == null){ return; } if (decayedSpectrum == null || decayedSpectrum.length != bands) { decayedSpectrum = new float[bands]; } for (int i = 0; i < bands; i++) { spectrum[i] *= internalBufferHeight * gain; if (spectrum[i] >= decayedSpectrum[i]) { decayedSpectrum[i] = spectrum[i]; } else { decayedSpectrum[i] -= 0.5F; if (spectrum[i] >= decayedSpectrum[i]) { decayedSpectrum[i] = spectrum[i]; } } } for (int i = 0; i < this.internalBufferWidth; i++) { for (int j = 0; j < this.internalBufferHeight; j++) { if (decayedSpectrum[i] > j) { float rawColor = j / (float) Math.floor(decayedSpectrum[i]) * (colorMap.size()-1); int thisColor = (int) Math.floor(rawColor); int nextColor = (thisColor+1) % colorMap.size(); float ratio = rawColor - (float) thisColor; internalBuffer[i + (j * internalBufferWidth)] = getColor(thisColor, nextColor, ratio); } else { internalBuffer[i + (j * internalBufferWidth)] = 0x000000; } } } } private void bottomUp(){ int bands = internalBufferWidth; float[] spectrum = Controller.getControllerInstance().getSpectrum(bands); if(spectrum == null){ return; } if (decayedSpectrum == null || decayedSpectrum.length != bands) { decayedSpectrum = new float[bands]; } for (int i = 0; i < bands; i++) { spectrum[i] *= internalBufferHeight * gain; if (spectrum[i] >= decayedSpectrum[i]) { decayedSpectrum[i] = spectrum[i]; } else { decayedSpectrum[i] -= 0.5F; if (spectrum[i] >= decayedSpectrum[i]) { decayedSpectrum[i] = spectrum[i]; } } } for (int i = 0; i < this.internalBufferWidth; i++) { for (int j = 0; j < this.internalBufferHeight; j++) { if (decayedSpectrum[i] > j) { float rawColor = j / (float) Math.floor(decayedSpectrum[i]) * (colorMap.size()-1); int thisColor = (int) Math.floor(rawColor); int nextColor = (thisColor+1) % colorMap.size(); float ratio = rawColor - (float) thisColor; internalBuffer[i + ((internalBufferHeight - 1 - j) * internalBufferWidth)] = getColor(thisColor, nextColor, ratio); } else { internalBuffer[i + ((internalBufferHeight - 1 - j) * internalBufferWidth)] = 0x000000; } } } } /** * @return the gain */ public int getGain() { return (int) (gain * 100F); } /** * @param gain the gain to set */ public void setGain(int gain) { this.gain = (gain / 100F); } /** * @return the analyserDirection */ public AnalyserDirection getAnalyserDirection() { return analyserDirection; } /** * @param analyserDirection the analyserDirection to set */ public void setAnalyserDirection(AnalyserDirection analyserDirection) { this.analyserDirection = analyserDirection; } }