This page describes how the LightDJ software works.
The LightDJ software is written in Java, and is divided into three main parts:
1.) Signal processing - looking for useful information in the audio data. For example, trying to detect bass kicks, claps, trying to guess the genre, the mood, the tempo, etc.
2.) Color Algorithms - these are what control all the colored LED's. Generally, these color algorithms take in as input some processed sound data, looks for any patterns/features, and outputs color data accordingly.
3.) Low-level Communication - takes the color data computed by the color algorithms, and is responsible for actually talking to the hardware to blink the lights.
There software supports two types of plugins, and this is where most of the work needs to be done!
1.) FeatureDetectors - do signal processing. Input: A Fast Fourier Transform (FFT), representing the amounts of different frequencies at some particular time in the song. Output: some list of Features, where a feature is a (key, value) pair. The key is a string name, and the value can be any Java type. For example, a Feature might be ("BASS_LEVEL", 1.3) or ("GENRE", "Rock").
2.) Visualizors - figure out what colors to make things. Input: The list of all features made by the FeatureDetectors (aptly called the FeatureList). Output: colors for each of the lights
All of the FeatureDetectors will run in parallel, and all of the Visualizors will run in parallel. The PhotonDJ will mix different Visualizor outputs together, to produce the final colorings that are sent to the lights!
Here's a schematic of this: File:PluginArchitecture.png
Current FeatureDetector keys
- BASS_LEVEL - a double, smoothly estimating the current bass kick level. Smoothed out and cleaned up, varies from 0.0 to 1.0
- CLAP_LEVEL - a double, that stays at a lowish value until a clap/snare/sharp-sounding noise. When this happens, the value spikes. Ranges from 0.0 to 1.0
- FREQ_RANGE_CUSTOM - a double, measuring the amount of a custom frequency range selected by the LightDJ. Varies between 0.0 and 1.0, and is smoothed out.
- OVERALL_LEVEL - a double, trying to measure the overall volume level. Varies from 0.0 to 1.0, except that it really doesn't.
- SILENT - a boolean, that is true if the music is perceived to be silent or not.
This section lists a bunch of important Java classes and gives brief descriptions on what they do. These are generally the classes you'll want to know about when modifying the software.
SoundEngine / VisualizationEngineParty
A very important class. Controls a lot of stuff of stuff, like running the plugin architecture, controlling the GUI, etc.
PartyLightsController / PartyLightsController
Implements the serial package to send data to the lights
FeatureDetectors / (all classes in this package)
The feature detectors that do signal processing to find features of the music
Visualizors / (all classes in this package)
All of the visualizer plugins that do cool stuff with the features detected by the FeatureDetectors
Common / (all classes in this package)
Contain a bunch of classes that are used by other stuff. Useful
Signals / FFTEngine
If your curious, this is the class that implements a heavily optimized, low-latency FFT. Computes using only multiplies/additions with butterfly computations
How to write a new Plugin
This section tells you how to write a new LightDJ Visualizer Plugin! It's actually quite easy.
To get an idea, it's probably easiest to look at some reference implementations of plugins. Check out a simple plugin, such as the WhitePulseBass plugin and read through it. A more complicated one might be the FireSlider plugin, or the FingerPiano - but they're all still pretty easy!
Here are some steps to guide you:
- Create a new class with you plugin's name and put in in the Visualizers package. Make it extend the Visualizer class.
- Implement methods required by the Visualizer plugin. The init() method is where you can initialize stuff you need. This will be automatically called when the LightDJ software starts up. The visualize() function is what actually takes in a list of features (a FeatureList class, which contains a bunch of key value pairs) and outputs a coloring for all the lights. Use the values in the FeatureList to compute a cool-looking pattern, and return it as a ColorOutput. You can use some of the built-in easy ColorOutput methods (like setAllFrontLEDs(color), for example) to help you do this.
- Once you finished writing your plugin, save it, and then look at the allVisualizers() method within the VisualzationEngineParty class. Add a line to the end of the list following the pattern of all the plugins. This will register your new plugin with the LightDJ software.
You're done! Next time you run the code, your Visualizer should automatically start running. It will be automatically assigned a letter based on the order that plugins are registered in the allVisualizers() method.