Communitygithub.com

BlackAngel242/sound-design

Diseño de sonido procedural con el motor sfx — escribiendo una hoja de referencia contra la línea de tiempo de un vídeo, qué sonido corresponde con qué evento visual, jerarquía de ganancia, paneo, tonalidad musical, masterización automática a -14 LUFS, añadiendo nuevos generadores y verificando sincronía. Úsalo al añadir, modificar o comprobar audio, SFX, fondos musicales o sonoridad de cualquier vídeo en este repositorio.

¿Qué es sound-design?

Este skill especializa a un agente de IA (como Claude Code, Cursor o Codex) en el diseño de sonido procedural para vídeos generados por IA. Proporciona un motor `sfx/` escrito completamente en Python con la biblioteca estándar, sin necesidad de muestras, licencias o instalaciones adicionales, garantizando la misma salida en cada ejecución. El skill permite escribir hojas de referencia (cue sheets) que asocian eventos visuales de la línea de tiempo con sonidos sintetizados —como clics, pops, whooshes, chimes o pads—, controlando ganancia, paneo y tonalidad musical. La masterización automática ajusta la sonoridad a -14 LUFS, respetando un pico verdadero ≤ -2 dBFS para evitar saturación en la compresión AAC. Incluye herramientas de verificación de sincronía, visualización de formas de onda y soporte para generadores de audio externos como ElevenLabs MCP. Es útil para añadir, modificar o comprobar audio, SFX, fondos musicales o sonoridad de cualquier vídeo en el repositorio, reemplazando workflows de edición de audio tradicionales por un enfoque reproducible y programático.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/BlackAngel242/skill-market/tree/HEAD/skills/claude-motion/sound-design

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Diseño de sonido

La mayoría de los gráficos en movimiento hechos con IA son silenciosos. El sonido es lo que hace que una pieza se sienta producida.

El motor sfx/ sintetiza cada sonido en Python puro de la biblioteca estándar: sin muestras, sin licencias, sin instalaciones, la misma salida en cada ejecución. Lee el mismo JSON de línea de tiempo que la imagen, por lo que el sonido no puede desincronizarse.

Cómo encaja

ArchivoRol
sfx/synth.pygeneradores: cada uno devuelve muestras mono a 48 kHz
sfx/mix.pyMix: coloca sonidos en el tiempo, masteriza a un objetivo de sonoridad, escribe WAV
sfx/loudness.pySonoridad integrada BS.1770 (coincide con ebur128 de ffmpeg)
sfx/cues/<video>.pyuna hoja de referencia: el diseño de sonido de un vídeo
python3 -m sfx --list                   # generadores con su propósito
python3 -m sfx sfx/cues/<video>.py      # renderizar → WAV masterizado

Escribir una hoja de referencia para un vídeo nuevo

Crea sfx/cues/<video>.py:

from sfx.synth import click, pop, whoosh, chime, riser, impact

TIMELINE = "timeline.json"      # el mismo archivo que lee la composición
OUT = "public/sfx.wav"
TARGET_LUFS = -14.0             # opcional, este es el valor por defecto

def score(mix, tl):
    s1 = tl["s1"]
    mix.put(s1["title"], whoosh(0.4, 500, 2400, peak=0.45), 0.12)
    for i, t in enumerate(s1["items"]):
        mix.put(t, pop(900 + i * 150, 400), 0.3, pan=-0.4 + i * 0.3)
  • mix.put(t, samples, gain, pan): t siempre proviene de tl, nunca un número escrito. Los desplazamientos desde un beat (s1["exit"] + 0.05) están bien.
  • mix.typing(start, end, chars): una pulsación de tecla humanizada por carácter.
  • mix.put_stereo(t, left, right, gain): para fuentes estéreo como pad().
  • La masterización es automática: el motor recorta suavemente y ajusta la ganancia para alcanzar TARGET_LUFS, aumentando la excursión solo lo necesario para mantener el pico verdadero ≤ −2 dBFS (espacio para el exceso de AAC, por lo que el MP4 se mantiene por debajo de −1 dBTP). Una mezcla compuesta principalmente de golpes cortos con silencio entre ellos no puede alcanzar −14 sin comprimir; el motor entonces sale más bajo y lo indica. Soluciónalo con sonido sostenido (un pad, colas más largas), no forzándolo.
  • Añade un script "sfx" en package.json que apunte a la nueva hoja de referencia, o ejecútala directamente.

sfx/cues/effort.py es un ejemplo real completo: 128 sonidos más un pad de fondo.

Evento visual → sonido

En pantallaGeneradorNotas
Escrituramix.typing()fluctuación ±4–6 ms, ganancia aleatoria
Revelación de palabra / líneawhoosh() + blip() al aterrizarcorto, aireado
Insignia, chip, llamada aparecenpop()eleva el tono a lo largo de una secuencia
Control se ajusta a un pasoclick() + blip() en tono
Boceto / dibujoscratch()
Acumulaciónriser()termina exactamente en el golpe; un gran riser por vídeo
Éxito / llegadachime()acorde en tono
Transición principalwhoosh() al entrar, impact() en el golpeun impacto por vídeo
Debajo de todopad() con un envelope()redúcelo bajo la transición principal

Acentúa, no narres: no todo movimiento necesita un sonido. El movimiento continuo (deriva, grano, rotación) permanece en silencio.

Niveles y espacio

  • Golpes principales: ganancia 0.25–0.35. Sonidos de apoyo: 0.08–0.2. Pad: ~0.03, reducido ~65% bajo la transición principal.
  • El paneo sigue la posición en pantalla (−1 izquierda … +1 derecha). Las secuencias barren el campo estéreo.
  • Elige una tonalidad y mantén cada sonido tonal en ella; el tono sube con el progreso y se resuelve en el remate. (En el ejemplo effort, el pad y las notas del slider están en Re mayor, pero los pops de la escena 3 y el chime siguen en Do mayor. No copies eso).

Añadir un generador

Escribe una función en sfx/synth.py que devuelva una lista de flotantes a SR. Pon su propósito en la primera línea del docstring; --list lo mostrará. Usa el random a nivel de módulo para ruido, de modo que los renderizados sigan siendo reproducibles. Construye sobre bandnoise() para cualquier cosa aireada.

Verificar

npm run sfx                              # o python3 -m sfx sfx/cues/<video>.py
npm run wave                             # out/wave.png + sonoridad del WAV
npm run build
node scripts/wave.mjs out/effort.mp4     # sonoridad de lo que realmente publicarás

En out/wave.png, cada línea coral es un beat de la línea de tiempo. Cada transitorio debe situarse sobre una línea o justo después. Un golpe entre líneas significa un tiempo codificado o un WAV desactualizado. Pasa --timeline para un vídeo con su propio archivo de línea de tiempo.

Opcional: audio generado

Para locuciones o sonidos que no puedas sintetizar, el MCP de ElevenLabs (consulta .mcp.json.example) puede generar archivos en public/. Colócalos con <Audio src={staticFile(...)} /> dentro de un <Sequence from={beat * FPS}>.

Skills relacionados