Releases: finnmckenty/NTSCRT
Release list
NTSCRT 0.8.0
Keyframe animation works on video, not just stills.
Load a clip, toggle Animate, and keyframe the whole effect chain along it — clean at the start, hammered by the end, a tracking error sweeping through the middle. Export applies the animation frame by frame.
- The timeline replaces the transport bar on video. Same play button and scrubber, with the keyframe track underneath — the playhead is the video position, so scrubbing it seeks the footage and there aren't two scrubbers disagreeing about where you are.
- Length and frame rate come from the clip, shown rather than editable, since the source dictates both. Keyframe times stay proportional, so a preset saved from a still applies to a clip with its keys spread along it.
- Everything that worked on stills still does: keys hold parameters you didn't touch, editing while parked on a keyframe updates it in place, and per-keyframe easing is unchanged.
Universal binary (Apple Silicon + Intel), signed and notarized. The Intel half remains community-tested — see the README.
NTSCRT 0.7.0
Preset library in the menu, and integer scale snaps again.
- Bundled presets — the Preset menu now lists ready-made looks (Glitch 1, Glitch 2) underneath Save and Load. Loading one that carries keyframes opens the timeline with it, so the animation it brought is visible rather than hidden. Presets save and restore everything: downscale, NTSC, shader, view, and the whole timeline — duration, frame rate, and every keyframe with its easing.
- Integer scale snaps again — 0.6.0 regressed it: the preview scaled smoothly to fit instead of stepping between whole multiples, toggling it barely changed anything, and toggling while zoomed shifted the magnification. It now displays at an exact whole multiple of the downscale resolution, letterboxed, stepping as the window grows — while still rendering at enough rows per source line that the look doesn't change with window size. The two pull against each other, which is how the regression slipped through, so the rules are now covered by tests that run as a release gate.
Universal binary (Apple Silicon + Intel), signed and notarized. The Intel half remains community-tested — see the README.
NTSCRT 0.6.0
Clearer labels, a snappier sidebar, and disclosure triangles you can actually hit.
- Sidebar renamed and reorganised — VHS (ntsc-rs) is now NTSC (TV) and Shader is now CRT, matching what the app is. Scale is now Intensity and sits at the top of the NTSC section, where the control you reach for most belongs, with Horizontal / Vertical intensity inside it. The four loose chroma controls are collected under Chroma distortion. The toolbar's Timeline button is now Animate. Labels only — every setting keeps its name and value, so presets still round-trip with the ntsc-rs desktop app.
- Disclosure triangles are clickable — the twirl was a chevron with roughly eight points of hit area, so a click landing slightly off did nothing, which felt like lag instead of a miss. It's now a proper target, and section headings toggle from anywhere in the row.
- The sidebar stays responsive while the preview animates — the analog stage is CPU work that runs on the same thread as the UI, and it was taking about 62% of it. Animate now runs at 30 fps while that stage is on (NTSC is a 30 fps format, so nothing is lost), and the stage no longer re-reads a still image it already has every frame. Main thread went from 62% busy to 27%.
Universal binary (Apple Silicon + Intel), signed and notarized. The Intel half remains community-tested — see the README.
NTSCRT 0.5.0
Animated GIF export, and a round of rendering fixes.
- GIF export — GIF joins the codecs in the export panel, for stills (with keyframe animation) and for video sources. It gets its own width and frame rate, because it behaves nothing like the video codecs: 256 colours and run-length compression against full-frame analog noise means files run large. A 5-second 480px GIF at 12 fps lands near 8 MB; the panel estimates the size before you export and warns past 10 MB. Frame delays are stored in hundredths of a second, so the rates land on that grid (12 fps plays at 12.5, 24 at 25) and the panel tells you.
- Scanline banding in exports — CRT shaders draw scanlines in output pixels, so an export size that isn't a whole multiple of the downscale height gave one source line a fractional number of rows, and the scanlines grouped into visible bands. Exports now render at a whole multiple and average down, so any size works. Snap size to scanline grid takes the other route: it rounds the output to a size where every source line gets the same whole number of rows.
- Preview banding with integer scale — the integer-scale letterbox centred on a half pixel whenever the drawable and the render differed by an odd number, putting every sample on a texel boundary and duplicating rows. It now letterboxes on whole pixels.
- Window size no longer changes the look — with integer scale on, the chain rendered at whatever multiple fit the window, and since CRT shaders work in output pixels, that multiple was the look: small windows lost their scanlines entirely and blew out the highlights. The multiple now has a floor independent of the window, and oversized renders are downsampled for display. The preview matches the export at any window size.
Universal binary (Apple Silicon + Intel), signed and notarized. The Intel half remains community-tested — see the README.
NTSCRT 0.4.0
Animate a still image and render it as video.
- Timeline — load an image, toggle Timeline in the toolbar, and keyframe the entire effect chain over time. Scrub the playhead, dial in a look, press Keyframe; move the playhead, dial in another look, keyframe again. Everything keys together as one master keyframe, so parameters you don't touch between keys hold still on their own.
- Editing is live — click a keyframe and change any VHS or shader parameter, and that keyframe updates in place, the way After Effects and Premiere behave.
- Interpolation per keyframe — linear, ease in, ease out, ease in-out, or hold, from the dropdown under each keyframe. Drag a diamond to retime it; keyframe times are proportional, so changing the duration stretches the whole animation.
- Video from any still, even with no keyframes — tape noise, jitter, head switching and interlacing animate on their own. Set length and frame rate (12/24/30/60 fps) in the timeline; export uses them.
Fixes and changes
- The compare divider no longer disappears when dragged to either edge.
- Tooltips display properly on the floating view controls, and appear sooner (macOS's ~2s default was long enough that they read as missing).
- Lighter house defaults: the lowpass filter starts on Butterworth (sharper), and horizontal/vertical scale start at 0.3, so the out-of-the-box look is less aggressive. Saved presets keep their own values.
Universal binary (Apple Silicon + Intel), signed and notarized. The Intel half remains community-tested — see the README.
NTSCRT 0.3.0
The interface got out of your way:
- Toolbar — Open (⌘O), Preset save/load, and Export (⌘E) now live in the window toolbar. Export is a popover with the codec / quality / bitrate flow, and the toolbar button shows live progress while a video export runs.
- Floating view palette — Compare, Integer scale, Animate, and zoom float over the preview and fade out when the mouse goes idle.
- Transport bar — videos get a full-width, frame-accurate scrubber docked under the preview (play/pause + frame/time/fps readout).
- The sidebar is now purely creative controls, top to bottom in signal order: Source → Downscale → VHS → Shader.
Universal binary (Apple Silicon + Intel), signed and notarized. The Intel half remains community-tested (see README).
NTSCRT 0.2.0
Signed and notarized — download, open, drag to Applications. macOS 14+, now a universal binary (Apple Silicon + Intel).
Intel note: NTSCRT is developed and tested on Apple Silicon; the author has not personally tested the Intel build. Intel support comes from a contributed fix (#1, thanks @fuxkspecial) verified on an Intel iMac Pro. If anything misbehaves on your Intel Mac, please open an issue.
New
- Universal binary — one download runs natively on Apple Silicon and Intel (Intel needs a discrete-GPU texture-sync fix that landed via #1)
- Export codecs & quality — H.264/HEVC with resolution- and framerate-scaled quality tiers (Standard → Maximum, live Mbps readout), plus ProRes 422 / 422 HQ
.movfor edit workflows. Scanline detail eats bitrate; the tiers are sized accordingly - App icon
- VHS stage hits harder by default — "Scale with video size" is now on (ntsc-rs effects are sized in signal lines; at HD+ input resolutions they were proportionally tiny), scale factors default to exactly 1.0, and head switching actually works out of the box (offset ≥ height silently disables the effect — defaults fixed, and the panel now warns when you cross that line)
Fixed
- Head switching was completely inert with the previous default settings
- Intel Macs: VHS stage produced noise-only frames and PNG exports were black (#1, reworked to Metal's documented managed-storage pattern — byte-identical output on Apple Silicon, verified)
Verification notes
Shader output is byte-identical to v0.1.2 across all 7 presets (librashader pinned; a newer upstream would have changed crt-royale rendering). The Intel slice was exercised under Rosetta: shader output byte-identical to arm64; the NTSC stage differs by 4 pixels in 307,200 at 1 LSB (SIMD rounding).
NTSCRT 0.1.2
Signed and notarized — download, open, drag to Applications. macOS 14+, Apple Silicon.
New
- Nearest+ sampling — nearest-neighbor punch without the temporal shimmer on video (a narrow-Gaussian stabilized point-sample; measured 3× less frame-to-frame flicker than Nearest)
- Collapsible sidebar — every section and sub-section folds down with a twirl, so dialed-in settings get out of your way; View controls moved to the top
Fixed
- Typing exact values into numeric fields could mangle the input (e.g. "120" becoming "1,620")
- Uneven scanline spacing with Integer scale at odd multiples (integer scaling now snaps to even multiples, where scanlines are pixel-exact)
- Sidebar content clipped at the left edge
- Expanding large sections (VHS) was laggy
NTSCRT 0.1.1
Signed and notarized — download, open, drag to Applications. macOS 14+, Apple Silicon.
Changes
- Any aspect ratio: the downscale is now width-only — console presets read "SNES (256px)", "VGA (320px)", etc., and the vertical resolution always follows your source's aspect ratio. Widescreen, portrait, square: all work. Custom widths via the dropdown's Custom option or by editing the width field.
- Sidebar reorder: Export and Preset (formerly "Look") now sit right under Source for quicker access.
- Fixed: the Animate toggle froze the preview if turned off and back on.
NTSCRT 0.1.0
First release of NTSCRT — vintage analog TV / VHS looks for stills and video: ntsc-rs signal emulation into RetroArch CRT shaders (via librashader). All the image magic belongs to those projects; this app glues them together.
Requirements: macOS 14+, Apple Silicon.
Install: download the DMG, open it, drag NTSCRT to Applications. The app is signed and notarized — no security warnings.
What's inside
- 7 RetroArch CRT presets (crt-royale, crt-hyllian, crt-aperture, crt-easymode, crtglow ×2, crtsim) — frame-identical output to RetroArch
- Full ntsc-rs VHS stage (composite artifacts, tape noise, head switching, tracking) with its complete settings schema; preset JSON is interchangeable with the ntsc-rs desktop app
- Pipeline: NTSC at full resolution → downscale → CRT shader
- Live compare split (processed vs original), integer scaling, animated preview, video playback
- PNG and MP4 export; save/load complete looks as JSON files