Booth notes · why these seven exist

Not a feature list. Reasons to build the app.

Free / no paywall / no account is half the story. The other half is these seven choices — the homepage cards. They are the primary reasons StentorDecks was written at all: booth software that behaves like an instrument when money is not the product.

Companion to the engineering essay · operator how-tos in Docs

Two refusals started this project. One was commercial: stop renting the right to mix your own files. The other was craft: stop accepting DJ software that shrugs at PA jumps, robotic SYNC, unnatural jog wheels, unreadable waveforms, “library in the cloud,” fake cueing, and trust-me binaries.

Each card below is a design decision with a motive — what you feel in a set, why we chose it that way, then the short under-the-hood note for people who care.

An engine, not an app

In the booth

You are not fighting a playlist UI. You have two decks, channel faders, EQ, filter, a bit of flanger when you want colour — and the room stays safe when a hand slips.

Master starts quiet on purpose (~30%). Soft takeover means a physical knob does not jump the PA after you loaded a track or clicked the screen. The limiter is the last seatbelt, not a loudness cheat.

Why we built it this way

Because the itch was not “another skin over a store.” It was a controller under the stairs and software that had become a shopping cart. We wanted a mixer-shaped brain: continuous controls with manners, gain staging that assumes humans are tired at 2 a.m., and zero mystery about who owns the fader — mouse or MIDI, same path. If the PA flinches after a load, the tool failed its job. That failure mode is exactly why this card exists.

A good booth tool disappears. You think about the next phrase, not about which menu owns the gain.

Under the hood

Web Audio graph per deck: decode → EQ → filter → FX wet/dry → channel fader curve → buses. Gain and continuous params use ≥ 15 ms ramps (setTargetAtTime / linear), never a naked .value slam mid-playback. Master path ends in a DynamicsCompressor safety limiter after master gain. Soft takeover is a pure state machine shared by mouse and MIDI — same store actions, same pickup mark. Spec first; “sounds fine” is not a test.

A library that does its homework

In the booth

Point StentorDecks at your folders once. While you sleep (or while you mix), it fills in BPM, Camelot key, beatgrid, waveforms. Folders on disk stay the crates — the app never moves or deletes your files.

Damaged old MP3s? Check MP3 / Write fixed WAV builds a sibling named (Fixed by SD). Your original stays untouched. Optional harmonic sort and Next up help pick the next tune — you still load by hand.

Why we built it this way

Because real crates are folders, not a subscription locker — and because analysis you already paid for (with time) must survive a rename. Cloud libraries and “re-rip it” lectures treat your history as disposable. We built identity + offline analysis + repair-as-sibling so the library is yours: prep once, trust it on Saturday, never hostage to an account. That respect for the crate is a founding reason for the app, not a checkbox.

Under the hood

Identity = path + size + mtime + partial content hash. SQLite holds BPM/key/grid/peaks/loudness; analysis never blocks the mix. Mixmatch is pure rules (Camelot + BPM) — no cloud, no auto-load into a playing deck. Resilient decode stitches VBR mess; repair never overwrites the source.

Waveforms you can read from a meter away

In the booth

At one metre, in a dark room, with tired eyes, you need the drop to be obvious — not a grey scribble. Overview + scrolling detail stay beatgrid-aware and high contrast. When the track is pitched, the waveform scroll matches what you hear.

Big numbers for BPM and key. Remaining-time warnings before you talk over the outro. Instrument panel, not spreadsheet.

Why we built it this way

Because booth UI is a safety and timing surface, not a brand canvas. If you cannot glance the phrase structure while talking to someone, the design failed. We locked glanceability and accessibility floors in the spec on purpose — no shrinking type to “fit more features.” Readable waveforms are why the Performance screen exists in this shape; they are not decoration bolted on later.

Under the hood

One shared rAF frame clock samples both transports into typed arrays and draws canvases outside React — no private loops that crawl out of sync. Rate-aware visual position; analysis peaks for overview/detail. UI tokens and row heights from the style guide are non-negotiable.

SYNC with manners

In the booth

StentorDecks is manual-first. SYNC is a helper, not autopilot. Hit it: tempos meet, beats line up once. Keep mixing with the jog — it does not fight you. Turn SYNC off and the phase does not jump; nudge the jog and it retargets; move the pitch fader and glue lets go.

Load a new track on the master? The follower’s SYNC clears and its pitch freezes — so the playing deck does not leap mid-phrase.

Why we built it this way

