Audioreactive Dilate Mask | Akatz
A mask that breathes with the beat, with attack and decay
- mask
- normalized_amp
- MASK
Audioreactive Dilate Mask turns a static subject mask into one that swells and shrinks with your audio - with proper attack and decay, so it feels like it's breathing with the beat rather than snapping on and off. It's the mask-returning middle child of Akatz's audioreactive trio: more controllable than the "Dynamic" one, less heavy than the "Infinite" one that outputs color.
The core job: take a mask (say, a person or a logo), take a per-frame amplitude list, and each frame dilate the mask by a radius that tracks the amplitude - clamped between min_radius and max_radius. The attack and decay controls are what make it musical. Amplitude alone is jittery; attack/decay act like an envelope filter so the dilation eases up to a beat hit and eases back down, which is the difference between a smooth pulse and nervous twitching.
How it works
Under the hood it's classic signal shaping: the normalized amplitude drives a target radius, an attack/decay envelope smooths the actual radius over time (in seconds, so fps matters), and OpenCV morphological dilation renders each frame's mask with a circular or square kernel of that radius. Both the attack and the decay have their own easing function (linear, ease-in, ease-out, ease-in-out) so you can make the swell punchy or gentle independently on the way up and down.
Inputs that matter
mask- the input MASK (per-frame or reused).normalized_amp- per-frame amplitude values, roughly 0–1. Must be a NORMALIZED_AMPLITUDE or FLOAT type; the node validates this.fps- frames per second, used to convert attack/decay seconds into frames. Match your output frame rate.shape-circlefor smooth accurate edges,squarefor speed while testing.max_radius/min_radius- the dilation range the amplitude maps onto.threshold- amplitude below this produces no dilation.attack/decay- seconds to ramp up / down.attack_function/decay_function- the easing curves.
Output is a MASK batch, same length as your input. Wire it into an inpaint, a composite matte, or a color fill.
Installing it
Part of akatz-ai/ComfyUI-AKatz-Nodes. Install via ComfyUI Manager (search "AKatz") or:
cd ComfyUI/custom_nodes
git clone https://github.com/akatz-ai/ComfyUI-AKatz-Nodes
cd ComfyUI-AKatz-Nodes
pip install -r requirements.txt
Restart ComfyUI. No model downloads; requirements are numpy, torch, opencv-python and pydub.
Common issues
The #1 mistake is feeding an amplitude source that isn't normalized - the node will reject it with "normalized_amp must be an NORMALIZED_AMPLITUDE or FLOAT type" if it's some other type, and if you feed raw unnormalized values it silently behaves badly. The pack's own Schedule Audio Framesync output is built for this. Also remember attack/decay are in seconds: at 30 fps an attack of 0.5 means 15 frames to reach full dilation. And like all motion-based dilation, a mask that's already fully white has nowhere to grow - keep max_radius reasonable.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| normalized_amp | * | — | |
| fps | INT | 301–240 | — |
| shape | COMBO | 2 options: circle, square | |
| max_radius | INT | 25 | — |
| min_radius | INT | 0 | — |
| threshold | FLOAT | 0.50 | — |
| attack | FLOAT | 0.50 | — |
| decay | FLOAT | 0.50 | — |
| attack_function | COMBO | 4 options: linear, ease-in, ease-out, ease-in-out | |
| decay_function | COMBO | 4 options: linear, ease-in, ease-out, ease-in-out |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MASK | MASK | — |