Skip to content

Adding a Windows build - #1

Merged
CatastrophicCoder merged 25 commits into
mainfrom
windows-ci
Oct 3, 2026
Merged

CatastrophicCoder merged 25 commits into
mainfrom
windows-ci

Conversation

@CatastrophicCoder

Copy link
Copy Markdown
Owner

No description provided.

CatastrophicCoder and others added 25 commits October 2, 2026 11:39
docs/windows.md sets out what already ports, what has to change, and the
decisions that are not technical. The new Windows job is its first step:
configure, build and run ctest with MSVC and Ninja, with no validation,
packaging or release, to find out which of the expected problems are real.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A model prepared before the device was open reached prepare() with a host
rate and block size of zero. The rate ratio was then infinite, its product
with the zero block NaN, and NaN cast to int undefined: 0 on Apple silicon,
INT_MIN on x64, where the Windows build threw "vector too long". With no
host settings the resampler is now passthrough with nothing sized; AmpModel
already refuses such a model and re-prepares it once the settings arrive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Same validator and strictness as the macOS job. The standalone and the VST3
are uploaded as a run artefact for trying by hand; not an installer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pluginval.exe is a GUI-subsystem program and PowerShell does not wait for
those: the step returned five seconds in, during the editor tests, and
passed without a result. bash waits and propagates the exit code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The host check is now built on Apple only: it hosts the AU and looks for
the bundles in ~/Library, neither of which exists on Windows, and with it
in the way AMPSIM_BUILD_TOOLS could not be turned on there. The benchmark
runs at 48 kHz and at 44.1 kHz, the second with the resampler in the chain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The footer said 48 kHz whatever rate the benchmark was given, which the
44.1 kHz run on the Windows runner made visible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An experiment to separate the runner's hardware from the code it runs: the
benchmark alone, rebuilt with /arch:AVX2, run in the same job as the
default build and interleaved with it. The step fails if the flag does not
reach the compile lines, so a no-op comparison cannot pass for a result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
/arch:AVX2 measured 27 to 38 % cheaper on the amp model on the same
runner. It is set for every MSVC-style build ahead of nam_core and the
plugin, so Eigen gets AVX2 and FMA. The SSE2 comparison is gone from CI;
the benchmark step now fails if the flag stops reaching the compiler,
since nothing else would notice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Four more builds of the benchmark alone in the Windows job, each different
from the normal build in one thing: NAM_ENABLE_A2_FAST, NAM_USE_INLINE_GEMM,
NAM with whole-program optimisation, and clang-cl with lld-link. They run
on the same runner in alternating order, and each is allowed to fail
without costing the others their measurements.

The benchmark now prints what it was built with and whether NAM took its
A2 fast path, which it does silently. The bundled capture is a
SlimmableContainer of two A2-shaped WaveNets, so the check looks inside
containers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NAM's own CMake defines NAM_ENABLE_A2_FAST by default; this project builds
NAM itself and had left it compiled out. The bundled capture is two
A2-shaped WaveNets, and the path measured 3 to 7 % cheaper on the Mac.

It is a second implementation of the same model, so the new test builds
each bundled submodel both ways from the same weights and null-tests them:
-122 and -132 dB apart. The -100 dB threshold fails a single weight changed
by 1 % (-77 dB), and the test fails outright without the define.

The CI experiments have answered their questions and are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Avenir Next and Futura ship with macOS only, and are commercial faces that
cannot be embedded. Figtree replaces Avenir for the interface and Jost
replaces Futura for names printed on objects, on every platform. Both are
OFL with no Reserved Font Name; the files are static Regular and Medium
instances of the google/fonts variable fonts, with the licences beside
them. Figtree is also the look-and-feel's default sans, so JUCE's own
popups no longer fall back to the system font.

Every height on the panel was chosen for the old faces, so each new one is
scaled to put its capitals where theirs were, from cap height over ascent
plus descent measured in the font files. Unscaled, the tempo reading was
cut off as "120 BP..." and every printed name shrank; scaled, the three
pages match the old ones closely.

tools/PanelSnapshot.cpp renders each page to a PNG. It is how this was
checked, and the Windows job now runs it and uploads the images.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cally

The C++ runtime is now linked statically on Windows, so neither the
standalone nor the VST3 needs the Visual C++ redistributable; the
packaging script refuses a binary that still imports it.

packaging/windows/AmpSim.iss asks whether to install for everyone or for
the current user, and puts the VST3 in the system or the per-user VST3
folder to match. It refuses a processor without AVX2, since the build would
crash its host there, and requires Windows 10 2004, the first version that
answers that question. The VST3 and the standalone are separate
components, the licences always go with them, and uninstalling leaves the
user's presets.

packaging/package-windows.ps1 builds, checks and stages, and runs ISCC with
the version read from CMakeLists.txt. CI builds the installer on every run,
installs it both ways, installs it again over itself, and uninstalls it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JUCE's documentation for prepareToPlay says hosts may exceed the block size
it announces. Every buffer in the chain is sized to that announcement, so a
bigger block wrote past the end of them: a test that announces 64 samples
and sends 1024 crashed with a segmentation fault, after an assertion in the
drive pedal's oversampler. This is the likely cause of the corrupted output
heard with the Windows standalone in WASAPI exclusive mode.

processBlock now takes an oversized block in pieces no larger than it was
prepared for. The metronome offsets the host's position by where each piece
starts, so it stays on the grid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every Windows Audio mode goes through Windows' audio engine, which on the
Audient iD4 tested by hand stopped at a 10 ms period and 44.1 kHz. ASIO
uses the interface's own driver. The headers are those bundled with
JUCE 9, from Steinberg's SDK under its GPLv3 option, compatible with the
AGPLv3; the installer ships the SDK's licence, and CI checks that both it
and JUCE_ASIO=1 make it into the build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The macOS job used to publish on its own. A release job now runs on v* tags
once the macOS and Windows jobs have both passed, checks the tag against
CMakeLists.txt once, and attaches the .pkg, the .dmg and the Windows
installer together, with notes covering both platforms' requirements.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README, the user guide and packaging/README.md describe installing on
Windows, its requirements, and playing through ASIO rather than Windows'
shared audio path, with the guide's troubleshooting covering what came up
on real hardware. CHANGELOG.md records Windows, the new typefaces, the A2
fast path and the two fixes. CLAUDE.md drops Windows from what is out of
scope and describes the Windows build, CI and release job; the roadmap
moves Windows to Done and leaves signing as the open question.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CatastrophicCoder
CatastrophicCoder merged commit 44769dd into main Oct 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant