# Music Visualizer — `music-visualizer@1.0.0`

A round equaliser: two rings of glowing bars around a pulsing orb, kicking on every beat, with a ring of light running out across the floor. Loops perfectly.

A round equaliser. Two rings of glowing bars stand round a pulsing orb: the low notes at the top and bottom of the rings and the high notes at the sides, so the picture is a mirror image like a real spectrum drawn round a circle. A kick on every beat throws the bass bars up, snares and melody lines ripple through the rest, and a ring of light leaves the orb on each beat and runs out across the floor. There is no audio: the spectrum is a formula of the beat. Choose the number of bars, the colours (rainbow, neon, fire or mono), the beats per loop, how hard the bass kicks and whether the camera circles.

- Kind: object; status: published; digest sha256:fa63cba4b9783f8fa72fb98ddae8c7ac88a781f12032b187982a692c37ea0389
- Role: Object (3D, three.js): an audio-style visual for music, podcast and event content that needs no audio file.
- Implementation: three; entry `src/music-visualizer.js`
- Files: https://aipixelwizard.com/registry/music-visualizer/1.0.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/music-visualizer.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/music-visualizer/versions/1.0.0
- Runnable demo: https://aipixelwizard.com/registry/music-visualizer/1.0.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `three@0.185.1` (source) — Renderer, geometry and basic materials.; `apw-runtime@1.0.0` (demo) — Demo harness.

## Exports
- `createEqualiser({ bars?, palette?, beats?, punch? }) => { group, setProgress(progress), dispose() }` — The two rings of bars, the orb, the halo and the floor, about 11 across, resting on y = 0; render through createBloomPass.
- `createBloomPass(renderer, { width, height, glow?, exposure?, grain? }) => { render(scene, camera, output?), dispose() }` — A small bloom with an anti-aliased, depth-tested scene target.
- `PALETTES: { rainbow, neon, fire, mono }` — Colour schemes round the rings.

## Parameters
- `bars` (integer 24–120, default 64) — Bars per ring
- `palette` (select one of rainbow | neon | fire | mono, default "rainbow") — Colours
- `beats` (integer 4–16, default 8) — Beats per loop
- `punch` (number 0.4–1.8, default 1) — Bass punch
- `orbit` (boolean, default true) — Camera circles

## Composition
- Inputs: Time within the loop; the bars, colours, beats, punch and camera.
- Outputs: A full frame rendered in 3D through an anti-aliased bloom.
- Coordinates: The rings of radius 3.0 and 4.2 are centred on the origin on y = 0; the orb floats at y = 1.2; the camera looks down at about 36°.
- Lighting: Self-lit bars and orb; the bloom gives the glow.
- Timing: setProgress(progress) sets every bar's height from the beat; frames render in any order.
- Works with: kinetic-title, number-reveal
- Two instanced bar sets with instance colours; the spectrum is mirrored left-right by taking the cosine of the angle.

## Output and loop
- 1080×1080, 30 fps, 16 s, procedural
- Seamless loop: yes — The kick, the snare and the melody lines are functions of the beat with whole numbers of beats and cycles per loop, and the camera makes one full circle per loop, so the last frame meets the first.
- Verified 2026-10-05 in Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0 (WebGL 2 via SwiftShader (software)); deterministic: yes; loop check: Frame 0 vs end state (progress 1): mean |Δ| 0.0000, max |Δ| 0 of 255.

## Use it
New project: Create a WebGLRenderer, createEqualiser() and createBloomPass(renderer, { width, height }); each frame call eq.setProgress(progress) and bloom.render(scene, camera).

Existing project: Copy src/music-visualizer.js; add eq.group to your scene and render it through createBloomPass.

Reuse ideas:
- Podcast or radio: Rainbow, eight beats.
- Club: Neon, fast.
- Hard hitting: Fire, heavy bass.

## Limitations
- The spectrum is a formula, not driven by audio: to react to real sound feed the bar heights from an analyser.
- Neighbouring bars touch at the highest bar counts.

## License
MIT. Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.

Provenance: Adapted from the owner's threejs-sketches/data-information/music-visualizer (MIT) and rebuilt for AI Pixel Wizard in October 2026 as an original scene: a formula-driven radial spectrum with kick and snare envelopes, a pulsing orb and an expanding ring of light, through a bloom, on an exact loop.

