For Visual Artists
What You Receive
When you connect to this system, you receive a stream of values that describe what the music is doing right now. You do not receive raw audio data, frequency bins, or FFT buffers. You receive meaningful descriptions of the music expressed as simple values.
Here is everything the system sends you:
story.name String or null.
The name of the current moment:
"groove", "escalation", "breakdown", "drop", etc.
null when the kick is absent and no story applies.
story.phase String.
Where we are in this story's lifecycle:
"entering", "sustaining", or "transitioning"
story.duration Number (bars).
How many bars we have been in this story.
foundation.weight Float (0.0 – 1.0).
How heavy the kick feels.
0.0 = barely there. 1.0 = floor-shaking.
Updates every frame. Smooth, no jitter.
foundation.presence Float (0.0 – 1.0).
How clearly the kick cuts through the mix.
1.0 = crystal clear. 0.0 = gone.
Updates every frame. Smooth, no jitter.
foundation.sustain String: "dry", "mid", or "wet".
How the kick decays after impact.
Changes infrequently (every few bars at most).
variance.direction String: "rising", "stable", or "falling".
Is the energy around the kick going up,
staying the same, or coming down?
Changes infrequently (confirmed over 2+ bars).
variance.magnitude Float (0.0 – 1.0).
How fast or dramatically things are shifting.
0.0 = nothing changing. 1.0 = dramatic shift.
Updates every frame. Smooth.
That’s it. Nine values. Everything you need to create visuals that respond meaningfully to live techno music.
What You Don’t Need to Know
You do not need to understand any of the following to use this system:
- What an FFT is or how beat detection works
- What frequency bins are or what Hz means
- How Pro DJ Link communicates BPM data
- What temporal thresholds are or how debouncing works
- How the kick is isolated from the rest of the signal
- What spectral brightness or onset density means
All of that is handled by the engineering layer beneath this model. By the time the data reaches you, it has already been analyzed, interpreted, smoothed, and confirmed. You receive meaning, not data.
Two Types of Values
The nine values fall into two categories, and understanding this distinction will help you use them effectively.
Continuous Values (drive smooth visuals)
These update every frame. They move gradually and smoothly. Use them for things that should change fluidly — size, opacity, color intensity, blur, speed.
foundation.weight → size, intensity, scale
foundation.presence → opacity, sharpness, saturation
variance.magnitude → speed, complexity, particle count
These values are your primary visual drivers. They are always available, always smooth, and always responsive to the music.
State Values (drive structural changes)
These change infrequently — every few bars, sometimes every few minutes. When they change, it means something significant has happened in the music. Use them for things that should change discretely — color palette, geometry type, scene selection, transition effects.
story.name → which visual scene / palette / mode
story.phase → whether to be transitioning between scenes
foundation.sustain → the "texture" or "feel" of the visual
variance.direction → whether visuals should be intensifying, steady, or calming
Example Mappings
Basic: Weight Drives Everything
The simplest possible mapping. Weight alone can create responsive, meaningful visuals.
// The kick IS the visual
shape.size = foundation.weight * maxSize
shape.brightness = foundation.weight * maxBrightness
shape.speed = foundation.weight * maxSpeed
// When the kick is heavy, everything is big and bright.
// When the kick is light, everything is small and dim.
// When the kick disappears, presence drops to 0 and
// you can fade everything out.
Intermediate: Weight + Presence + Story
Adding Presence and Story creates more nuanced, structural responses.
// Weight drives size
shape.size = foundation.weight * maxSize
// Presence drives clarity
shape.opacity = foundation.presence
shape.blur = (1.0 - foundation.presence) * maxBlur
shape.sharpness = foundation.presence
// Story drives the scene
if (story.name == "groove") { palette = warm; geometry = solid }
if (story.name == "escalation") { palette = hot; geometry = expanding }
if (story.name == "breakdown") { palette = cool; geometry = dissolving }
if (story.name == "drop") { palette = flash; geometry = explosive }
// Story phase drives transitions
if (story.phase == "transitioning") {
crossfade(currentScene, nextScene, transitionSpeed)
}
Advanced: Full Model
Using all nine values for maximum expressiveness.
// Foundation drives the core visual
shape.size = foundation.weight * maxSize
shape.opacity = foundation.presence
shape.blur = (1.0 - foundation.presence) * maxBlur
// Sustain drives visual texture
if (foundation.sustain == "dry") {
shape.edges = sharp
shape.decay = instant // visuals snap on/off with the beat
shape.style = geometric
}
if (foundation.sustain == "mid") {
shape.edges = smooth
shape.decay = natural // visuals fade naturally between beats
shape.style = organic
}
if (foundation.sustain == "wet") {
shape.edges = blurred
shape.decay = trailing // visuals linger, blend, overlap
shape.style = atmospheric
}
// Variance drives energy and movement
if (variance.direction == "rising") {
movement.speed = baseSpeed * (1.0 + variance.magnitude)
particles.count = baseCount * (1.0 + variance.magnitude * 2)
color.temperature = shifting_warmer
}
if (variance.direction == "stable") {
movement.speed = baseSpeed
particles.count = baseCount
color.temperature = neutral
}
if (variance.direction == "falling") {
movement.speed = baseSpeed * (1.0 - variance.magnitude * 0.5)
particles.count = baseCount * (1.0 - variance.magnitude)
color.temperature = shifting_cooler
}
// Story drives the scene and transitions
scene.current = mapStoryToScene(story.name)
if (story.phase == "transitioning") {
beginSceneTransition()
}
Handling Null Story
When story.name is null, the kick is absent and the model has nothing to say about the music. This happens during breakdowns, between tracks, or during ambient sections.
Your visual system needs a strategy for this. Some options:
Option 1: Fade to minimal state
When story.name becomes null, gradually reduce all visual output
to a dim, ambient baseline. Resume when story returns.
Option 2: Hold the last state
Freeze the visual at its current state when story becomes null.
Let it sit there as a static image until the music returns.
Option 3: Freeform mode
When story.name is null, switch to a generative/autonomous visual
mode that doesn't depend on the kick. Run procedural animations,
slow drifts, ambient patterns. Return to music-driven mode when
story resumes.
Option 4: Use presence as the guide
Even when story is null, foundation.presence is still updating.
If presence is 0.0, the kick is truly gone. If presence is 0.3,
there might be ghost kicks or residual energy. Use this continuous
value to scale your ambient state.
Tips
Start with weight. Before you map anything else, get weight driving a single visual parameter (size or brightness). If that feels good and responsive, add more mappings. If it doesn’t, no amount of additional complexity will fix it.
Don’t map everything to everything. Nine inputs mapped to twenty visual parameters creates visual noise. Pick 3-4 strong mappings and let the rest be implicit or secondary.
Sustain is your texture knob. DRY sustain should make your visuals feel mechanical and precise. WET sustain should make them feel dreamy and flowing. MID is the baseline. If your visuals feel the same regardless of sustain, you’re missing an opportunity.
Story phase is your transition cue. When story.phase changes to “transitioning,” something is about to change. Use this to begin visual transitions before the new story arrives. The audience will feel the visual shift anticipating the musical shift — which is exactly how good VJ work feels.
Variance magnitude is your “something is happening” signal. Even without looking at direction, if magnitude is high, the music is in motion. If magnitude is low, it’s locked in. Use this for particle counts, movement speed, visual complexity — anything that should increase when the music is active.
Related Pages
- Story — what story names mean and how they work
- Weight — deep dive on the primary visual driver
- Presence — deep dive on kick clarity
- Sustain — deep dive on kick decay character
- Variance — deep dive on energy direction and magnitude