SONIC·SUITE

S O N I C SUITE

Seis librerías JavaScript, sin dependencias, para que una web escuche la música y se mueva con ella. Todo lo que ves aquí funciona en vivo con la misma canción.

Ver las librerías

Usa audífonos. Pista de demostración: «Enamorado tuyo», El Cuarteto de Nos, separada en voz, batería, bajo y melodía.

Análisis por stems

SonicMotionv4.4.0

El corazón de la suite. Suena la mezcla y, en silencio, analiza cada pista separada: energía real, bandas grave/medio/agudo y el instante exacto de cada golpe, compensando la latencia de los parlantes.

  • Atributos data-sonic: sin escribir animaciones.
  • onFrame con value, onset y bands por stem.
  • Mezcla por stems: escucha cada pista por separado.
npm i sonicmotion
cada panel es un stem
voz · skyGlow
batería · scale
bajo · pulse
melodía · float
voz-∞ dB
batería-∞ dB
bajo-∞ dB
melodía-∞ dB
import SonicMotion from 'sonicmotion';

const sonic = SonicMotion.create({ master: '/audio/master.mp3' });
sonic.addStem('drums', '/audio/drums.mp3');
sonic.addStem('bass', '/audio/bass.mp3', { onsetThreshold: 3, minOnsetGapMs: 120 });

SonicMotion.registerEffect('skyGlow', (el, v) => {   // efecto propio
  el.style.boxShadow = `0 0 ${v * 40}px rgba(74, 168, 224, ${v})`;
});
sonic.initDOM();   // <div data-sonic="scale" data-sonic-track="drums">
sonic.onFrame((d) => {
  if (d.drums.bands.bass.onset > 0) flash();   // cada golpe de bombo
});
playButton.onclick = () => sonic.play();
Visualizadores

SonicWavev1.2.0

Forma de onda, ecualizador y espectro en Canvas, livianos y sin dependencias. Una alternativa a WaveSurfer.js que se alimenta directo de SonicMotion.

  • La barra de abajo es su forma de onda: tócala para saltar.
  • Ecualizador que sigue el puntero cuando no hay música.
  • Espectro en barras, línea o espejo, escala logarítmica.
npm i sonicwave
ecualizador: batería · espectro:
import SonicWave from 'sonicwave';

const eq = SonicWave.createEqualizer({ container: '#eq', barCount: 28 });
const spectrum = SonicWave.createSpectrum({ container: '#spectrum', mode: 'mirror' });
const wave = SonicWave.createWaveform({ container: '#waveform' });
wave.setPeaks(peaks, duration);        // sin decodificar 4 min de audio
wave.enableSeek((p) => sonic.seek(p * duration));

sonic.onFrame(() => {
  eq.setAudioData(sonic.getSpectrum('drums'));
  spectrum.update(sonic.getSpectrum('other'));
  wave.setTime(sonic.currentTime);
});
Efectos visuales

SonicFXv1.2.0

Degradados, filtros CSS y bordes que reaccionan al audio, con presets listos por instrumento. Solo reescribe un estilo cuando su valor cambia.

  • Presets bassPulse, drumsHit, vocalsWave, otherFlow.
  • Bordes, filtros y degradados con su propio control.
  • Declarativo con data-sonicfx o por JavaScript.
npm i sonicfx
un efecto por tarjeta
bassPulsebajo
drumsHitbatería · bass.punch
vocalsWavevoz
otherFlowmelodía
borderRainbowmelodía
hueShiftvoz
import SonicFX from 'sonicfx';

const fx = SonicFX.create();
let frame = {};
sonic.onFrame((d) => { frame = d; });
fx.setDataSource(() => frame);

// <div data-sonicfx="bassPulse" data-sonicfx-track="bass" data-sonicfx-color="#4aa8e0">
fx.parseDOM();
fx.bind('#titulo', 'borderRainbow', { stem: 'other' });
fx.start();
Animaciones al hacer scroll

SonicScrollv1.2.0

Entradas al hacer scroll con IntersectionObserver, una alternativa moderna a AOS. Su modo AudioAware dice qué está en pantalla, así la música solo mueve lo que se ve.

  • Todas las secciones de esta página entran con SonicScroll.
  • slideUp, fadeIn, scaleIn, flipIn…
  • Respeta prefers-reduced-motion.
npm i sonicscroll
laten con el bombo solo si están en pantalla
slideUpdata-scroll="slideUp"
fadeIndelay 120
scaleIndelay 240
slideLeftdelay 360
flipIndelay 480
slideRightdelay 600

AudioAware: 0 tarjetas en pantalla

import SonicScroll from 'sonicscroll';

const scroll = SonicScroll.create({ once: true });
scroll.init();   // <div data-scroll="slideUp" data-scroll-delay="120">

const aware = scroll.createAudioAware();
aware.trackAll('.scroll-card');
sonic.onFrame((d) => {
  const kick = d.drums.bands.bass.punch;
  for (const el of aware.getVisible())       // solo lo que está en pantalla
    el.style.transform = `scale(${1 + kick * 0.06})`;
});
Letra sincronizada

SonicLyricsv1.3.0

Letra palabra por palabra que sigue lo que realmente se escucha, no el reloj del navegador. Lee el formato de Whisper/WhisperX y sobrevive a los saltos.

  • Eventos onWord y onLine, o consultas por tiempo.
  • Etiquetas por palabra para disparar efectos.
  • Aquí el texto es propio: cada palabra cae en un ataque real de la voz.
npm i soniclyrics
karaoke sobre la voz
Dale play: la voz entra a los 13 s.
import SonicLyrics from 'soniclyrics';

// { words: [{ word, start, end, line }] }  (el formato de Whisper)
const lyrics = SonicLyrics.create({ src: '/audio/lyrics.json', sonic });
lyrics.onLine((line) => pintarLinea(line?.words ?? []));
lyrics.onWord((w) => encender(w));   // 80 ms antes de que suene

// después de saltar en la canción
lyrics.seek(sonic.audibleTime);
Rendimiento

SonicPerfv1.2.0

Lo que hace que una web musical no se coma la batería: tope de cuadros por segundo, carga diferida y pausa automática cuando la pestaña no se ve.

  • Esta animación arranca recién cuando aparece en pantalla.
  • Cambia el tope de FPS y mira el costo real.
  • Cambia de pestaña: la música se pausa y vuelve sola.
npm i sonicperf
partículas con el bajo
0cuadros/s reales
0ms por cuadro
noanimación cargada
    import SonicPerf from 'sonicperf';
    
    const throttler = SonicPerf.createThrottler({ targetFPS: 30 });
    const loader = SonicPerf.createLazyLoader();
    loader.loadOnVisible('#perf-canvas', () => throttler.start(dibujar));
    fpsButtons.onclick = (fps) => throttler.setFPS(fps);
    
    const vis = SonicPerf.createVisibilityManager();
    vis.autoPause(sonic);   // pestaña oculta → pausa; al volver → sigue

    Hecho con Sonic Suite

    Dos experiencias completas que usan estas librerías.

    Enamorado tuyo · El Cuarteto de Nos · forma de onda con SonicWave
    0:00 / 4:19