Important
Already running StemDeck on Windows or Linux? This one needs the full download.
Automatic song structure adds a Python dependency, and the in-app updater replaces
the app and its backend but never the Python runtime underneath them. Rather than
offer you an update that would start and then fail on a missing package, StemDeck
stands down and sends you here. Take the package for your setup from the table
below and unzip it over a fresh folder; your library and settings live outside the
app folder and are not touched.
Important
macOS first launch (no code signing yet). After dragging StemDeck to Applications, clear the Gatekeeper quarantine flag or macOS will say the app is damaged:
xattr -dr com.apple.quarantine /Applications/StemDeck.app
Which file do I download?
| Your setup | Download |
|---|---|
| Windows, NVIDIA GPU | StemDeck-Windows-x64.NVIDIA.zip
|
| Windows, no NVIDIA GPU | StemDeck-Windows-x64.zip
|
| Linux, NVIDIA GPU | StemDeck-Linux-x64.NVIDIA.tar.gz
|
| Linux, no NVIDIA GPU | StemDeck-Linux-x64.tar.gz
|
| macOS, Apple Silicon (M1-M4) | StemDeck-macOS-arm64.dmg
|
| macOS, Intel | StemDeck-macOS-x64.dmg
|
| Docker / Unraid | Nothing here - pull ghcr.io/stemdeckapp/stemdeck:0.16.0
|
Pick one. Each Windows and Linux download is complete on its own: unzip and run, no installer, no toolchain. Everything else in the asset list is used by StemDeck itself - in particular the small -app files are the updater's payload and will not run on their own.
On the GPU variants: both ship the same small package. The NVIDIA build downloads the CUDA components matching your card on first launch, so it needs a working NVIDIA driver. If you are unsure, take the non-NVIDIA one - it works everywhere and you can switch later.
What's new in 0.16.0
StemDeck can name the parts of a song, and the studio finally fits on a laptop.
Automatic song structure, transposing one instrument without the others, zoomable
waveforms, panels you can fold away, and Korean.
Name the parts of a song without finding them by ear
StemDeck could tell you where every beat was and nothing about where the song
went. Turn on Song structure beside Split stems and, after separation, the
sections bar fills itself in: intro, verse, chorus, bridge, solo, outro.
It is off by default and it goes back to off as soon as you open another song.
The pass costs minutes of CPU, so it is a choice about the next import rather
than a setting that keeps spending long after the song you switched it on for.
The suggestions are draggable and editable, and repeated kinds are numbered
rather than merged. Two neighbouring choruses are a real predicted boundary, and
merging them threw away five true ones on the track this was built against.
Sections can also be cleared in one go now, with the button arming on the first
click because clearing cannot be undone.
Labels come from a model trained on a fixed set of functional names, which has
no class for a refrain or a pre-chorus, so some sections cannot be named
correctly by construction. They are suggestions, and they stay editable.
Move one instrument without moving the rest
Transpose the whole track from the footer, or a single lane from the mixer. Each
lane keeps its distance when you move the global key, so a guitar you put two
semitones up stays two above wherever the song goes.
Drums are never transposed. Not on the global control, not per lane, not by
a future caller passing the wrong argument.
Zoom the waveforms
Scroll over the lanes to zoom between 1x and 5x, anchored on the pointer so the
moment under the cursor stays under it. Shift-scroll pans, and loops work at any
zoom and survive it untouched.
The bars themselves do not change: 5.000 pixels per bar at 1x and at 5x, 182
bars across 910 px becoming 910 bars across 4550 px. Zooming buys detail rather
than fatter strokes. The ruler subdivides with it instead of spreading the same
handful of labels across five screen widths.
5x is where the stored waveform data runs out rather than a round number, and 1x
is a floor because there is nothing to see below a whole track on screen.
Six stems separated, six stems visible
On a 1366x768 laptop the mixer used to show two of six lanes. It now shows five,
and six with one click.
The analysis header went from 147 px to 73 px for the same seven numbers, its
two rows now share one seven-column grid, and the footer is a single line that
does not rearrange itself at every window width. Three toggles under the
composer fold away the analysis header, the sections bar or the timeline and
hand the height straight to the mixer.
Three lane bugs went with it. The lanes were sized once when a track loaded and
never fitted the panel again, so a 1200 px tall window left 432 px unused. A
stem name and its waveform drifted apart as you resized, by 55 px at the bottom
of the mixer. And the mixer VU meters were using about a tenth of their bar.
한국어, and Español
Two new languages, eleven in total. Korean does not inflect nouns for number, so
its plurals are written the way Japanese and Chinese are here, and the audio
words a Korean musician already uses are left as they are rather than translated
into something nobody says.
A test now refuses to let the next language ship unreachable. Adding a table
without teaching the app which browser locales should pick it fails the suite,
rather than shipping a language nobody can find.
Fixes
Exporting a track over about 50 minutes as WAV failed with a 500, after the
full render had already been paid for. A single render larger than the whole
cache budget put the cache over on its own, so the prune deleted it, newest and
only entry though it was. StemDeck accepts 60 minutes, so this was a supported
track failing.
A crash during song-structure analysis left up to 1.3 GB hidden in the stems
folder. Dot-prefixed, so invisible, and nothing else in the codebase had heard
of the prefix. A sweep now runs once at startup, when nothing can be analyzing.
One editor request could stall every other request to the server. A sections
save accepted a list of any length and held everything else behind it, including
a running job's progress stream: an idle health check went from 32 ms to 5219 ms
behind a 33 MB body, and it needed no valid job to do it. The same request now
answers in 16 ms.
RIFF and data chunk sizes were wrong on WAV export, so the header did not
describe the file that followed it.
A Windows portable install could report that another program was using port
8000 when the process it named was StemDeck's own backend.
0.15.1 could delete existing library jobs from disk during startup.
Retention is off unless you turn it on, and is now visible in Settings.
A backend started outside the desktop shell read the wrong settings file.
The app and the docs invited people to two different Discord servers.
The Unraid template named a version that was no longer the current one.
Under the hood
Browser tests could not run from a Windows checkout at all, which meant the
suite that drives the real UI only ever ran in CI.
The streaming render path had no coverage, and looking for its canvases the
obvious way said it was broken. It was not: that renderer draws inside shadow
roots, and the usual way of finding an element does not cross that boundary. The
false negative is now written down next to the test, because the next person to
look would have reached the same wrong conclusion.
Verified
Nine real tracks were run through automatic song structure with inference cached,
so before and after were compared on identical model output. Two tracks that
produced nothing now work, and none regressed. The reference track's thirteen
sections match the recorded timings to within 4 ms.
Lane alignment is checked at twelve window heights from 720 to 1300, including
the range where the lanes overflow rather than fit, which is where the 55 px
came from.
Every new guarantee in this release was checked against a deliberately broken
build first, so a passing test means the fix is doing the work rather than the
test agreeing with itself.
Issues closed
#245, #447, #457, #458, #459, #462, #463, #465, #467, #468, #470, #476, #477,
#478, #481, #482, #483, #484, #485, #487, #488, #489, #490, #492, #494, #497,
#498, #499, #501
#480 stays open. Folding the panels away is a way to reclaim the space, not a
decision about what the studio shows when you first open a track, and folding is
all or nothing per panel where that report asked for one row of it.
#475 was closed without a change. The player greys out stems that exist on disk
because when you extract a subset, the Original lane is the sum of the stems you
did not pick; playing those files alongside it would play them twice.