com.neophob.sematrix.glue.Collector.java Source code

Java tutorial

Introduction

Here is the source code for com.neophob.sematrix.glue.Collector.java

Source

/**
 * Copyright (C) 2011 Michael Vogt <michu@neophob.com>
 *
 * This file is part of PixelController.
 *
 * PixelController 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.
 *
 * PixelController 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 PixelController.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.neophob.sematrix.glue;

import java.net.BindException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang3.StringUtils;

import processing.core.PApplet;
import processing.core.PImage;

import com.neophob.sematrix.color.ColorSet;
import com.neophob.sematrix.effect.PixelControllerEffect;
import com.neophob.sematrix.fader.Fader;
import com.neophob.sematrix.generator.PixelControllerGenerator;
import com.neophob.sematrix.input.Sound;
import com.neophob.sematrix.input.SoundDummy;
import com.neophob.sematrix.input.SoundMinim;
import com.neophob.sematrix.jmx.PixelControllerStatus;
import com.neophob.sematrix.jmx.TimeMeasureItemGlobal;
import com.neophob.sematrix.listener.MessageProcessor;
import com.neophob.sematrix.listener.TcpServer;
import com.neophob.sematrix.mixer.PixelControllerMixer;
import com.neophob.sematrix.output.PixelControllerOutput;
import com.neophob.sematrix.properties.ApplicationConfigurationHelper;
import com.neophob.sematrix.properties.ConfigConstant;
import com.neophob.sematrix.properties.ValidCommands;
import com.neophob.sematrix.resize.PixelControllerResize;

/**
 * The Class Collector.
 */
public final class Collector {

    private static final Logger LOG = Logger.getLogger(Collector.class.getName());

    /** The Constant EMPTY_CHAR. */
    private static final String EMPTY_CHAR = " ";

    /** The Constant NR_OF_PRESENT_SLOTS. */
    public static final int NR_OF_PRESENT_SLOTS = 128;

    /** The singleton instance. */
    private static Collector instance = new Collector();

    /** The random mode. */
    private boolean randomMode = false;

    /** The initialized. */
    private boolean initialized;

    /** The papplet. */
    private PApplet papplet;

    /** The matrix. */
    private MatrixData matrix;

    /** all input elements. */
    private List<Visual> allVisuals;

    /** fx to screen mapping. */
    private List<OutputMapping> ioMapping;

    /** The nr of screens. */
    private int nrOfScreens;

    /** The fps. */
    private int fps;

    /** The frames. */
    private int frames;
    private int framesEffective;

    /** The current visual. */
    private int currentVisual;

    /** The current output. */
    private int currentOutput;

    /** present settings. */
    private int selectedPresent;

    /** The present. */
    private List<PresentSettings> present;

    /** The pixel controller generator. */
    private PixelControllerGenerator pixelControllerGenerator;

    /** The pixel controller mixer. */
    private PixelControllerMixer pixelControllerMixer;

    /** The pixel controller effect. */
    private PixelControllerEffect pixelControllerEffect;

    /** The pixel controller resize. */
    private PixelControllerResize pixelControllerResize;

    /** The pixel controller output. */
    private PixelControllerOutput pixelControllerOutput;

    /** The pixel controller shuffler select. */
    private PixelControllerShufflerSelect pixelControllerShufflerSelect;

    /** The pd srv. */
    @SuppressWarnings("unused")
    private TcpServer pdSrv;

    private ApplicationConfigurationHelper ph;

    /** The is loading present. */
    private boolean isLoadingPresent = false;

    private boolean soundAware = false;

    private PixelControllerStatus pixConStat;

    private List<ColorSet> colorSets;

    private int currentColorSet;

    /** The random mode. */
    private boolean inPauseMode = false;

    /**
     * Instantiates a new collector.
     */
    private Collector() {
        allVisuals = new CopyOnWriteArrayList<Visual>();

        this.nrOfScreens = 0;
        ioMapping = new CopyOnWriteArrayList<OutputMapping>();
        initialized = false;

        selectedPresent = 0;
        present = new CopyOnWriteArrayList<PresentSettings>();
        for (int n = 0; n < NR_OF_PRESENT_SLOTS; n++) {
            present.add(new PresentSettings());
        }

        pixelControllerShufflerSelect = new PixelControllerShufflerSelect();
        pixelControllerShufflerSelect.initAll();
    }