Because bad SYNC is why people swear off sync forever — and then suffer for it when they need a hand. We spent more ink on SYNC manners in the requirements than some products spend in a marketing bullet: assist, then get out of the way. The choice to stay manual-first with phase glue and pitch-freeze-on-master-load is not taste; it is the difference between a tool that trusts the DJ and one that hijacks the set. That difference is a primary reason to write our own stack.

Under the hood

Engage matches master’s pitch-fader BPM, then a one-shot beatgrid snap. Soft phase assist with hysteresis while lit; phase-glue when off. Playing seeks use overlap crossfades (~10–15 ms) so you never zipper with a cold stop/start.

Natural jog feel

In the booth

Natural is the whole point. Your hands should not relearn a fake control scheme — the wheel should answer like gear you already trust: a Technics SL-1200 or a CDJ. Slow rim rides the beat (tempo bends, phase creeps). A flick is a real nudge. Stop turning: the pitch fader owns tempo again, and your phase offset stays — no rubber-band snap back.

Paused: scrub. Soft is the default natural feel. Hit Vinyl on the RMX2 (or Spinny in Settings) when you want platter drama / spinback. Full scratching stays out of v1 — we spent the budget on beatmatch jogs that feel right, not on theatre that fights the mix.

Why we built it this way

Because natural feel is what lets you mix without thinking about software. Dead, laggy, or skippy jogs break that contract — and they are everywhere. We obsessed over Soft-mode manners (ride, nudge, sticky phase) so the RMX2’s platters feel continuous and honest, the way SL-1200 / CDJ muscle memory expects. That obsession is a primary reason this app exists. If the jog lies, manual mixing dies and SYNC becomes a crutch. We refused that.

Under the hood

Relative MIDI → rim-speed EMA regimes in shared/jogFeel — tuned against real RMX2 traffic for natural continuity, not a one-line sensitivity slider. Soft (default): slow rim = temporary rate ride; faster rim = stronger nudge + tiny sticky seasoning — deliberately not seek stairs. Vinyl / dual-zone: fine sticky seek + spinback on sustained whip. Playing seeks use ~10 ms overlap crossfades. Jog mutes soft phase assist briefly and retargets post-SYNC phase glue. Partner jog never yanks a SYNC slave’s pitch-only BPM reference. Presets: Soft · Balanced · Spinny.

Real headphone cueing

In the booth

Pre-listen like a mixer: PFL the incoming deck, blend cue vs master in your cans with HeadMix / CUE, level with PHN. The drop on the floor should be exactly the one you heard in headphones — not “close enough.”

On the RMX2, Plan A uses four outputs (booth + phones). The hardware phones knob is analog after the DAC; software PHN is the digital level before that.

Why we built it this way

Because headphone cueing is how you decide before the room hears it. Fake “cue” that is just master-ducked, or a driver quirk, trains bad habits and kills confidence. We insisted on a real PFL bus and equal-power cue/mix blend so prep in cans maps to the PA. If cueing is wrong, nothing else about the mixer metaphor matters — so this card is load-bearing, not a nice-to-have.

Under the hood

Per-deck pre-fader PFL into a cue bus; headphone = equal-power blend of cue sum vs master, then headphone gain. VU with PFL shows max(pre, post). Cue-point rules are Pioneer-ish; load resets cue to 0:00 on the new buffer.

Honest engineering

In the booth

You should not need a developer hat to trust the tool. When SmartScreen complains about an unsigned build, or someone asks “is this spyware?”, the answer is boring and good — read the source, no account, no telemetry maze, updates from GitHub Releases you can see.

Features we skipped on purpose stay skipped so the two decks you do have behave under pressure.

Why we built it this way

Because “free” without auditability is just a different kind of trust fall. Open source, typed boundaries, tests that run without your RMX2 plugged in, and specs that win over vibes — that is how you earn the right to ask someone to run an installer at a gig. Alongside refusing paywalls, honesty as a product feature is why StentorDecks exists as a public repo instead of a closed “indie” binary with a tip jar and a shrug.

Under the hood

TypeScript strict, Electron process boundaries, sandboxed renderers, typed IPC. ~200 automated tests; MIDI from recorded fixtures. Spec docs win over “sounds fine on my machine.” Auto-update needs a full release with latest.yml.

That is the deal: refuse the shopping cart, then sweat these seven so the booth still works. Download it, play a set, file an issue if reality disagrees.

↓ Download StentorDecks for Windows
Longer engineering essay →  ·  DJ docs →