Devanshu Singhai

Home / Blog / Sound

Scoring a showreel with Python

· Devanshu Singhai · 3 min read

Risograph-printed waveform of a decaying synthesized pop sound under the title Scoring a showreel with Python

Short answer: Every sound in my 58-second reel is synthesized in one Python script with numpy and scipy. Sound effects sit on event times read straight from the animation code, a pad changes chord on every cut, and each piece gets its own tempo. No samples, so no licensing, and the sync is exact.

Stock music never lands on the cut. You either edit the picture to the music or nudge sound effects by hand until they almost line up. Since my animations are code with known timings, the score could be code too.

The cut list is the source of truth

The reel is a sequence of pieces at fixed times: intro card 0 to 3s, kinetic type 3 to 11.1s, logo ident 11.1 to 17.9s, and so on to the end card at 53.8s. The script keeps that as a table. A helper converts "1.2 seconds into the type piece" to reel time, so every sound is placed by the same numbers the animation uses.

def place(at, sig, gain=1.0, pan=0.0, verb=0.25):
    """add sig at time `at` (s), constant-power pan -1..1"""
    i = int(at * SR)
    sig = sig[: len(L) - i] * gain
    a = (pan + 1) * np.pi / 4
    L[i:i + len(sig)] += sig * np.cos(a)
    R[i:i + len(sig)] += sig * np.sin(a)
    VERB[i:i + len(sig)] += sig * verb

Instruments from three ingredients

Every sound is some mix of a sine wave, filtered noise and an envelope. A "pop" for a word landing is a sine whose pitch drops fast:

def pop(f=600, d=.16):
    t = np.arange(int(SR * d)) / SR
    freq = f * (1 + .9 * np.exp(-t * 90))       # pitch falls
    ph = 2 * np.pi * np.cumsum(freq) / SR
    return np.sin(ph) * np.exp(-t * 32) * np.minimum(1, t * 600)

The same pattern gives ticks, thuds, whooshes (band-passed noise with a moving filter), chimes, typing clicks and counter ticks for the data piece.

A tempo per piece

The beat follows the picture rather than sitting at one BPM:

Piece Tempo Feel
Kinetic type 124 bpm four on the floor, offbeat open hats
Logo ident 84 bpm half-time, the bells carry it
Data story 112 bpm ticking sixteenths under the counters
Launch film 128 bpm the fullest beat, snare-roll build
3D form study 70 bpm a heartbeat
Trance 90 → 170 bpm accelerando into a drop

A small grid() function returns step times between two points while gliding the tempo.

Waveform of the 58-second showreel score with pink cut markers and the tempo of each section: type 124 bpm, ident 84, data 112, launch 128, form 70, Trance 90 to 170
The real score.wav. Loudness and density change at every cut because each section has its own tempo and instruments.

Mix and master

Everything sums into stereo buffers plus a mono reverb send, convolved with a generated impulse response, softly saturated with tanh, then written as a 48 kHz WAV and muxed onto the video with ffmpeg. Change a cut, update the table, re-run, and the whole score moves with it.

FAQ

How can I get royalty-free music for a showreel?

Generate it. Short synthesized sounds (pops, ticks, whooshes, chimes, kicks) built from sine waves, filtered noise and envelopes are enough for a motion reel, and because nothing is sampled there is nothing to license.

How do you sync sound effects exactly to an animation?

Take event times from the animation code itself (when a word lands, when a counter ticks), map them to reel time using the cut list, and place each sound at that sample index. The sync is exact because both come from the same numbers.

Do I need to know music theory?

A little. Knowing which chord to use per section helps, but most of the work is timing and envelopes.

Does this work with After Effects or Premiere projects?

Yes. Export marker times from your timeline as the cut list and the same approach applies.

I'm Devanshu, a motion designer, video editor and web and app developer in Delhi. Need motion, a site or an app built? Get in touch.