Communitygithub.com

BlackAngel242/sound-design

Design de som procedural com o motor sfx — escrevendo uma folha de dicas contra a linha do tempo de um vídeo, qual som corresponde a qual evento visual, hierarquia de ganho, pan, tonalidade musical, masterização automática para -14 LUFS, adição de novos geradores e verificação de sincronia. Use ao adicionar, alterar ou verificar áudio, SFX, bases musicais ou loudness para qualquer vídeo neste repositório.

O que é sound-design?

Esta skill oferece um motor de design de som procedural totalmente em Python puro (stdlib), sem necessidade de samples, licenças ou instalações. Ela permite criar paisagens sonoras completas para vídeos gerados por IA, sincronizando cada som com eventos específicos da linha do tempo do vídeo, como digitação, revelações de palavras, badges, transições e muito mais. O motor realiza masterização automática para o alvo de -14 LUFS com soft-clipping e proteção de pico verdadeiro, garantindo que o áudio final esteja dentro dos padrões de broadcast e evite distorções em codecs como AAC. A skill suporta a criação de folhas de dicas (cue sheets) em Python, onde você define quais sons tocam em que momento, com controle fino de ganho, pan e tonalidade musical. Além disso, permite adicionar novos geradores de som personalizados e verificar a sincronia através de ferramentas de visualização de forma de onda. É ideal para desenvolvedores que desejam adicionar áudio profissional a vídeos sem depender de bibliotecas externas ou estações de áudio complexas.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Design de som

A maioria dos motion graphics feitos por IA são silenciosos. O som é o que faz uma peça parecer produzida.

O motor sfx/ sintetiza cada som em Python puro stdlib: sem samples, sem licenças, sem instalações, mesma saída em cada execução. Ele lê o mesmo JSON de linha do tempo que a imagem, então o som não pode sair de sincronia.

Como tudo se encaixa

ArquivoFunção
sfx/synth.pygeradores: cada um retorna amostras mono a 48 kHz
sfx/mix.pyMix: posiciona sons no tempo, masteriza para um alvo de loudness, escreve WAV
sfx/loudness.pyLoudness integrada BS.1770 (corresponde ao ebur128 do ffmpeg)
sfx/cues/<video>.pyuma folha de dicas: o design de som de um vídeo
python3 -m sfx --list                   # geradores com o que cada um faz
python3 -m sfx sfx/cues/<video>.py      # renderiza → WAV masterizado

Escrevendo uma folha de dicas para um novo vídeo

Crie sfx/cues/<video>.py:

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

TIMELINE = "timeline.json"      # o mesmo arquivo que a composição lê
OUT = "public/sfx.wav"
TARGET_LUFS = -14.0             # opcional, este é o padrão

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 sempre vem de tl, nunca um número digitado. Deslocamentos a partir de uma batida (s1["exit"] + 0.05) são aceitáveis.
  • mix.typing(start, end, chars): uma tecla humanizada por caractere.
  • mix.put_stereo(t, left, right, gain): para fontes estéreo como pad().
  • A masterização é automática: o motor faz soft-clipping e ajusta o ganho para atingir TARGET_LUFS, aumentando o drive apenas o necessário para manter o pico verdadeiro ≤ −2 dBFS (espaço para overshoot do AAC, para que o MP4 fique abaixo de −1 dBTP). Uma mixagem com maioria de hits curtos e silêncio entre eles não consegue atingir −14 sem esmagamento; o motor então sai mais baixo e avisa. Corrija com som sustentado (um pad, caudas mais longas), não forçando.
  • Adicione um script "sfx" em package.json apontando para a nova folha de dicas, ou execute diretamente.

sfx/cues/effort.py é um exemplo real completo: 128 sons mais um pad de fundo.

Evento visual → som

Na telaGeradorNotas
Digitaçãomix.typing()jitter ±4–6 ms, ganho aleatório
Revelação de palavra / linhawhoosh() + blip() no pousocurto, arejado
Badge, chip, callout aparecempop()aumenta o tom em uma sequência
Controle se encaixa em um passoclick() + blip() na tonalidade
Esboço / desenhoscratch()
Acúmuloriser()termina exatamente no hit; um riser grande por vídeo
Sucesso / chegadachime()acorde na tonalidade
Transição de heróiwhoosh() na entrada, impact() no hitum impact por vídeo
Debaixo de tudopad() com um envelope()abaixe sob a transição de herói

Acentue, não narre: nem todo movimento precisa de som. Movimento contínuo (deriva, grão, rotação) permanece silencioso.

Níveis e espaço

  • Hits de herói: ganho 0,25–0,35. Sons de suporte: 0,08–0,2. Pad: ~0,03, abaixado ~65% sob a transição de herói.
  • Pan segue a posição na tela (−1 esquerda … +1 direita). Sequências varrem o campo estéreo.
  • Escolha uma tonalidade e mantenha todos os sons tonais nela; o tom sobe com o progresso e resolve no payoff. (No exemplo effort, o pad e as notas do slider são em Ré maior, mas os pops e chime da cena 3 ainda estão em Dó maior. Não copie isso.)

Adicionando um gerador

Escreva uma função em sfx/synth.py que retorna uma lista de floats em SR. Coloque para que serve na primeira linha do docstring; --list mostra. Use o random de nível de módulo para ruído, para que as renderizações permaneçam reproduzíveis. Use bandnoise() para qualquer coisa arejada.

Verificar

npm run sfx                              # ou python3 -m sfx sfx/cues/<video>.py
npm run wave                             # out/wave.png + loudness do WAV
npm run build
node scripts/wave.mjs out/effort.mp4     # loudness do que você realmente vai postar

Em out/wave.png, cada linha coral é uma batida da linha do tempo. Cada transitório deve estar sobre uma linha ou um pouco depois. Um hit entre linhas significa um tempo codificado ou um WAV desatualizado. Passe --timeline para um vídeo com seu próprio arquivo de linha do tempo.

Opcional: áudio gerado

Para narração ou sons que você não pode sintetizar, o MCP do ElevenLabs (veja .mcp.json.example) pode gerar arquivos em public/. Coloque-os com <Audio src={staticFile(...)} /> dentro de um <Sequence from={beat * FPS}>.

Habilidades Relacionadas