A native Windows build of Lavboard, in progress. The macOS app in App/ is the reference for features and behaviour.
src/LavboardEngine: the native audio engine, a C++ DLL. It compiles the real-time mixer and resampler fromShared/AudioCore(the same C code the macOS app runs) and adds the Windows device layer on WASAPI.src/Lavboard.Core: everything testable without a window: tracks, the mic-system contract and modules, engine planning, recording, settings, and P/Invoke bindings to the engine.src/Lavboard: the app, WinUI 3 on the Windows App SDK, unpackaged and self-contained.Themes/: the console design tokens (Console.xaml, transcribed from the macOSTheme.swift) and control templates.Controls/: the console's parts: LED meters, faders, keys, tape labels, and macOS-style pop-up buttons, check boxes, switches and segmented controls.Views/: the window's sections, one per macOS view: track and master strips, desk, transport bar, popovers and menus.Model/: app state, the mic-system contract and the demo scenes.Assets/Fonts/: Inter and Barlow Condensed (SIL Open Font License), standing in for SF Pro and its condensed widths.
tests/Lavboard.Tests: xunit tests that run the shared core through the DLL, checking that the MSVC build behaves like the macOS one.tools/: helpers for building and testing over SSH.
Windows has no aggregate devices, so the engine does by hand what a macOS aggregate does. One endpoint clocks the mixer: a wireless receiver if a track uses one, else the first other input a track uses (never Bluetooth), else an output. Its audio reaches the mixer directly, on a pro-audio thread driven by its WASAPI events. Every other input, app audio (process loopback) and every output that isn't the clock runs on its own thread through the shared async resampler, which follows that device's clock with the same drift control the macOS app uses for Bluetooth mics. EnginePlan in Lavboard.Core makes those choices, and its tests pin them down.
You need Visual Studio 2026 (or 2022 17.14 or later) with the Desktop development with C++, .NET desktop development and Windows application development workloads, the Windows SDK 10.0.26100 and the .NET 10 SDK.
From a Developer PowerShell:
msbuild windows\Lavboard.slnx -restore -p:Configuration=Debug -p:Platform=x64
windows\artifacts\bin\Lavboard.Tests\Debug\net10.0-windows10.0.26100.0\Lavboard.Tests.exe
windows\artifacts\bin\Lavboard\Debug\net10.0-windows10.0.26100.0\win-x64\Lavboard.exeUntil the WASAPI engine lands, the app shows a demo desk. --scene readme (the default) stages the README screenshot; --scene parity and --scene compact stage scenes a macOS debug build can show too.
dotnet build can't build the C++ engine, so use Visual Studio's msbuild (or open Lavboard.slnx in Visual Studio).
tools/LavProbe runs the engine without the window, for testing with real devices:
LavProbe devices # endpoints, formats, USB IDs
LavProbe apps # apps with audio sessions
LavProbe tone tone.wav --freq 1000 --level -12 # a test tone to play
LavProbe run --track "dev=CABLE Output:0" --venue "Speakers" --seconds 20 --record out
LavProbe analyze "out\Session ...\01 Track 1.wav" --freq 1000run prints meters and each resampler's buffer, correction and underruns every second; analyze reports a recording's level, frequency, dropouts and clicks. With VB-CABLE, play the tone into CABLE Input and capture CABLE Output.
SSH sessions have no desktop. On the dev VM, Start-Gui.ps1 launches an app on the logged-in desktop and Get-Screenshot.ps1 captures it. tools/Focus-Window.ps1 brings a window to the front first, since Windows won't let a background launch take the foreground.
Releases are Velopack packages: windows/scripts/Pack-Release.ps1 -Version 0.1.0 builds the app self-contained and packs Lavboard-win-Setup.exe, the full and delta packages and releases.win.json into artifacts/releases (install the packer first: dotnet tool install -g vpk). The Windows release workflow does the same on a windows-v* tag and publishes a GitHub release that is never marked latest (the macOS app's appcast lives at releases/latest). See CONTRIBUTING.
Installed copies check for updates on every launch, offer Update to x.y.z in the toolbar, and restart into the new version (never mid-recording). To test the update flow without publishing, pack two versions into one folder, install the older one, and point it at the folder with the LAVBOARD_UPDATE_FEED environment variable (a folder or URL).
The two apps should look the same. To compare them, run tools/parity-capture.sh on a Mac (it stages the parity scene in a debug build and captures the window), launch the Windows app with --scene parity at the same width, and compare the two side by side. Strip widths follow the same rules on both (DeskLayout here, Desk in ContentView.swift), so at window widths of about 1230 and up the strips match pixel for pixel.