    /**
     * initialize the collector.
     *
     * @param papplet the PApplet
     * @param ph the PropertiesHelper
     */
    public synchronized void init(PApplet papplet, ApplicationConfigurationHelper ph) {
        if (initialized) {
            return;
        }

        this.papplet = papplet;
        this.nrOfScreens = ph.getNrOfScreens();
        this.ph = ph;
        this.fps = ph.parseFps();

        //choose sound implementation
        try {
            Sound.getInstance().setImplementation(new SoundMinim());
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "FAILED TO INITIALIZE SOUND INSTANCE, Exception: {0}.", e);
            Sound.getInstance().setImplementation(new SoundDummy());
        }

        new MatrixData(ph.getDeviceXResolution(), ph.getDeviceYResolution());

        pixelControllerResize = new PixelControllerResize();
        pixelControllerResize.initAll();

        //create generators
        pixelControllerGenerator = new PixelControllerGenerator(ph);
        pixelControllerGenerator.initAll();

        pixelControllerEffect = new PixelControllerEffect();
        pixelControllerEffect.initAll();

        pixelControllerMixer = new PixelControllerMixer();
        pixelControllerMixer.initAll();

        //create visuals
        int additionalVisuals = 1 + ph.getNrOfAdditionalVisuals();
        if (additionalVisuals > 32) {
            //just make sure we don't kill the cpu...
            additionalVisuals = 32;
        }
        Visual.initializeVisuals(nrOfScreens + additionalVisuals);

        pixelControllerOutput = new PixelControllerOutput();
        pixelControllerOutput.initAll();

        ph.loadPresents();
        soundAware = ph.isAudioAware();

        //create an empty mapping
        ioMapping.clear();
        for (int n = 0; n < nrOfScreens; n++) {
            ioMapping.add(new OutputMapping(n));
        }

        //Start tcp server
        int listeningPort = Integer.parseInt(ph.getProperty(ConfigConstant.NET_LISTENING_PORT, "3448"));
        int sendPort = Integer.parseInt(ph.getProperty(ConfigConstant.NET_SEND_PORT, "3449"));
        String listeningIp = ph.getProperty(ConfigConstant.NET_LISTENING_ADDR, "127.0.0.1");

        try {
            pdSrv = new TcpServer(papplet, listeningPort, listeningIp, sendPort);
        } catch (BindException e) {
            LOG.log(Level.SEVERE, "failed to start TCP Server", e);
        } catch (Exception e) {
            LOG.log(Level.SEVERE, "failed to start TCP Server", e);
        }

        pixConStat = new PixelControllerStatus(fps);

