audio-reactive
Skill9 starsChanged 6 months agoMITView on GitHub
Binding audio analysis data to visual parameters including smoothing, beat detection responses, and frequency-to-visual mappings. Use when creating audio visualizers, music-reactive animations, or any visual effect driven by audio input.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- soilmass/motion-design-agenttheir own version, first seen Nov 8, 2026
Other versions2 projects use a version of this.
Word for word · 1
- belentani7/manus-ai-skill-pack★ 0100% same
Edited · 0
None found.
Wrote their own version · 1
- soilmass/motion-design-agent★ 7same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository77 other files it gives its agents.
- building-mechanicsSkill
- algorithmic-artSkill
- audio-analysisSkill
- audio-playbackSkill
- audio-routerSkill
- aws-skillsSkill
- backend-dev-guidelinesSkill
- brainstormingSkill
- brand-guidelinesSkill
- builder-uxSkill
- building-routerSkill
- canvas-designSkill
- case-studies-referenceSkill
- component-librarySkill
- d3js-visualizationSkill
- dashboardSkill
- decay-upkeepSkill
- doc-coauthoringSkill
- docxSkill
- form-accessibilitySkill
- form-reactSkill
- form-securitySkill
- forms-routerSkill
- form-ux-patternsSkill
- form-validationSkill
- form-vanillaSkill
- form-vueSkill
- frontend-designSkill
- frontend-dev-guidelinesSkill
- gsap-fundamentalsSkill
- gsap-reactSkill
- gsap-routerSkill
- gsap-scrolltriggerSkill
- gsap-sequencingSkill
- immersive-visuals-routerSkill
- internal-commsSkill
- mcp-builderSkill
- multiplayer-buildingSkill
- particles-gpuSkill
- particles-lifecycleSkill
- particles-physicsSkill
- particles-routerSkill
- pdfSkill
- performance-at-scaleSkill
- platform-buildingSkill
- postfx-bloomSkill
- postfx-composerSkill
- postfx-effectsSkill
- postfx-routerSkill
- pptxSkill
- product-self-knowledgeSkill
- r3f-dreiSkill
- r3f-fundamentalsSkill
- r3f-geometrySkill
- r3f-materialsSkill
- r3f-performanceSkill
- r3f-routerSkill
- router-templateSkill
- scientific-documentationSkill
- shader-effectsSkill
- The first 60 shown.
The file
Files
Audio Reactive Visuals
Connecting audio analysis to visual parameters.
Quick Start
import * as Tone from 'tone';
const analyser = new Tone.Analyser('fft', 256);
const player = new Tone.Player('/audio/music.mp3');
player.connect(analyser);
player.toDestination();
function animate() {
const fft = analyser.getValue();
const bass = (fft[2] + 100) / 100; // Normalize to 0-1
// Apply to visual
element.style.transform = `scale(${1 + bass * 0.2})`;
requestAnimationFrame(animate);
}Core Patterns
Audio-to-Visual Mapping
class AudioReactiveMapper {
constructor(analyser) {
this.analyser = analyser;
this.smoothers = {
bass: new Smoother(0.85),
mid: new Smoother(0.9),
high: new Smoother(0.92)
};
}
// Get values optimized for different visual properties
getValues() {
const fft = this.analyser.getValue();
const len = fft.length;
// Extract and normalize bands
const rawBass = this.avgRange(fft, 0, len * 0.1);
const rawMid = this.avgRange(fft, len * 0.1, len * 0.5);
const rawHigh = this.avgRange(fft, len * 0.5, len);
return {
bass: this.smoothers.bass.update(this.normalize(rawBass)),
mid: this.smoothers.mid.update(this.normalize(rawMid)),
high: this.smoothers.high.update(this.normalize(rawHigh))
};
}
avgRange(data, start, end) {
let sum = 0;
for (let i = Math.floor(start); i < Math.floor(end); i++) {
sum += data[i];
}
return sum / (end - start);
}
normalize(db) {
return Math.max(0, Math.min(1, (db + 100) / 100));
}
}
class Smoother {
constructor(factor = 0.9) {
this.factor = factor;
this.value = 0;
}
update(input) {
this.value = this.factor * this.value + (1 - this.factor) * input;
return this.value;
}
}Visual Property Mappings
Scale/Size
// Pulse on bass
function updateScale(element, bass) {
const scale = 1 + bass * 0.3; // 1.0 to 1.3
element.style.transform = `scale(${scale})`;
}
// Three.js mesh
function updateMeshScale(mesh, bass) {
const scale = 1 + bass * 0.5;
mesh.scale.setScalar(scale);
}Position/Movement
// Vibration based on high frequencies
function updatePosition(element, high) {
const shake = high * 5; // Pixels
const x = (Math.random() - 0.5) * shake;
const y = (Math.random() - 0.5) * shake;
element.style.transform = `translate(${x}px, ${y}px)`;
}
// Smooth wave motion
function updateWavePosition(mesh, mid, time) {
mesh.position.y = Math.sin(time * 2) * mid * 2;
}Rotation
// Continuous rotation speed based on energy
class SpinController {
constructor() {
this.rotation = 0;
}
update(energy) {
const speed = 0.01 + energy * 0.05;
this.rotation += speed;
return this.rotation;
}
}Color/Brightness
// Brightness based on volume
function updateBrightness(element, volume) {
const brightness = 0.5 + volume * 0.5; // 50% to 100%
element.style.filter = `brightness(${brightness})`;
}
// Color shift based on frequency balance
function getReactiveColor(bass, mid, high) {
// More bass = more red/magenta, more high = more cyan
const r = Math.floor(bass * 255);
const g = Math.floor(mid * 100);
const b = Math.floor(high * 255);
return `rgb(${r}, ${g}, ${b})`;
}
// Three.js emissive intensity
function updateGlow(material, bass) {
material.emissiveIntensity = 1 + bass * 3;
}Opacity/Visibility
// Fade based on volume
function updateOpacity(element, volume) {
element.style.opacity = 0.3 + volume * 0.7;
}Beat Response
Simple Beat Flash
class BeatFlash {
constructor(decayRate = 0.95) {
this.intensity = 0;
this.decayRate = decayRate;
}
trigger() {
this.intensity = 1;
}
update() {
this.intensity *= this.decayRate;
return this.intensity;
}
}
// Usage
const flash = new BeatFlash();
function animate() {
if (beatDetector.detect(analyser)) {
flash.trigger();
}
const intensity = flash.update();
element.style.backgroundColor = `rgba(0, 245, 255, ${intensity})`;
requestAnimationFrame(animate);
}Beat Scale Pop
class BeatPop {
constructor(popScale = 1.3, decayRate = 0.9) {
this.scale = 1;
this.targetScale = 1;
this.popScale = popScale;
this.decayRate = decayRate;
}
trigger() {
this.targetScale = this.popScale;
}
update() {
// Lerp toward target, then decay target back to 1
this.scale += (this.targetScale - this.scale) * 0.3;
this.targetScale = 1 + (this.targetScale - 1) * this.decayRate;
return this.scale;
}
}Beat Spawn
class BeatSpawner {
constructor(onSpawn) {
this.onSpawn = onSpawn;
this.cooldown = 0;
this.minInterval = 200; // ms
}
check(isBeat) {
if (isBeat && this.cooldown <= 0) {
this.onSpawn();
this.cooldown = this.minInterval;
}
this.cooldown -= 16; // Assuming 60fps
}
}
// Usage: spawn particles on beat
const spawner = new BeatSpawner(() => {
particleSystem.emit(10);
});React Three Fiber Integration
Audio Reactive Component
import { useRef } from 'react';
import { useFrame } from '@react-three/fiber';
function AudioReactiveSphere({ audioData }) {
const meshRef = useRef();
const materialRef = useRef();
useFrame(() => {
if (!audioData || !meshRef.current) return;
const { bass, mid, high, isBeat } = audioData;
// Scale on bass
const scale = 1 + bass * 0.5;
meshRef.current.scale.setScalar(scale);
// Rotation speed on mid
meshRef.current.rotation.y += 0.01 + mid * 0.03;
// Emissive on high
if (materialRef.current) {
materialRef.current.emissiveIntensity = 1 + high * 2;
}
});
return (
<mesh ref={meshRef}>
<sphereGeometry args={[1, 32, 32]} />
<meshStandardMaterial
ref={materialRef}
color="#111"
emissive="#00F5FF"
emissiveIntensity={1}
/>
</mesh>
);
}Audio Context Hook
function useAudioAnalysis(playerRef) {
const [data, setData] = useState(null);
const analyserRef = useRef(null);
const mapperRef = useRef(null);
useEffect(() => {
analyserRef.current = new Tone.Analyser('fft', 256);
mapperRef.current = new AudioReactiveMapper(analyserRef.current);
if (playerRef.current) {
playerRef.current.connect(analyserRef.current);
}
return () => analyserRef.current?.dispose();
}, []);
useFrame(() => {
if (mapperRef.current) {
setData(mapperRef.current.getValues());
}
});
return data;
}Post-Processing Integration
Audio-Reactive Bloom
function AudioReactiveBloom({ audioData }) {
const bloomRef = useRef();
useFrame(() => {
if (bloomRef.current && audioData) {
// Bass drives bloom intensity
bloomRef.current.intensity = 1 + audioData.bass * 2;
// High frequencies lower threshold (more bloom)
bloomRef.current.luminanceThreshold = 0.3 - audioData.high * 0.2;
}
});
return (
<EffectComposer>
<Bloom ref={bloomRef} luminanceThreshold={0.2} intensity={1} />
</EffectComposer>
);
}Audio-Reactive Chromatic Aberration
function AudioReactiveChroma({ audioData }) {
const chromaRef = useRef();
useFrame(() => {
if (chromaRef.current && audioData) {
// High frequencies drive aberration
const offset = 0.001 + audioData.high * 0.005;
chromaRef.current.offset.set(offset, offset * 0.5);
}
});
return <ChromaticAberration ref={chromaRef} offset={[0.002, 0.001]} />;
}GSAP Integration
Audio-Driven Timeline
class AudioTimeline {
constructor() {
this.timeline = gsap.timeline({ paused: true });
this.progress = 0;
}
build(duration) {
this.timeline
.to('.element', { scale: 1.5 }, 0)
.to('.element', { rotation: 360 }, duration * 0.5)
.to('.element', { scale: 1 }, duration);
}
updateWithAudio(bass) {
// Map bass to timeline progress
const targetProgress = this.progress + bass * 0.02;
this.progress = Math.min(1, targetProgress);
this.timeline.progress(this.progress);
}
}Beat-Triggered GSAP
function createBeatAnimation(element) {
return gsap.timeline({ paused: true })
.to(element, {
scale: 1.2,
duration: 0.1,
ease: 'power2.out'
})
.to(element, {
scale: 1,
duration: 0.3,
ease: 'power2.out'
});
}
// On beat
if (isBeat) {
beatAnimation.restart();
}Complete System Example
class AudioVisualSystem {
constructor(player, visualElements) {
this.player = player;
this.elements = visualElements;
// Analysis
this.analyser = new Tone.Analyser('fft', 256);
this.mapper = new AudioReactiveMapper(this.analyser);
this.beatDetector = new BeatDetector();
// Reactive controllers
this.beatFlash = new BeatFlash();
this.beatPop = new BeatPop();
// Connect
this.player.connect(this.analyser);
this.player.toDestination();
}
update() {
const values = this.mapper.getValues();
const isBeat = this.beatDetector.detect(this.analyser);
if (isBeat) {
this.beatFlash.trigger();
this.beatPop.trigger();
}
const flashIntensity = this.beatFlash.update();
const popScale = this.beatPop.update();
// Apply to visuals
this.elements.background.style.opacity = 0.5 + values.bass * 0.5;
this.elements.circle.style.transform = `scale(${popScale})`;
this.elements.glow.style.boxShadow =
`0 0 ${flashIntensity * 50}px rgba(0, 245, 255, ${flashIntensity})`;
}
start() {
const animate = () => {
this.update();
requestAnimationFrame(animate);
};
animate();
}
}Temporal Collapse Integration
const TEMPORAL_MAPPINGS = {
// Digit glow intensity
digitGlow: (bass, mid) => 1 + bass * 2 + mid,
// Particle emission rate
particleRate: (bass, isBeat) => isBeat ? 50 : bass * 20,
// Background pulse
backgroundBrightness: (bass) => 1 + bass * 0.3,
// Time dilation visual (warp effect)
warpIntensity: (high) => high * 0.5,
// Vignette darkness (close in on beat)
vignetteDarkness: (isBeat, current) => isBeat ? 0.7 : current * 0.95,
// Chromatic aberration (glitch on high)
chromaticOffset: (high) => 0.001 + high * 0.004
};
function applyTemporalMappings(audioData, visuals) {
const { bass, mid, high, isBeat } = audioData;
visuals.digitMaterial.emissiveIntensity =
TEMPORAL_MAPPINGS.digitGlow(bass, mid);
visuals.particles.emissionRate =
TEMPORAL_MAPPINGS.particleRate(bass, isBeat);
visuals.background.brightness =
TEMPORAL_MAPPINGS.backgroundBrightness(bass);
visuals.bloom.intensity =
1.5 + bass * 1.5;
visuals.chromatic.offset =
TEMPORAL_MAPPINGS.chromaticOffset(high);
}Performance Tips
// 1. Update at lower frequency if possible
let frameCount = 0;
function animate() {
if (frameCount % 2 === 0) {
updateAudioData();
}
applyVisuals();
frameCount++;
}
// 2. Use smoothing to hide skipped frames
const smoother = new Smoother(0.95); // Higher = more smoothing
// 3. Batch DOM updates
function applyAllStyles(elements, values) {
// Single reflow
requestAnimationFrame(() => {
elements.forEach((el, i) => {
el.style.transform = `scale(${values[i]})`;
});
});
}
// 4. Use CSS variables for multiple elements
document.documentElement.style.setProperty('--audio-bass', bass);
// CSS: transform: scale(calc(1 + var(--audio-bass) * 0.2));Reference
- See
audio-playbackfor audio loading and transport - See
audio-analysisfor FFT and beat detection - See
audio-routerfor audio domain routing
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

