freezeframe
freezeframe · effectsFREEZEFRAME fuses two video effects in one card. First, a SAMPLE & HOLD "freeze": with nothing patched to GATE the source passes through live; patch a gate and the image FREEZES, and the GATE jack then honours both readings of the gate cable at once. Send a TRIGGER at it and each rising edge updates EXACTLY ONE frame, after which it is still again. Hold the gate HIGH (level >= 0.5) and you get that same one-frame update at the edge, and then — once the level has STOOD high for about 75 ms — continuous live updating for as long as it stays high. That 75 ms is deliberate and is the shortest honest answer available: the patch bridge does not stream the gate waveform to a video module, it re-reports the level roughly every 25 ms, so for the first tick or two a 5 ms trigger and a gate that has just opened are literally the same bytes. Anything held shorter than the window is therefore classified as a TRIGGER and updates exactly one frame — including a gate DERIVED from a trigger by GATEMAIDEN, whose default width is 50 ms, so inserting GATEMAIDEN into the path does not change the frame count. In practice a square LFO below roughly 6.6 Hz plays while open and stutter-freezes the instant it closes (at 1 Hz about 44 percent of frames update, at 4 Hz about 26 percent); faster than that knee each cycle contributes only its one edge frame and the module reads as a strobe, which is the frame-rate-independent reading anyway. Short pulses cannot be missed or double-counted — the rising edge is detected as the gate value arrives rather than sampled once per rendered frame, and the one-shot is a latch a single frame consumes. The first frame always captures so the buffer seeds with real content instead of black. Second, a PER-CHANNEL POSTERIZE: four QUANT knobs each reduce one channel's colour depth, mapping the sweep geometrically in log2 from 256 levels (full depth) at min, through 32 at midway, to 2 (on/off) at max — crank all four for a hard few-bit posterized look. The shader posterizes each channel with floor(c*levels)/(levels-1); the combined output also applies the QUANT-luma reduction as a hue-preserving luma ratio so that knob still shapes the main out. Third, PHOSPHOR DECAY: switch DECAY on and a held frame no longer just sits there — it fades exponentially to black over the DECAY TIME knob's 0.05 to 2 seconds, the way a CRT phosphor gives up once the beam stops refreshing it, and INVERT sends it to white instead. DECAY TIME reads as "gone by": at the time you dial in the frame has reached the target exactly and stays there, rather than the 37 percent a 1/e time constant would leave behind. It is only visible WHILE THE IMAGE IS FROZEN, which is not a limitation but what the effect IS — decay is the age of the held frame, so with GATE unpatched (live passthrough) or held open every frame is brand new and the switch legitimately does nothing. The fade is evaluated from elapsed TIME rather than accumulated per frame, so it takes the same real half-second whether the renderer is managing 8 frames a second or 240, and it is applied after the posterizer (a signal is quantized, then a display persists it) so it still fades smoothly even with all four QUANT knobs at max. Five outputs let you tap the recombined image, each isolated channel as a grey intensity image, or the Rec.601 luma. Usage hint: drive GATE from an LFO or clock to strobe/freeze a video feed, then dial the QUANT knobs for VHS/8-bit colour crushing; add DECAY for trailing strobe ghosts; fan the R/G/B/LUMA taps into separate processors for channel-split effects.
the faceplate
inputs
| id | cable | what it does |
|---|---|---|
video_in | video | The source video frame fed into the sample-and-hold buffer and posterizer. RGB video stream |
gate_in | gate | Sample-and-hold gate. Unpatched = continuous live passthrough. Patched, the image is FROZEN while the level is LOW. Each RISING EDGE updates EXACTLY ONE frame, so a trigger pulse re-samples once and then holds still. A gate HELD HIGH gets that edge frame too, and then updates CONTINUOUSLY once the level has stood high for about 75 ms — three reports of the ~25 ms patch bridge, which is the soonest a held gate can be told apart from a trigger at all, since until the level is re-reported the two are identical. A high shorter than that window reads as a TRIGGER: notably a 50 ms gate derived from a trigger by GATEMAIDEN, which is why inserting GATEMAIDEN does not change the frame count. Both readings come from this one jack — patch a held gate or slow square LFO for live-while-open, or a clock/trigger for one frame per tick. gate / trigger; modulates gateLevel (summed directly (the destination DSP scales it)); gate — acts while the level is high (reacts to both edges) |
outputs
| id | cable | what it does |
|---|---|---|
video_out | video | The recombined R/G/B image with each channel's posterize applied, plus the QUANT-LUMA reduction as a hue-preserving luma ratio. The card's on-screen preview shows this output. RGB video stream |
r_out | video | The posterized RED channel alone, rendered as a grey intensity image (R copied to all three channels). RGB video stream |
g_out | video | The posterized GREEN channel alone, rendered as a grey intensity image. RGB video stream |
b_out | video | The posterized BLUE channel alone, rendered as a grey intensity image. RGB video stream |
luma_out | video | The Rec.601 luma (0.299R+0.587G+0.114B), posterized by QUANT LUMA, rendered as a grey intensity image. RGB video stream |
params
| id | label | range | default | curve |
|---|---|---|---|---|
quant_r | QUANT R | 0..1 | — | linear |
quant_g | QUANT G | 0..1 | — | linear |
quant_b | QUANT B | 0..1 | — | linear |
quant_luma | QUANT LUMA | 0..1 | — | linear |
decay | DECAY | 0..1 | — | discrete |
decay_invert | INVERT | 0..1 | — | discrete |
decay_time | DECAY TIME | ?..?s | — | log |
gateLevel | GATE | 0..1 | 0 | linear |
controls
| control | what it does |
|---|---|
| DECAY | DECAY — phosphor persistence, OFF by default. Switch it on and a HELD frame fades away instead of sitting there: the image drops exponentially toward black over the DECAY TIME you set, the way a CRT phosphor gives up after the beam stops refreshing it. It only does anything WHILE THE IMAGE IS FROZEN, and that is the honest behaviour rather than a limitation — decay is the AGE of the held frame, and a frame that was just captured is zero seconds old. So with nothing patched to GATE (live passthrough), or with the gate held open, every frame is fresh and this switch changes nothing you can see. Patch a gate, let it close, and the fade begins. Turning DECAY off restores the previous output exactly, not approximately. |
| INVERT | INVERT — flip the decay TARGET from black to white, so a held frame blooms out to a white field instead of sinking to a black one. Same curve and the same DECAY TIME, measured as distance-to-white rather than distance-to-black, so the two directions clear at exactly the same moment. Does nothing unless DECAY is on. |
| DECAY TIME | DECAY TIME — how long a held frame takes to CLEAR, from 0.05 s (a fast strobe-trail flicker) to 2 s (a long smear). Read it as "gone by": at the time you dial in, the frame has reached the target exactly and stays there — it is not a 1/e time constant, which would still leave 37 percent of the picture on screen when the clock ran out. The shape between the ends is exponential, so most of the brightness goes early and the last of it lingers, which is what phosphor actually does. Moving the knob mid-fade changes the rate from that moment on and leaves the part already faded alone, so it will not jump. Does nothing unless DECAY is on. |
| GATE | GATE — hidden synthetic param the cross-domain CV bridge writes from gate_in; it carries the live gate level into the sample-and-hold decision, is rising-edge detected on arrival for the one-shot trigger, and the fact that it is written at all is how the module detects the gate is patched. The wall clock of the last rising edge is what the 75 ms hold-qualification window is measured from, so a level that has not yet stood that long counts as a trigger rather than a hold. Exposed only as the gate cv jack, not as a knob. |
| QUANT B | QUANT B — posterize amount for the blue channel, 256 levels at min down to 2 at max. Affects video_out and b_out. |
| QUANT G | QUANT G — posterize amount for the green channel, 256 levels at min down to 2 at max. Affects video_out and g_out. |
| QUANT LUMA | QUANT LUMA — posterize amount for the Rec.601 luma, 256 levels at min down to 2 at max. Drives luma_out and applies an overall luma-depth reduction to video_out as a hue-preserving ratio. |
| QUANT R | QUANT R — posterize amount for the red channel. min = 256 levels (full depth / passthrough), midway = 32 levels, max = 2 levels (on/off). Affects video_out and r_out. |
source
freezeframe.ts on GitHub.