        initialized = true;
    }

    /**
     * update the whole system:
     * -generators
     * -effects
     * -outputs
     * 
     * update the generators, if the sound is
     * louder, update faster.
     */
    public void updateSystem() {
        //do not update system if presents are loading
        if (isLoadingPresent()) {
            return;
        }

        int u = 1;

        if (soundAware) {
            //get sound volume
            float f = Sound.getInstance().getVolumeNormalized();
            u = (int) (0.5f + f * 1.5f);
            //check for silence - in this case update slowly
            if (u < 1) {
                if (frames % 3 == 1) {
                    u = 1;
                }
            }
            if (Sound.getInstance().isKick()) {
                u += 3;
            }
            if (Sound.getInstance().isHat()) {
                u += 1;
            }
        }

        //update the current value of frames per second
        pixConStat.setCurrentFps(papplet.frameRate);
        pixConStat.setFrameCount(papplet.frameCount);

        framesEffective += u;
        long l = System.currentTimeMillis();
        //update generator depending on the input sound
        for (int i = 0; i < u; i++) {
            pixelControllerGenerator.update();
        }
        pixConStat.trackTime(TimeMeasureItemGlobal.GENERATOR, System.currentTimeMillis() - l);

        l = System.currentTimeMillis();
        pixelControllerEffect.update();
        pixConStat.trackTime(TimeMeasureItemGlobal.EFFECT, System.currentTimeMillis() - l);

        l = System.currentTimeMillis();
        pixelControllerOutput.update();
        pixConStat.trackTime(TimeMeasureItemGlobal.OUTPUT_SCHEDULE, System.currentTimeMillis() - l);

        //cleanup faders
        l = System.currentTimeMillis();
        for (OutputMapping om : ioMapping) {
            Fader fader = om.getFader();
            if (fader.isDone()) {
                //fading is finished
                fader.cleanUp();
            }
        }
        pixConStat.trackTime(TimeMeasureItemGlobal.FADER, System.currentTimeMillis() - l);

        if (randomMode) {
            Shuffler.shuffleStuff();
        }

        frames++;
    }

    /**
     * Gets the single instance of Collector.
     *
     * @return single instance of Collector
     */
    public static Collector getInstance() {
        return instance;
    }

    /**
     * Gets the nr of screens.
     *
     * @return the nr of screens
     */
    public int getNrOfScreens() {
        return nrOfScreens;
    }

    /**
     * create screenshot
     */
    public void saveScreenshot() {
        int ofs = 0;
        String suffix = frames + ".png";
        for (Visual v : allVisuals) {
            String prefix = "screenshot/" + ofs;
            PImage p = v.getGeneratorAsImage(0);
            p.save(prefix + "-gen1-" + suffix);
            p = v.getGeneratorAsImage(1);
            p.save(prefix + "-gen2-" + suffix);
            p = v.getEffectAsImage(0);
            p.save(prefix + "-fx1-" + suffix);
            p = v.getEffectAsImage(1);
            p.save(prefix + "-fx2-" + suffix);
            p = v.getMixerAsImage();
            p.save(prefix + "-mix-" + suffix);
            ofs++;
        }
    }

    /**
     * which fx for screenOutput?.
     *
     * @param screenOutput the screen output
     * @return fx nr.
     */
    public int getFxInputForScreen(int screenOutput) {
        return ioMapping.get(screenOutput).getVisualId();
    }

    /**
     * define which fx is shown on which screen, without fading.
     *
     * @param screenOutput which screen nr
     * @param visualInput which visual
     */
    public void mapInputToScreen(int screenOutput, int visualInput) {
        OutputMapping o = ioMapping.get(screenOutput);
        o.setVisualId(visualInput);
        ioMapping.set(screenOutput, o);
    }

    /**
     * get all screens with a specific visual
     * used for crossfading.
     *
     * @param oldVisual the old visual
     * @return the all screens with visual
     */
    public List<Integer> getAllScreensWithVisual(int oldVisual) {
        List<Integer> ret = new ArrayList<Integer>();
        int ofs = 0;
        for (OutputMapping o : ioMapping) {
            if (o.getVisualId() == oldVisual) {
                ret.add(ofs);
            }
            ofs++;
        }
        return ret;
    }

    /**
     * Gets the papplet.
     *
     * @return the papplet
     */
    public PApplet getPapplet() {
        return papplet;
    }

    /**
     * Gets the fps.
     *
     * @return the fps
     */
    public int getFps() {
        return fps;
    }

    /**
     * Checks if is random mode.
     *
     * @return true, if is random mode
     */
    public boolean isRandomMode() {
        return randomMode;
    }

    /**
     * Sets the random mode.
     *
     * @param randomMode the new random mode
     */
    public void setRandomMode(boolean randomMode) {
        this.randomMode = randomMode;
    }

    /**
     * load a saved preset.
     *
     * @param preset the new current status
     */
    public void setCurrentStatus(List<String> preset) {
        setLoadingPresent(true);
        for (String s : preset) {
            s = StringUtils.trim(s);
            s = StringUtils.removeEnd(s, ";");
            MessageProcessor.processMsg(StringUtils.split(s, ' '), false);
        }
        setLoadingPresent(false);
    }

    /**
     * update the visual setting in the gui.
     *
     * @return the current mini status
     */
    public List<String> getCurrentMiniStatus() {
        List<String> ret = new ArrayList<String>();

        //get visual status
        int n = 0;
        for (Visual v : allVisuals) {
            ret.add(ValidCommands.CURRENT_VISUAL + EMPTY_CHAR + n++);
            ret.add(ValidCommands.CHANGE_GENERATOR_A + EMPTY_CHAR + v.getGenerator1Idx());
            ret.add(ValidCommands.CHANGE_GENERATOR_B + EMPTY_CHAR + v.getGenerator2Idx());
            ret.add(ValidCommands.CHANGE_EFFECT_A + EMPTY_CHAR + v.getEffect1Idx());
            ret.add(ValidCommands.CHANGE_EFFECT_B + EMPTY_CHAR + v.getEffect2Idx());
            ret.add(ValidCommands.CHANGE_MIXER + EMPTY_CHAR + v.getMixerIdx());
        }

        //get output status
        for (OutputMapping om : ioMapping) {
            ret.add(ValidCommands.CURRENT_OUTPUT + EMPTY_CHAR + om.getVisualId());
            ret.add(ValidCommands.CHANGE_OUTPUT_FADER + EMPTY_CHAR + om.getFader().getId());
            ret.add(ValidCommands.CHANGE_OUTPUT_VISUAL + EMPTY_CHAR + om.getVisualId());
        }

        return ret;
    }

    /**
     * get current state of visuals/outputs
     * as string list - used to save current settings.
     *
     * @return the current status
     */
    public List<String> getCurrentStatus() {
        List<String> ret = this.getCurrentMiniStatus();

        //add element status
        ret.addAll(pixelControllerEffect.getCurrentState());
        ret.addAll(pixelControllerGenerator.getCurrentState());
        ret.addAll(pixelControllerShufflerSelect.getCurrentState());

        ret.add(ValidCommands.CHANGE_PRESENT + EMPTY_CHAR + selectedPresent);
        ret.add(ValidCommands.CURRENT_COLORSET + EMPTY_CHAR + currentColorSet);
        return ret;
    }

    /*
     * MATRIX ======================================================
     */

    /**
     * Gets the matrix.
     *
     * @return the matrix
     */
    public MatrixData getMatrix() {
        return matrix;
    }

    /**
     * Sets the matrix.
     *
     * @param matrix the new matrix
     */
    public void setMatrix(MatrixData matrix) {
        this.matrix = matrix;
    }

    /*
     * VISUAL ======================================================
     */

    /**
     * Adds the visual.
     *
     * @param visual the visual
     */
    public void addVisual(Visual visual) {
        allVisuals.add(visual);
    }

    /**
     * Gets the all visuals.
     *
     * @return the all visuals
     */
    public List<Visual> getAllVisuals() {
        return allVisuals;
    }

    /**
     * Gets the visual.
     *
     * @param index the index
     * @return the visual
     */
    public Visual getVisual(int index) {
        if (index >= 0 && index < allVisuals.size()) {
            return allVisuals.get(index);
        }
        return allVisuals.get(0);
    }

    /**
     * Sets the all visuals.
     *
     * @param allVisuals the new all visuals
     */
    public void setAllVisuals(List<Visual> allVisuals) {
        this.allVisuals = allVisuals;
    }

    /* 
     * PRESENT ======================================================
     */

    /**
     * Gets the selected present.
     *
     * @return the selected present
     */
    public int getSelectedPresent() {
        return selectedPresent;
    }

    /**
     * Sets the selected present.
     *
     * @param selectedPresent the new selected present
     */
    public void setSelectedPresent(int selectedPresent) {
        this.selectedPresent = selectedPresent;
    }

    /**
     * Gets the present.
     *
     * @return the present
     */
    public List<PresentSettings> getPresent() {
        return present;
    }

    /**
     * Sets the present.
     *
     * @param present the new present
     */
    public void setPresent(List<PresentSettings> present) {
        this.present = present;
    }

    /*
     * OUTPUT MAPPING ======================================================
     */

    /**
     * Gets the all output mappings.
     *
     * @return the all output mappings
     */
    public List<OutputMapping> getAllOutputMappings() {
        return ioMapping;
    }

    /**
     * Gets the output mappings.
     *
     * @param index the index
     * @return the output mappings
     */
    public OutputMapping getOutputMappings(int index) {
        return ioMapping.get(index);
    }

    /**
     * Gets the current visual.
     *
     * @return the current visual
     */
    public int getCurrentVisual() {
        return currentVisual;
    }

    /**
     * Sets the current visual.
     *
     * @param currentVisual the new current visual
     */
    public void setCurrentVisual(int currentVisual) {
        if (currentVisual < allVisuals.size()) {
            this.currentVisual = currentVisual;
        }
    }

    /**
     * 
     * @return
     */
    public int getCurrentOutput() {
        return currentOutput;
    }

    /**
     * 
     * @param currentOutput
     */
    public void setCurrentOutput(int currentOutput) {
        if (currentOutput < ioMapping.size()) {
            this.currentOutput = currentOutput;
        }
    }

    /**
     * Checks if is loading present.
     *
     * @return true, if is loading present
     */
    public synchronized boolean isLoadingPresent() {
        return isLoadingPresent;
    }

    /**
     * Sets the loading present.
     *
     * @param isLoadingPresent the new loading present
     */
    public synchronized void setLoadingPresent(boolean isLoadingPresent) {
        this.isLoadingPresent = isLoadingPresent;
    }

    /**
     * Gets the shuffler select.
     *
     * @param ofs the ofs
     * @return the shuffler select
     */
    public boolean getShufflerSelect(ShufflerOffset ofs) {
        return pixelControllerShufflerSelect.getShufflerSelect(ofs);
    }

    /**
     * Gets the pixel controller shuffler select.
     *
     * @return the pixel controller shuffler select
     */
    public PixelControllerShufflerSelect getPixelControllerShufflerSelect() {
        return pixelControllerShufflerSelect;
    }

    /**
     * Gets the pixel controller mixer.
     *
     * @return the pixel controller mixer
     */

    public PixelControllerMixer getPixelControllerMixer() {
        return pixelControllerMixer;
    }

    /**
     * Gets the pixel controller effect.
     *
     * @return the pixel controller effect
     */
    public PixelControllerEffect getPixelControllerEffect() {
        return pixelControllerEffect;
    }

    /**
     * Gets the pixel controller generator.
     *
     * @return the pixel controller generator
     */
    public PixelControllerGenerator getPixelControllerGenerator() {
        return pixelControllerGenerator;
    }

    /**
     * Gets the pixel controller resize.
     *
     * @return the pixel controller resize
     */
    public PixelControllerResize getPixelControllerResize() {
        return pixelControllerResize;
    }

    /**
     * Gets the pixel controller output.
     *
     * @return the pixel controller output
     */
    public PixelControllerOutput getPixelControllerOutput() {
        return pixelControllerOutput;
    }

    /**
     * @return the ph
     */
    public ApplicationConfigurationHelper getPh() {
        return ph;
    }

    /**
     * 
     * @return
     */
    public int getFrames() {
        return framesEffective;
    }

    /**
     * 
     * @return
     */
    public PixelControllerStatus getPixConStat() {
        return pixConStat;
    }

    public List<ColorSet> getColorSets() {
        return colorSets;
    }

    public void setColorSets(List<ColorSet> colorSets) {
        this.colorSets = colorSets;
    }

    /**
     * @return the currentColorSet
     */
    public int getCurrentColorSet() {
        return currentColorSet;
    }

    public ColorSet getActiveColorSet() {
        return this.colorSets.get(currentColorSet);
    }

    /**
     * @param currentColorSet the currentColorSet to set
     */
    public void setCurrentColorSet(int currentColorSet) {
        this.currentColorSet = currentColorSet;
    }

    public void togglePauseMode() {
        if (inPauseMode) {
            inPauseMode = false;
        } else {
            inPauseMode = true;
        }
    }

    public boolean isInPauseMode() {
        return inPauseMode;
    }

}