vibeapp.win

Numbers

Sharp sound effects peaked at +1.8 dBTP after AAC encoding, so we added a low-pass and a limiter

Henning replaced the music on the generated Instagram Reels with sound effects that follow the animation. The sharp attacks measured +1.8 dBTP after AAC encoding, so we added a low-pass at about 12 kHz, lowered the limiter ceiling to −4 dBFS and set the level from only the parts where a sound is playing.

The newsroom engine makes an Instagram Reel for each story on kokkekunst.no: a 15–30 second animation with a motif that fits the story. A wine story gets a bottle that is opened and poured into a glass. Every sound in these Reels is generated in code. There are no audio files and no licences. The output is a 48 kHz, 16-bit stereo WAV, which ffmpeg then encodes to AAC because Instagram asks for that format.

This post covers one change from 8 October 2026: the music went, sound effects that follow the motion came in, and we found out what those effects did to the peak level after encoding.

From music to motion

The first Reels had a fixed electric piano track. After that came music chosen by the directing step: five moods and five instruments, and all 25 combinations measured at −14.5 LUFS. Henning didn’t like it. His message was in Norwegian. In English it was roughly: “Wouldn’t it be better with a sound for opening the bottle, a pop, and sounds that support the movement in the animation?”

Claude wrote a new set of effects that follow what happens in the frame:

  • a corkscrew that creaks as it turns in, with a small click on each turn
  • a cork pop
  • wine glugging and rising in pitch as the glass fills
  • a glass clink
  • a whoosh on every cut
  • a soft thud as each word of the title lands
  • a mechanical counter that clicks when the digits roll over
  • a map pin dropping, a medal ringing, pages turning, and fire crackling on the pass

The music code is still there, but it is now off by default. The sound-generation function takes a music option, and the default changed to “no music”.

How the sounds are built

Each effect is made from sine waves and filtered noise. The noise comes from a seeded random number generator, so the same Reel produces exactly the same audio every time.

A few of the effects needed more than a sine and an envelope:

  • The cork pop has three parts: a very short high-passed click about 4 ms long, the bottle neck ringing briefly like a Helmholtz resonator with its pitch rising slightly as the cork comes free, and air rushing out after it through a band-pass that sweeps down.
  • The pour runs noise through a band-pass whose centre frequency rises as the glass fills, since that rising pitch is what the ear recognises. Small bubbles go on top, each a short tone that rises in pitch, packed most tightly at the start.
  • The whoosh goes through two narrow band-passes that sweep up and down and are a little apart from each other. It is loudest just before the middle, like something passing the camera.

To make the pour and the whoosh possible, Claude added a state-variable band-pass filter (Chamberlin form) whose centre frequency can change on every sample.

What the sharp attacks did after encoding

Many of the new effects start with a sharp attack. Measured after AAC encoding, the sharp attacks reached +1.8 dBTP. A true peak above 0 dBTP means the decoded audio goes past full scale, so the clip would distort on playback.

The limiter ceiling before the change was 0.72 linear, about −2.9 dBFS. That ceiling had already been lowered once: an earlier code comment records that with a ceiling of 0.79, a guitar in the music peaked at −0.3 dBTP after AAC.

The fix

The commit changed three things:

  1. A low-pass at about 12 kHz on the mix.
  2. A lower limiter. The soft knee moved from 0.56 to 0.50 and the hard ceiling from 0.72 to 0.63, which is −4 dBFS. The code comment gives the reason: “with sharp attacks and AAC, the room is needed”.
  3. Level set from the active parts. With no music, most of a Reel is near silence with short effects in between. The level is now measured only over 0.1-second windows above −45 dBFS, and the target is an RMS of 0.17 in those windows.

The third change comes from an earlier failure. When the level was set from the average of the whole track, quiet music pulled the bell at the end of a Reel to −3 LUFS.

What we measured afterwards

After the change, the wine-list Reels measure −13.6 LUFS integrated with a true peak below −1.5 dBTP after AAC. The material doesn’t record which tool did the measurement.

Before and after, measured after AAC:

Limiter ceiling True peak after AAC
Music, earlier ceiling 0.79 −0.3 dBTP
Effects, before the fix not stated in the commit +1.8 dBTP
Effects, low-pass ~12 kHz, ceiling −4 dBFS 0.63 below −1.5 dBTP

One trap on the way

The video cache is keyed on the Reel’s plan, not on the code. If only the sound changes, the cache keeps serving the old video. The commit bumped the Reel version to 6 so that new audio would actually be rendered. The session notes now say to bump that number for every visual or audio change.

Where it stands

A Reel with the new sound has been posted. Henning is not entirely happy with the sound yet. The session notes say the next step is real recordings rather than more synthesis. The options are recordings Henning makes himself in a kitchen, a CC0 library, or a one-off set of generated effects. They also suggest a page for auditioning each sound with a thumbs up or down, and measuring two or three Reels he likes. None of that has been decided. Reels already posted will not be changed.

What we learned: check true peak after encoding, not on the mix. Once the sounds had sharp attacks, they measured +1.8 dBTP after AAC.