Hypernatural

TechniqueBy HypernaturalVersion 2, Oct 29, 2026

python-synth-sfx-for-motion-graphics

Add sound effects to a motion-graphics or interactive-titles cut: read the cue times from the hn4a-compositor spec, synthesize pops, squashes, splats, thwacks and panned whooshes locally with numpy/scipy (free), and swap the spec's audio for the SFX track. Use when hn4a has no sound-effect model or the person wants SFX in place of the original audio.

SKILL.md

Synthesized SFX for motion graphics

hn4a has no sound-effect model, so effects are made in Python and mixed by the compositor. They come out clean and a little cartoony, which suits kinetic type; if the person wants realistic foley, ask them for sound files and place those at the same cues.

1. Cues from the spec, not by ear

Read every event time from the compose JSON so a re-timed spec re-cues the sound: a layer's start (entrance), end (exit), the key where a box height reaches its minimum (flat), and the contact time where x keys start moving (hit). One sound per visible event; leave space between them.

EventSoundRecipe
Title pops inpopsine sweep 650-900 Hz up to 1500-1700 Hz, 90 ms, exp decay ~38/s, plus a 2-6 kHz noise tick
Squash under a handrubbery squeezesawtooth sweep 260 Hz down to 70 Hz with 18 Hz wobble, low-passed at 1.4 kHz, plus band-passed noise gated at 22-52 Hz (creak), getting louder as it flattens
Pressed flatsplat90 Hz falling thump decaying ~14/s plus low-passed noise smack
Blinks outdown-popsine 900 Hz down to 300 Hz, 120 ms, quieter
Hand hits itthwack140 Hz falling thump plus 0.8-5 kHz noise burst, 250 ms
Flies offwhooshnoise through a band-pass whose centre sweeps 400 Hz to 4 kHz over ~0.45 s, sin envelope, panned from the hit side to the exit side

Pan each sound toward where its title sits (left title about -0.4, right about +0.5). Start transients about 10 ms before the visual event.

2. Build the track

48 kHz stereo, the comp's exact duration. scipy.signal.butter(..., output='sos') with sosfilt for the filters; equal-power pan (sqrt((1-p)/2), sqrt((1+p)/2)); for a moving pan, add the whoosh in 10 ms slices with the pan ramping. Seed the noise generator so a rebuild sounds the same. Normalize the mix peak to about -1 dBFS. Write it to audio/sfx.wav and keep the script in scripts/make_sfx.py, taking the spec path as its argument.

3. Replace the audio

In the spec: "audio": [{"src": "../audio/sfx.wav", "start": 0, "trim": 0, "volume": 1}]. To keep the original sound under the effects, list the footage as a second audio entry at a lower volume instead of removing it. Changing audio needs a whole render, not --into.

4. Check

  • After the render, run volumedetect on a stretch with no events: about -91 dB means the original audio is really gone.
  • You can't hear: put the render on a review page, each sound and its moment in the row's body, send the MP4 into the chat, and ask the person to listen. Adjust gain or swap a recipe per their notes, then rebuild from the script.

Go make something cool.

Install the app, open your agent, describe the video. That's the whole onboarding.

Sticker HypernaturalSticker BannerSticker TVBoy