From 4a621de6b1ff6623f35b9c0c8aa1a1419a5bda75 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Fri, 7 Aug 2026 11:27:29 +0200 Subject: [PATCH] =?UTF-8?q?chore(packaging):=20retire=20VB-Cable=20?= =?UTF-8?q?=E2=80=94=20audio's=20substrate=20is=20Steam's=20drivers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The other half of the audio-substrate decision (spikes S2+S3 green, minted endpoints landed in the previous commit): stop bundling a third-party kernel driver the host no longer needs. installer the VB-CABLE task, payload, silent-install run and the donationware notice are gone; a suppressible notice tells a Steam-less box that audio needs Steam INSTALLED (never running) and that installing it later just works. A cable from an older install is still deliberately not removed. packer + CI -VbCableDir/VBCABLE_DIR, the staged-payload check and the runner provisioning download are gone; SBOM drops the redistributed-driver component. winget the VB-Audio bundling-grant agreement becomes the honest Steam requirement (surfaced on the unattended path where no wizard is on screen). docs windows-host/uninstall/security/echo say what actually ships: no kernel-mode driver of our own, endpoints minted from Valve's vendor-signed drivers, VB-CABLE mentioned only as the historical fallback that keeps working. host wording the mic-open guidance and module headers lead with Steam; the NAME ladder itself is untouched — demoting 'cable input' was considered and rejected (on a box where minting transiently fails, the SSM would outrank an installed cable, steal the silent sink, and make audio host-audible). --- .gitea/workflows/sbom.yml | 2 +- .gitea/workflows/windows-host.yml | 8 -- compliance/sbom/manual-components.cdx.json | 8 -- .../src/audio/windows/audio_control.rs | 5 +- .../src/audio/windows/wasapi_mic.rs | 10 +- .../punktfunk-host/src/audio/wiring_plan.rs | 17 ++-- docs-site/content/docs/echo.md | 9 +- docs-site/content/docs/security.md | 14 +-- docs-site/content/docs/uninstall.md | 9 +- docs-site/content/docs/windows-host.md | 27 +++--- packaging/windows/README.md | 33 +++---- packaging/windows/install-vbcable.ps1 | 97 ------------------- .../windows/licenses/VB-CABLE-NOTICE.txt | 26 ----- packaging/windows/pack-host-installer.ps1 | 32 +----- packaging/windows/punktfunk-host.iss | 58 +++++------ packaging/winget/README.md | 4 +- .../winget/unom.PunktfunkHost.installer.yaml | 6 +- .../unom.PunktfunkHost.locale.en-US.yaml | 15 ++- scripts/ci/gen-sbom.sh | 4 +- .../ci/provision-windows-punktfunk-extras.ps1 | 26 +---- 20 files changed, 122 insertions(+), 288 deletions(-) delete mode 100644 packaging/windows/install-vbcable.ps1 delete mode 100644 packaging/windows/licenses/VB-CABLE-NOTICE.txt diff --git a/.gitea/workflows/sbom.yml b/.gitea/workflows/sbom.yml index 871bbdaa..8cfc4f34 100644 --- a/.gitea/workflows/sbom.yml +++ b/.gitea/workflows/sbom.yml @@ -9,7 +9,7 @@ # # What goes in: scripts/ci/gen-sbom.sh = syft over the checkout (every lockfile-pinned dep in # both Rust workspaces + the JS trees + Swift Package.resolved) merged with -# compliance/sbom/manual-components.cdx.json (vendored C/C++, bundled DLLs, VB-CABLE, gamescope). +# compliance/sbom/manual-components.cdx.json (vendored C/C++, bundled DLLs, gamescope). name: sbom # One pending run per workflow+ref: a newer push supersedes the queued/running one and cancels # it (a canary only needs the latest commit; each release tag is its own ref so tag runs never diff --git a/.gitea/workflows/windows-host.yml b/.gitea/workflows/windows-host.yml index 0b63931f..65050e73 100644 --- a/.gitea/workflows/windows-host.yml +++ b/.gitea/workflows/windows-host.yml @@ -148,13 +148,6 @@ jobs: if (-not $env:FFMPEG_DIR) { "FFMPEG_DIR=C:\Users\Public\ffmpeg" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 } - # VBCABLE_DIR: the pinned official VB-CABLE package (provisioned by - # provision-windows-punktfunk-extras.ps1) -> pack-host-installer.ps1 bundles the - # streaming virtual microphone. Same daemon-env-or-fallback pattern as FFMPEG_DIR - # (the daemon env only refreshes on a runner-task restart). - if (-not $env:VBCABLE_DIR) { - "VBCABLE_DIR=C:\Users\Public\vbcable" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8 - } $pf = & "$env:GITHUB_WORKSPACE/scripts/ci/pf-version.ps1" # single source of truth: base is one minor ahead of the latest stable tag $v = if ($env:GITHUB_REF -like 'refs/tags/v*') { $env:GITHUB_REF_NAME -replace '^v', '' @@ -404,7 +397,6 @@ jobs: @{ n = 'bun runtime (BUN_EXE)'; p = $env:BUN_EXE; f = '' } @{ n = 'plugin runner (SCRIPTING_BUNDLE)';p = $env:SCRIPTING_BUNDLE; f = '' } @{ n = 'FFmpeg DLLs (FFMPEG_DIR\bin)'; p = $env:FFMPEG_DIR; f = 'bin' } - @{ n = 'VB-CABLE (VBCABLE_DIR)'; p = $env:VBCABLE_DIR; f = 'VBCABLE_Setup_x64.exe' } ) $missing = @() foreach ($x in $need) { diff --git a/compliance/sbom/manual-components.cdx.json b/compliance/sbom/manual-components.cdx.json index 56587039..ba80fbb8 100644 --- a/compliance/sbom/manual-components.cdx.json +++ b/compliance/sbom/manual-components.cdx.json @@ -59,14 +59,6 @@ "licenses": [{ "license": { "id": "Zlib" } }], "externalReferences": [{ "type": "vcs", "url": "https://github.com/libsdl-org/SDL" }] }, - { - "type": "application", - "name": "VB-CABLE", - "version": "redistributed installer, see packaging/windows/install-vbcable.ps1", - "description": "Third-party kernel-mode virtual audio driver redistributed with the Windows host; notice at packaging/windows/licenses/VB-CABLE-NOTICE.txt. Planned to be replaced by an attestation-signed first-party driver.", - "licenses": [{ "license": { "name": "Proprietary freeware (VB-Audio Software, redistribution permitted per notice)" } }], - "externalReferences": [{ "type": "website", "url": "https://vb-audio.com/Cable/" }] - }, { "type": "application", "name": "punktfunk-gamescope", diff --git a/crates/punktfunk-host/src/audio/windows/audio_control.rs b/crates/punktfunk-host/src/audio/windows/audio_control.rs index f298296c..b40d5e93 100644 --- a/crates/punktfunk-host/src/audio/windows/audio_control.rs +++ b/crates/punktfunk-host/src/audio/windows/audio_control.rs @@ -3,7 +3,10 @@ //! //! A headless host has no real audio output, so BOTH the desktop-audio loopback ([`super::wasapi_cap`]) //! and the virtual mic ([`super::wasapi_mic`]) must run on VIRTUAL audio cables — and on DIFFERENT -//! ones, or the loopback re-captures the injected mic (an infinite echo). The installer bundles +//! ones, or the loopback re-captures the injected mic (an infinite echo). The host mints its own +//! endpoint pair from Steam's streaming drivers (see [`super::minted`] — the plan's tier-0); the +//! name-based ladder below covers boxes where minting is unavailable. Historically the installer +//! bundled //! VB-Audio Virtual Cable (the mic target: its "CABLE Input" render endpoint → "CABLE Output" capture) //! and the host auto-installs the Steam Streaming pair (a loopback-capable render). This module wires //! them up so no manual Sound-settings fiddling is ever needed: diff --git a/crates/punktfunk-host/src/audio/windows/wasapi_mic.rs b/crates/punktfunk-host/src/audio/windows/wasapi_mic.rs index 09b85bff..b27b9590 100644 --- a/crates/punktfunk-host/src/audio/windows/wasapi_mic.rs +++ b/crates/punktfunk-host/src/audio/windows/wasapi_mic.rs @@ -4,7 +4,8 @@ //! **capture** endpoint then surfaces as a microphone that host apps can record from. //! //! The target comes from the [`audio_control::wire_now`] plan (recomputed on every open): VB-Audio -//! "CABLE Input" (bundled by the installer — the dedicated mic target), the Steam Streaming +//! the minted "Punktfunk Microphone" (tier-0, see `super::minted`), then by name: VB-Audio +//! "CABLE Input" (bundled by installers until the audio-substrate change), the Steam Streaming //! Microphone, VoiceMeeter, or anything with "virtual" in the name; `PUNKTFUNK_MIC_DEVICE` overrides. //! The plan reserves the mic target and points the desktop-audio loopback at a DIFFERENT endpoint, so //! injecting here can never echo into the host→client audio stream (see @@ -238,9 +239,10 @@ fn resolve_target() -> Result<(wasapi::Device, String)> { ); } anyhow::bail!( - "no virtual-mic render endpoint on this box. Install VB-Audio Virtual Cable (the host \ - installer bundles it) or enable Steam Remote Play's microphone (Steam Streaming \ - Microphone), or set PUNKTFUNK_MIC_DEVICE=." + "no virtual-mic render endpoint on this box. Install Steam (the host mints its own \ + microphone endpoint from Steam's streaming drivers — Steam never needs to run), or \ + install VB-Audio Virtual Cable, or set PUNKTFUNK_MIC_DEVICE=." ); }; let name = ep.0.clone(); diff --git a/crates/punktfunk-host/src/audio/wiring_plan.rs b/crates/punktfunk-host/src/audio/wiring_plan.rs index 95e84162..04c9b059 100644 --- a/crates/punktfunk-host/src/audio/wiring_plan.rs +++ b/crates/punktfunk-host/src/audio/wiring_plan.rs @@ -12,12 +12,15 @@ //! //! WASAPI loopback captures *everything* an endpoint renders — including what the virtual mic //! writes — so if both land on the same device the client's voice echoes straight back into the -//! client's own audio stream. The plan therefore assigns the mic its endpoint FIRST (VB-CABLE is -//! bundled by the installer for exactly this) and gives the loopback a *different* one; when only +//! client's own audio stream. **Tier-0** avoids the collision by construction: the host mints +//! its OWN pair from Steam's streaming drivers ([`MintedIds`] — "Punktfunk Microphone" for the +//! mic, "Punktfunk Speakers" for the loopback, matched by ID because their names are identical +//! to Steam's primaries). Below tier-0, the name ladder keeps the old discipline: the mic is +//! assigned FIRST (VB-CABLE was bundled by installers until the audio-substrate change; a +//! user-installed cable still serves) and the loopback gets a *different* endpoint; when only //! the cable exists (headless box, no other output), the MIC wins and the loopback is honestly //! unavailable. The old code did the opposite — the mic refused the cable because it was the -//! default render endpoint — which permanently killed mic passthrough in the exact configuration -//! the installer ships (VB-CABLE as the only render device). +//! default render endpoint — which permanently killed mic passthrough on exactly that box. //! //! **One exception to mic-first — game audio outranks the mic.** The Steam Streaming //! Microphone's render side is ALSO the only silent client-only loopback sink, so the mic may @@ -192,9 +195,11 @@ impl Wiring { } /// Render-endpoint friendly-name substrings (lowercased) usable as the virtual-mic write target, -/// ordered by preference. VB-CABLE first: the installer bundles it for this exact purpose. +/// ordered by preference — the NAME ladder below the minted tier-0 ([`MintedIds`] outranks all +/// of these). VB-CABLE first among the names: installers bundled it for the mic until the +/// audio-substrate change, and a user-installed cable still serves. const MIC_CANDIDATES: &[&str] = &[ - "cable input", // VB-Audio Virtual Cable — bundled by the installer + "cable input", // VB-Audio Virtual Cable — user-installed / from older bundled installs "steam streaming microphone", "voicemeeter input", "voicemeeter aux input", diff --git a/docs-site/content/docs/echo.md b/docs-site/content/docs/echo.md index 59acbc14..5b82e549 100644 --- a/docs-site/content/docs/echo.md +++ b/docs-site/content/docs/echo.md @@ -27,11 +27,12 @@ leaving the stream; see [Input](/docs/input#getting-your-input-back). ## "Listen to this device" and app monitoring (Windows hosts) Windows can play a microphone straight out of the speakers. If **Listen to this device** is -ticked for the Punktfunk mic (usually *CABLE Output*), your voice plays on the host's output — -which the stream then captures and sends right back to you. +ticked for the Punktfunk mic — a *Steam Streaming Microphone*-class device on current hosts, +*CABLE Output* on older ones — your voice plays on the host's output, which the stream then +captures and sends right back to you. -Open **Sound settings → More sound settings → Recording**, double-click *CABLE Output*, and on -the **Listen** tab untick *Listen to this device*. +Open **Sound settings → More sound settings → Recording**, double-click the Punktfunk mic, and +on the **Listen** tab untick *Listen to this device*. The same loop hides in apps: **Discord's** *Mic Test* / input monitoring, **OBS's** *Monitor audio* on a mic source, and similar monitoring features in other tools all play your mic into diff --git a/docs-site/content/docs/security.md b/docs-site/content/docs/security.md index ad9e9dc3..1f8bfe8a 100644 --- a/docs-site/content/docs/security.md +++ b/docs-site/content/docs/security.md @@ -167,12 +167,14 @@ We mitigate this deliberately: - **Punktfunk's own drivers are user-mode.** The virtual display, both virtual-gamepad drivers (DualSense / DualShock 4 / Edge / Deck, and Xbox 360 / XInput) and the virtual pointer are **user-mode (UMDF)** drivers, so a driver bug is contained to a restricted service account — never - ring-0, never full-system. (This is why Punktfunk dropped ViGEmBus.) **One exception:** the - microphone-passthrough option installs VB-CABLE, a third-party **kernel-mode** audio driver from - VB-Audio. It's a ticked-by-default checkbox on the installer's task page — clear it if you don't - want it, though on a headless host (no real sound device) a virtual cable is also what desktop - audio plays into — and because other applications may use it, uninstalling Punktfunk leaves it in - place; remove it through its own uninstaller. + ring-0, never full-system. (This is why Punktfunk dropped ViGEmBus.) Audio is the one place a + kernel-mode driver is unavoidable (Windows has no user-mode way to create an audio device), and + Punktfunk deliberately ships none of its own: the "Punktfunk Speakers" and "Punktfunk + Microphone" endpoints are instances of **Steam's vendor-signed streaming-audio drivers**, + created on your box from your own Steam install. Older Punktfunk versions bundled VB-CABLE + (a third-party kernel-mode driver from VB-Audio) for the microphone; if you have one, other + applications may use it, so uninstalling Punktfunk leaves it in place — remove it through its + own uninstaller. - **Sealed internal channels.** The desktop-frame ring and the gamepad input/output channels are passed between the host and its drivers as duplicated handles to unnamed objects, so another local service can't open them by name to read your screen or forge controller input. diff --git a/docs-site/content/docs/uninstall.md b/docs-site/content/docs/uninstall.md index 49d4bdb2..8a1972de 100644 --- a/docs-site/content/docs/uninstall.md +++ b/docs-site/content/docs/uninstall.md @@ -210,10 +210,11 @@ Three things are left on purpose: Remove-Item -Recurse -Force "$env:ProgramData\punktfunk" ``` -- **VB-CABLE**, unless you cleared its checkbox during setup — it is ticked by default. It is a - third-party VB-Audio component other apps may be using, so the Punktfunk uninstaller never touches - it. Remove it with its own uninstaller — - `VBCABLE_Setup_x64.exe -u -h` — or the **VB-Audio Virtual Cable** entry in Installed apps. +- **VB-CABLE**, if an older Punktfunk version installed it (releases used to bundle it for the + microphone; current hosts use Steam's streaming drivers instead). It is a third-party VB-Audio + component other apps may be using, so the Punktfunk uninstaller never touches it. Remove it + with its own uninstaller — `VBCABLE_Setup_x64.exe -u -h` — or the **VB-Audio Virtual Cable** + entry in Installed apps. - **The publisher certificate**, if you imported it by hand to silence the Unknown Publisher prompt. Remove it in `certlm.msc` under **Trusted Publishers** and **Trusted Root Certification Authorities**. (This is *not* the driver certificate above, which the uninstaller does remove.) diff --git a/docs-site/content/docs/windows-host.md b/docs-site/content/docs/windows-host.md index 2d23a93c..730884a9 100644 --- a/docs-site/content/docs/windows-host.md +++ b/docs-site/content/docs/windows-host.md @@ -51,9 +51,10 @@ Download the signed `punktfunk-host-setup-.exe` from the displays, - installs the bundled **virtual gamepad drivers** (DualSense, DualShock 4, Xbox 360), - registers the bundled **HDR Vulkan layer** so Vulkan games can enable HDR over the virtual display, -- installs **VB-CABLE** (VB-Audio, donationware) as the virtual microphone for client mic - passthrough — a checkbox in the installer, **ticked by default**; clear it, or pass - `/MERGETASKS="!installaudiocable"`, if you don't want it, +- checks for **Steam** — game audio and microphone passthrough run through Punktfunk's own + instances of Steam's streaming audio drivers ("Punktfunk Speakers" / "Punktfunk Microphone"), + so Steam needs to be **installed** on the host (it never has to run). Without it the host + streams video only, and picks Steam up automatically whenever you install it, - adds a **status icon** to the notification area (see [Status tray](#status-tray)), - sets up the **web management console** (see below). @@ -72,12 +73,13 @@ winget source add -n punktfunk https://winget.punktfunk.unom.io -t Microsoft.Res winget install unom.PunktfunkHost ``` -Before it downloads anything, winget shows the package's agreements — the bundled VB-CABLE notice, -and that Moonlight compatibility is off by default — and asks you to accept them. +Before it downloads anything, winget shows the package's agreements — that audio needs Steam +installed on the host, and that Moonlight compatibility is off by default — and asks you to +accept them. `winget install` runs setup silently with the same defaults the wizard shows, so the console password is generated for you (see [Unattended install](#unattended-install)). Add `--interactive` -for the full wizard instead (the task checkboxes, the console-password page, the VB-CABLE notice). +for the full wizard instead (the task checkboxes and the console-password page). To change an individual installer task on the silent path, pass the whole switch line through `--override` — not `--custom`, which *appends* and would leave two `/MERGETASKS` on one command line: @@ -230,8 +232,9 @@ Open **Settings → Apps → Installed apps → Punktfunk Host → Uninstall**, Three things are left behind on purpose: **`%ProgramData%\punktfunk`** (`host.env`, the host certificate and key, the management token, the console password, your paired devices and the logs — -keeping it is what makes a reinstall pick up where you left off), **VB-CABLE** unless you cleared its -checkbox, and **the publisher certificate** if you imported one by hand. +keeping it is what makes a reinstall pick up where you left off), **VB-CABLE** if an older +Punktfunk version installed it (releases used to bundle it for the microphone), and **the +publisher certificate** if you imported one by hand. [Uninstalling → Windows host](/docs/uninstall#windows-host) shows how to clear each one, and has the same walkthrough for the other platforms. @@ -251,9 +254,9 @@ the status icon's menu. Running as SYSTEM is what makes headless, log-in-optional streaming work — and it's why the host is a high-privilege component worth being deliberate about. Punktfunk mitigates this with **user-mode drivers** — the virtual display, the virtual gamepads and the virtual pointer are all UMDF, none of -ours is kernel-mode (the optional third-party VB-CABLE mic driver is the one exception) — **sealed -internal channels** between the host and its drivers, and Administrators/SYSTEM-only permissions on -its secrets. See +ours is kernel-mode; the audio endpoints are instances of Valve's own vendor-signed streaming +drivers — **sealed internal channels** between the host and its drivers, and +Administrators/SYSTEM-only permissions on its secrets. See [Security & Safe Use](/docs/security) for the full picture, including why we recommend not hosting on your most sensitive machine. @@ -272,7 +275,7 @@ pipeline orchestration are all shared with the Linux host. The Windows host is a | **Input — mouse/keyboard** | libei / wlr protocols | **SendInput** (Win32 VK + absolute mouse) | | **Input — gamepads** | uinput Xbox 360 + UHID DualSense/DS4 | **UMDF** virtual pads — DualSense, DualShock 4, Xbox 360 (XUSB) + rumble | | **Audio capture** | PipeWire sink-monitor | **WASAPI loopback** | -| **Virtual mic** | PipeWire `Audio/Source` | **VB-CABLE** virtual device (optional), captured via WASAPI | +| **Virtual mic** | PipeWire `Audio/Source` | **"Punktfunk Microphone"** — the host's own instance of Steam's streaming-mic driver | The virtual display is **pf-vdisplay**, Punktfunk's own all-Rust **Indirect Display Driver (IDD)**. The host creates a shared GPU texture ring and the driver pushes finished frames straight into it — a real diff --git a/packaging/windows/README.md b/packaging/windows/README.md index 0a250ffb..fcffaf61 100644 --- a/packaging/windows/README.md +++ b/packaging/windows/README.md @@ -82,8 +82,9 @@ parse breakage that silently failed installs on non-English boxes. firewall rules), removes the `PunktfunkWeb` task + its firewall rule, then `driver uninstall` (+ `--gamepad`) removes the punktfunk virtual-device drivers — the pf-vdisplay device node(s) and the pf-vdisplay / pf-gamepad / pf-xusb driver-store packages (the field report was that they survived - uninstall). **VB-CABLE is intentionally NOT removed** (a third-party shared component the user may - use elsewhere — its own uninstaller is `VBCABLE_Setup_x64.exe -u -h`); the `%ProgramData%\punktfunk` + uninstall). **A VB-CABLE from an older punktfunk install is intentionally NOT removed** (a + third-party shared component the user may use elsewhere — its own uninstaller is + `VBCABLE_Setup_x64.exe -u -h`); the `%ProgramData%\punktfunk` config (incl. `web-password`) is also left in place. Silent install: `punktfunk-host-setup-.exe /VERYSILENT` (omit the driver with @@ -100,21 +101,16 @@ fresh install uses the generated random console password — read it from - **Virtual gamepads need no prerequisite.** The DualSense / DualShock 4 / Xbox 360 (XUSB) UMDF drivers are **bundled** in the installer (the *Install the virtual gamepad drivers* task) and `pnputil`-installed. **ViGEmBus is no longer used.** -- **The streaming microphone uses VB-CABLE**, bundled + silently installed by the installer (the *Install - VB-CABLE virtual audio* task). The host writes the client's mic into VB-CABLE's input; its `CABLE - Output` capture endpoint surfaces as a host mic. A Windows audio device can only be created by a - **kernel-mode** driver (no UMDF path exists), so unlike our self-signed UMDF drivers we cannot ship our - own — VB-CABLE is a vendor-signed cable that loads with no test-signing. It is **donationware** by - VB-Audio, redistributed under VB-Audio's bundling grant (only the single base cable) — the grant - requires the end user to see VB-CABLE's origin + donationware status, which the wizard task text and - `licenses/VB-CABLE-NOTICE.txt` surface. The package binary is **not** in the repo — CI provisions the - **pinned, SHA-256-verified official package** onto the runner (`scripts/ci/provision-windows-punktfunk-extras.ps1` - → `C:\Users\Public\vbcable`) and `windows-host.yml` passes it via `$env:VBCABLE_DIR`, so **published - installers always bundle it**; locally supply `-VbCableDir` / `$env:VBCABLE_DIR` (the extracted - official package, containing `VBCABLE_Setup_x64.exe`). Unset → the installer is built without it and - the host falls back to auto-installing the Steam Streaming pair; set-but-invalid → the pack **fails** - (a broken provisioning must not silently ship a mic-less installer again). *(Endgame: - attestation-sign our own MIT virtual-audio driver to drop this dependency.)* +- **Audio uses Steam's streaming drivers — nothing is bundled.** A Windows audio device can only + be created by a **kernel-mode** driver (no UMDF path exists), so unlike our self-signed UMDF + drivers we cannot ship our own. The host instead mints its OWN devnode instances of Valve's + vendor-signed streaming-audio drivers on the target box: **"Punktfunk Speakers"** (the + client-only desktop-audio sink, from `SteamStreamingSpeakers.inf`) and **"Punktfunk + Microphone"** (mic passthrough, from `SteamStreamingMicrophone.inf`). Audio therefore requires + **Steam installed — never running**; the installer shows a suppressible notice when Steam is + absent, and the host re-checks live, so installing Steam later just works. VB-CABLE was + bundled for the mic until the audio-substrate change (2026-08) — a cable from an older install + (or one the user installs) keeps working as a fallback mic target. ## Files here @@ -122,10 +118,9 @@ fresh install uses the generated random console password — read it from |------|------| | `punktfunk-host.iss` | Inno Setup script (the installer definition). | | `branding/` | Wizard branding: `gen-branding.ps1` renders the brand mark into the committed `wizard-image-*.bmp` / `wizard-small-*.bmp` (100–200% DPI) + `punktfunk.ico`. Re-run only on a brand change. | -| `pack-host-installer.ps1` | Orchestrator: cert + sign exe, **build + sign the drivers from source**, stage them + FFmpeg + VB-CABLE + the **web console** (`.output` + bun) + the HDR layer + branding, run ISCC, sign setup.exe. | +| `pack-host-installer.ps1` | Orchestrator: cert + sign exe, **build + sign the drivers from source**, stage them + FFmpeg + the **web console** (`.output` + bun) + the HDR layer + branding, run ISCC, sign setup.exe. | | `build-pf-vdisplay.ps1` | Build pf-vdisplay from source (the `drivers/` workspace) + clear FORCE_INTEGRITY + sign `.dll`/`.cat` + export `.cer`. | | `build-gamepad-drivers.ps1` | Sign + catalog the gamepad drivers (`pf-gamepad` + `pf-xusb`) from the same workspace build (`-SkipBuild`), one shared cert. | -| `install-vbcable.ps1` | On-target: seed VB-Audio's cert into `TrustedPublisher`, silently install the bundled VB-CABLE (`-i -h`). Run by the installer's *Install VB-CABLE virtual audio* task; idempotent + always exits 0 (non-fatal). | | `make-driver-cert.ps1` | Generate the stable `CN=punktfunk-driver` code-signing cert (the `DRIVER_CERT_PFX_B64` / `DRIVER_CERT_PASSWORD` secrets). No key container, so it works over SSH; self-tests with signtool where it can. See *Driver signing* above. | | `clear-force-integrity.ps1` | Clear the `/INTEGRITYCHECK` PE bit so a self-signed driver loads (reused by every driver build). | | `stage-pf-vdisplay.ps1` | Stage the just-built pf-vdisplay bundle + fetch/verify the **pinned** nefcon release. | diff --git a/packaging/windows/install-vbcable.ps1 b/packaging/windows/install-vbcable.ps1 deleted file mode 100644 index 662ad30c..00000000 --- a/packaging/windows/install-vbcable.ps1 +++ /dev/null @@ -1,97 +0,0 @@ -<# -.SYNOPSIS - Silently install the bundled VB-Audio Virtual Cable (the punktfunk virtual microphone) on the host. - -.DESCRIPTION - punktfunk pipes the streaming client's microphone into a virtual audio cable's render endpoint; the - cable's capture endpoint ("CABLE Output") then surfaces as a host microphone that games/apps record - from (see crates/punktfunk-host/src/audio/windows/wasapi_mic.rs). On a headless host there is no real - audio output, so a virtual cable is required. We bundle the OFFICIAL base VB-CABLE package (VB-Audio, - https://vb-cable.com) and install it unattended: - - 1. If a "CABLE Input"/"CABLE Output" endpoint already exists, do nothing (idempotent). - 2. Pre-seed VB-Audio's Authenticode signing certificate (read from the bundled signed driver) into - LocalMachine\TrustedPublisher, so the kernel-driver-publisher prompt is suppressed and the - install is fully silent (required for the SYSTEM/Session-0 service install). - 3. Run the official silent installer: VBCABLE_Setup_x64.exe -i -h (arm64: the same exe name in the - arm64 package; x86 falls back to VBCABLE_Setup.exe). - 4. Wait briefly for the audio subsystem to register the new endpoint. - - VB-CABLE is donationware by VB-Audio Software, redistributed here under VB-Audio's bundling grant - (https://vb-audio.com/Services/licensing.htm); see {app}\licenses\VB-CABLE-NOTICE.txt. Only the base - single cable is bundled (A+B / C+D are not redistributable). - - Best-effort: any failure is logged and returns a non-zero exit, but the caller (the installer) treats - it as non-fatal - the host still runs (mic passthrough then needs a manually-installed cable, and the - host falls back to auto-installing the Steam Streaming pair). - -.PARAMETER Dir - The staged VB-CABLE package directory (contains VBCABLE_Setup_x64.exe + the signed driver files). -#> -[CmdletBinding()] -param( - [Parameter(Mandatory = $true)][string]$Dir -) -$ErrorActionPreference = 'Stop' -$ProgressPreference = 'SilentlyContinue' - -function Test-CablePresent { - # An active render OR capture endpoint named "CABLE ..." means VB-CABLE is already installed. - $eps = Get-PnpDevice -Class AudioEndpoint -ErrorAction SilentlyContinue | - Where-Object { $_.Status -eq 'OK' -and $_.FriendlyName -match 'CABLE (Input|Output|In)' } - return [bool]$eps -} - -if (Test-CablePresent) { - Write-Host 'VB-CABLE already installed (CABLE endpoint present) - skipping.' - exit 0 -} - -if (-not (Test-Path -LiteralPath $Dir)) { throw "VB-CABLE package dir not found: $Dir" } - -# Pick the silent installer for this architecture. The x64 package ships both; arm64 ships an arm64 -# VBCABLE_Setup_x64.exe (VB-Audio's naming); fall back to the 32-bit setup if that's all that's staged. -$setup = $null -foreach ($name in @('VBCABLE_Setup_x64.exe', 'VBCABLE_Setup.exe')) { - $p = Join-Path $Dir $name - if (Test-Path -LiteralPath $p) { $setup = $p; break } -} -if (-not $setup) { throw "no VBCABLE_Setup*.exe under $Dir" } -Write-Host "VB-CABLE silent installer: $setup" - -# --- pre-seed VB-Audio's signing cert into LocalMachine\TrustedPublisher (unattended driver install) --- -# Read the Authenticode signer from a bundled signed file (prefer a driver .sys/.cat; fall back to the -# setup exe). Importing it into TrustedPublisher makes Windows install the signed driver with no prompt. -try { - $signed = Get-ChildItem -LiteralPath $Dir -Recurse -Include '*.sys', '*.cat', '*.exe' -ErrorAction SilentlyContinue | - ForEach-Object { Get-AuthenticodeSignature -LiteralPath $_.FullName -ErrorAction SilentlyContinue } | - Where-Object { $_.Status -eq 'Valid' -and $_.SignerCertificate } | - Select-Object -First 1 - if ($signed -and $signed.SignerCertificate) { - $store = New-Object System.Security.Cryptography.X509Certificates.X509Store('TrustedPublisher', 'LocalMachine') - $store.Open('ReadWrite') - $store.Add($signed.SignerCertificate) - $store.Close() - Write-Host "seeded VB-Audio cert into LocalMachine\TrustedPublisher (subject=$($signed.SignerCertificate.Subject))" - } - else { - Write-Warning 'no valid Authenticode signer found in the VB-CABLE package - the driver-publisher prompt may appear (install may stall under SYSTEM)' - } -} -catch { - Write-Warning "could not pre-seed the VB-Audio cert: $($_.Exception.Message)" -} - -# --- run the official silent install: -i (install) -h (hidden) ----------------------------------- -# VB-Audio documents these switches; the process returns before the endpoint is fully registered. -$proc = Start-Process -FilePath $setup -ArgumentList '-i', '-h' -Wait -PassThru -WindowStyle Hidden -Write-Host "VBCABLE setup exit code: $($proc.ExitCode)" - -# Give the audio subsystem time to enumerate the new endpoint, then verify. -for ($i = 0; $i -lt 10; $i++) { - Start-Sleep -Seconds 1 - if (Test-CablePresent) { Write-Host 'VB-CABLE installed - CABLE endpoint present.'; exit 0 } -} -Write-Warning 'VB-CABLE setup ran but no CABLE endpoint appeared yet (a reboot may be required).' -# Non-fatal: the device often appears after the next session/reboot; the host retries mic open with backoff. -exit 0 diff --git a/packaging/windows/licenses/VB-CABLE-NOTICE.txt b/packaging/windows/licenses/VB-CABLE-NOTICE.txt deleted file mode 100644 index c3d31503..00000000 --- a/packaging/windows/licenses/VB-CABLE-NOTICE.txt +++ /dev/null @@ -1,26 +0,0 @@ -VB-CABLE Virtual Audio Device — Attribution -=========================================== - -The punktfunk host installer bundles and silently installs VB-CABLE, the virtual -audio cable used as the streaming virtual microphone (the client's mic is written -into VB-CABLE's input, and its "CABLE Output" capture endpoint surfaces as a host -microphone that games and apps record from). - - VB-CABLE is a product of VB-Audio Software. - Origin: https://vb-cable.com (https://vb-audio.com) - VB-CABLE is DONATIONWARE — all participations are welcome. - Please consider donating to VB-Audio if you find it useful: - https://vb-audio.com/Cable/ - -VB-CABLE is redistributed here, unmodified (the official base VB-CABLE package), -under VB-Audio's distribution grant for bundling the base cable with another -application; see VB-Audio's licensing terms: - https://vb-audio.com/Services/licensing.htm - -Only the single base VB-CABLE is bundled. VB-CABLE A+B and C+D are not -redistributed. VB-Audio retains all rights to VB-CABLE; punktfunk claims no -ownership of it. - -To remove VB-CABLE, use its own uninstaller (VBCABLE_Setup_x64.exe -u -h) or the -"VB-Audio Virtual Cable" entry in Windows "Apps & features"; uninstalling the -punktfunk host does not remove VB-CABLE. diff --git a/packaging/windows/pack-host-installer.ps1 b/packaging/windows/pack-host-installer.ps1 index 9770ddcb..711ecdf6 100644 --- a/packaging/windows/pack-host-installer.ps1 +++ b/packaging/windows/pack-host-installer.ps1 @@ -31,7 +31,6 @@ param( [string]$WebDir = $env:WEB_OUTPUT_DIR, # built web .output tree -> bundle the mgmt console [string]$ScriptingBundle = $env:SCRIPTING_BUNDLE, # built runner-cli.js -> bundle the plugin/script runner [string]$BunExe = $env:BUN_EXE, # portable bun.exe runtime for the console + runner - [string]$VbCableDir = $env:VBCABLE_DIR, # official base VB-CABLE package -> bundle the virtual mic [switch]$NoDriver, # build without the bundled pf-vdisplay driver [switch]$NoSign, # skip signing (local debug) # 'auto' (default) = required iff this is a v* tag build; 'true'/'false' to force. See below. @@ -222,33 +221,10 @@ if (-not $NoDriver) { } # --- stage the official base VB-CABLE package (the streaming virtual microphone) -------------- -# VB-CABLE is the virtual audio cable the host writes the client's mic into (its capture endpoint then -# surfaces as a host microphone). We bundle + silently install the OFFICIAL base VB-CABLE package -# (VB-Audio donationware, redistributed under VB-Audio's bundling grant - see the VB-CABLE notice added -# to the licenses payload). The package binary is NOT in the repo (it's a signed third-party blob, -# shipped intact); supply it via -VbCableDir / $env:VBCABLE_DIR pointing at the extracted official -# package (must contain VBCABLE_Setup_x64.exe). Absent -> installer built WITHOUT the bundled cable; the -# host then auto-installs the Steam Streaming pair as a fallback and mic passthrough needs a manual cable. -if ($VbCableDir -and -not ((Test-Path $VbCableDir) -and (Get-ChildItem -Path $VbCableDir -Filter 'VBCABLE_Setup*.exe' -ErrorAction SilentlyContinue))) { - # An explicitly-supplied dir that doesn't hold the package is a broken provisioning, not an - # opt-out - fail loudly instead of silently shipping an installer without the virtual mic - # (exactly the field regression this bundling fixes). Opt out by leaving VBCABLE_DIR unset. - throw "VbCableDir '$VbCableDir' has no VBCABLE_Setup*.exe - re-run scripts/ci/provision-windows-punktfunk-extras.ps1 (or unset VBCABLE_DIR to build without the virtual mic)" -} -if ($VbCableDir) { - $vbStage = Join-Path $OutDir 'vbcable' - if (Test-Path $vbStage) { Remove-Item -Recurse -Force $vbStage } - New-Item -ItemType Directory -Force -Path $vbStage | Out-Null - Copy-Item (Join-Path $VbCableDir '*') $vbStage -Recurse -Force - # The on-target installer script (seeds VB-Audio's cert into TrustedPublisher, runs -i -h) ships - # alongside the package so it's extracted to the same {tmp}\vbcable dir. - Copy-Item (Join-Path $here 'install-vbcable.ps1') $vbStage -Force - $defines += "/DAudioCableStageDir=$vbStage" - # Attribution: VB-Audio's bundling grant requires we surface VB-CABLE's origin + donationware status. - Copy-Item (Join-Path $here 'licenses\VB-CABLE-NOTICE.txt') -Destination $licStage -Force - Write-Host "==> bundling VB-CABLE (virtual mic) from $VbCableDir -> $vbStage" -} -else { Write-Host "no -VbCableDir/`$env:VBCABLE_DIR -> installer built WITHOUT the bundled VB-CABLE virtual mic (CI always bundles it; see provision-windows-punktfunk-extras.ps1)" } +# VB-CABLE is no longer bundled (the audio-substrate program, 2026-08): the host mints its own +# audio endpoints from Steam's streaming drivers ("Punktfunk Speakers/Microphone"), so audio needs +# Steam installed on the target box - never running - and no third-party cable. A user-installed +# VB-CABLE keeps working as a fallback mic target. # --- stage the FFmpeg shared DLLs (AMD/Intel AMF/QSV build) ------------------------------------ # A host built with --features amf-qsv link-imports avcodec/avutil/swscale/... so the shared DLLs diff --git a/packaging/windows/punktfunk-host.iss b/packaging/windows/punktfunk-host.iss index e845eb72..624d5591 100644 --- a/packaging/windows/punktfunk-host.iss +++ b/packaging/windows/punktfunk-host.iss @@ -48,12 +48,10 @@ #ifdef GamepadStageDir #define WithGamepad #endif -; AudioCableStageDir (the official base VB-CABLE package + install-vbcable.ps1) is optional - present -; when the VB-CABLE package was supplied to the packer. It is the streaming virtual microphone; on a -; headless host (no real audio output) a virtual cable is required for mic + desktop-audio passthrough. -#ifdef AudioCableStageDir - #define WithAudioCable -#endif +; VB-CABLE is no longer bundled (retired 2026-08, the audio-substrate program): the host mints its +; own audio endpoints from Steam's streaming drivers - "Punktfunk Speakers" for desktop audio and +; "Punktfunk Microphone" for mic passthrough - so audio needs Steam INSTALLED (never running). A +; VB-CABLE the user installed themselves keeps working as a fallback mic target. ; FfmpegBin (a dir of FFmpeg shared DLLs) is optional - present when the host is built with ; --features amf-qsv (the AMD/Intel AMF/QSV encode backend link-imports the FFmpeg libs). #ifdef FfmpegBin @@ -144,12 +142,6 @@ Name: "installdriver"; Description: "Install the pf-vdisplay virtual display dri #ifdef WithGamepad Name: "installgamepad"; Description: "Install the virtual gamepad drivers (DualSense / DualShock 4 / Xbox 360 - no ViGEmBus needed)" #endif -#ifdef WithAudioCable -; VB-Audio's bundling grant requires the end user to see VB-CABLE's origin + donationware status -; at install time - keep the vendor, URL, and donationware wording in this visible task text (the -; full notice ships in {app}\licenses\VB-CABLE-NOTICE.txt). -Name: "installaudiocable"; Description: "Install VB-CABLE virtual audio for microphone passthrough (VB-CABLE by VB-Audio, www.vb-cable.com - donationware, all participations welcome)" -#endif #ifdef WithVkLayer Name: "installhdrlayer"; Description: "Install the HDR Vulkan layer (lets Vulkan games like Doom use HDR on the virtual display)" #endif @@ -233,10 +225,6 @@ Source: "{#StageDir}\*"; DestDir: "{tmp}\pfvdisplay"; Flags: deleteafterinstall ; The built-from-source UMDF gamepad drivers + install-gamepad-drivers.ps1, extracted to {tmp}, removed after. Source: "{#GamepadStageDir}\*"; DestDir: "{tmp}\gamepad"; Flags: deleteafterinstall recursesubdirs createallsubdirs; Tasks: installgamepad #endif -#ifdef WithAudioCable -; The official base VB-CABLE package + install-vbcable.ps1, extracted to {tmp}, removed after install. -Source: "{#AudioCableStageDir}\*"; DestDir: "{tmp}\vbcable"; Flags: deleteafterinstall recursesubdirs createallsubdirs; Tasks: installaudiocable -#endif #ifdef WithVkLayer ; The HDR Vulkan implicit layer (cdylib + its JSON manifest) laid into {app}\vklayer and registered ; below. The manifest's library_path is ".\pf_vkhdr_layer.dll" (relative to the JSON), so the two @@ -293,15 +281,6 @@ Filename: "{app}\punktfunk-host.exe"; Parameters: "driver install --gamepad --di StatusMsg: "Installing the virtual gamepad drivers..."; \ Flags: runhidden waituntilterminated; Tasks: installgamepad #endif -#ifdef WithAudioCable -; Silently install the bundled VB-CABLE (the streaming virtual microphone). Best-effort: install-vbcable.ps1 -; always exits 0 (a missing cable just disables mic passthrough; the host falls back + retries), so a -; cable hiccup never fails the whole install. -Filename: "powershell.exe"; \ - Parameters: "-NoProfile -ExecutionPolicy Bypass -File ""{tmp}\vbcable\install-vbcable.ps1"" -Dir ""{tmp}\vbcable"""; \ - StatusMsg: "Installing VB-CABLE virtual audio (microphone passthrough)..."; \ - Flags: runhidden waituntilterminated; Tasks: installaudiocable -#endif ; Register (or re-point, on upgrade - idempotent) the SYSTEM service from its FINAL {app} location: ; service install records current_exe() as the SCM binPath, so it must run from {app}, not {tmp}. ; --gamestream=on|off carries the wizard's GameStream task choice into host.env's PUNKTFUNK_HOST_CMD. @@ -359,8 +338,10 @@ Filename: "{app}\punktfunk-host.exe"; Parameters: "service uninstall"; Flags: ru ; driver packages). AFTER service uninstall so the host no longer holds the devices. Unconditional ; (not #ifdef'd on this build's bundled payload - an upgrade may have dropped a payload the original ; install laid down); `driver uninstall` is best-effort and no-ops when nothing is installed. -; VB-CABLE is deliberately NOT removed: it is a third-party shared component the user may use -; elsewhere - see licenses\VB-CABLE-NOTICE.txt for its own uninstall. +; A VB-CABLE from an OLDER punktfunk install (bundled until the audio-substrate change) is +; deliberately NOT removed: it is a third-party shared component the user may use elsewhere. +; The host's own minted audio devnodes ("Punktfunk Speakers/Microphone") are likewise left in +; place - they are plain instances of Steam's streaming drivers, inert without the host. Filename: "{app}\punktfunk-host.exe"; Parameters: "driver uninstall"; Flags: runhidden waituntilterminated; RunOnceId: "PunktfunkVdisplayDriverUninstall" Filename: "{app}\punktfunk-host.exe"; Parameters: "driver uninstall --gamepad"; Flags: runhidden waituntilterminated; RunOnceId: "PunktfunkGamepadDriverUninstall" #ifdef WithWeb @@ -423,6 +404,18 @@ end; { Runs before any wizard page - the earliest point we can warn. Detect a conflicting host and let the user abort (default) or continue. Returning False cancels setup. } +{ Steam's streaming-audio driver INFs - the host mints its audio endpoints from them (audio + needs Steam INSTALLED, never running). Checked per-arch like the host's own resolver. } +function SteamAudioDriversPresent(): Boolean; +var + Base: String; +begin + Base := ExpandConstant('{commoncf32}\Steam\drivers\Windows10\'); + Result := FileExists(Base + 'x64\SteamStreamingMicrophone.inf') + or FileExists(Base + 'arm64\SteamStreamingMicrophone.inf') + or FileExists(Base + 'x86\SteamStreamingMicrophone.inf'); +end; + function InitializeSetup(): Boolean; var Found: String; @@ -430,6 +423,17 @@ begin Result := True; { Record the fresh-vs-upgrade verdict while host.env still reflects the PREVIOUS run. } FreshHostInstall := not FileExists(HostEnvPath); + { Informational, suppressible (silent installs proceed): without Steam's streaming drivers + the host has no audio substrate to mint from - it streams video only, and says so in its + own logs/status too. The runtime re-checks live, so installing Steam later just works. } + if not SteamAudioDriversPresent() then + SuppressibleMsgBox( + 'Steam does not appear to be installed on this PC.' + #13#10 + #13#10 + + 'Punktfunk uses Steam''s streaming audio drivers for game audio and microphone ' + + 'passthrough (Steam only needs to be installed - it never has to run). Without it, ' + + 'this host streams video only.' + #13#10 + #13#10 + + 'You can install Steam at any time; the host picks it up automatically.', + mbInformation, MB_OK, IDOK); Found := ''; if StreamHostEnabled('SunshineService') then Found := Found + ' - Sunshine' + #13#10; if StreamHostEnabled('ApolloService') then Found := Found + ' - Apollo' + #13#10; diff --git a/packaging/winget/README.md b/packaging/winget/README.md index 90901588..b4e97c9d 100644 --- a/packaging/winget/README.md +++ b/packaging/winget/README.md @@ -21,7 +21,7 @@ agreements and installation notes stay under normal code review. `packaging/windows/punktfunk-host.iss`** — if that GUID ever changes, change it here too or upgrades silently stop being detected. - **`interactive` is in `InstallModes`.** `winget install unom.PunktfunkHost --interactive` runs the - full existing wizard: every task checkbox, the web-console password page, the VB-CABLE notice. + full existing wizard: every task checkbox and the web-console password page. Nothing about the installer changes to support it. - **No `/MERGETASKS` in the silent switches.** A silent install deliberately takes the *same* task defaults the wizard shows, so the product does not differ by install channel — a per-channel @@ -41,7 +41,7 @@ Inno's `/MERGETASKS` takes `!` prefixes to deselect a default-checked task. Use winget install unom.PunktfunkHost --override "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /MERGETASKS=!gamestream" ``` -Task names: `installdriver`, `installgamepad`, `installaudiocable`, `installhdrlayer`, +Task names: `installdriver`, `installgamepad`, `installhdrlayer`, `gamestream`, `allowpublicfw`, `startservice`, `trayicon`. ## Two installer behaviours that exist for this path diff --git a/packaging/winget/unom.PunktfunkHost.installer.yaml b/packaging/winget/unom.PunktfunkHost.installer.yaml index ad8e64b8..09fe0557 100644 --- a/packaging/winget/unom.PunktfunkHost.installer.yaml +++ b/packaging/winget/unom.PunktfunkHost.installer.yaml @@ -16,8 +16,8 @@ ElevationRequirement: elevatesSelf MinimumOSVersion: 10.0.22621.0 InstallModes: - # interactive keeps the FULL wizard — every task checkbox, the web-console password page, and the - # VB-CABLE notice text. `winget install unom.PunktfunkHost --interactive`. + # interactive keeps the FULL wizard — every task checkbox and the web-console password page. + # `winget install unom.PunktfunkHost --interactive`. - interactive - silent - silentWithProgress @@ -34,7 +34,7 @@ InstallerSwitches: # enabling it unattended is the additive form: # winget install unom.PunktfunkHost --override "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /MERGETASKS=gamestream" # and dropping a default-on task is the negated form, e.g. /MERGETASKS=!trayicon - # Task names: installdriver, installgamepad, installaudiocable, installhdrlayer, + # Task names: installdriver, installgamepad, installhdrlayer, # gamestream, allowpublicfw, startservice, trayicon Silent: /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- SilentWithProgress: /SILENT /SUPPRESSMSGBOXES /NORESTART /SP- diff --git a/packaging/winget/unom.PunktfunkHost.locale.en-US.yaml b/packaging/winget/unom.PunktfunkHost.locale.en-US.yaml index 67d33b3a..0a23db50 100644 --- a/packaging/winget/unom.PunktfunkHost.locale.en-US.yaml +++ b/packaging/winget/unom.PunktfunkHost.locale.en-US.yaml @@ -36,16 +36,15 @@ Documentations: # Shown BEFORE download/install; the user must accept or the install does not proceed. This is what # carries — on the unattended path, where no wizard page is on screen — the disclosures the wizard -# puts in its task text. VB-Audio's bundling grant specifically requires the end user to see -# VB-CABLE's origin + donationware status at install time. +# surfaces interactively. Agreements: - - AgreementLabel: Bundled virtual audio (VB-CABLE by VB-Audio) + - AgreementLabel: Audio requires Steam installed on this PC Agreement: >- - Punktfunk's streaming microphone uses VB-CABLE by VB-Audio (www.vb-cable.com), which this - installer bundles and installs. VB-CABLE is donationware — all participations welcome. It is - redistributed under VB-Audio's bundling grant; the full notice is installed to - %ProgramFiles%\punktfunk\licenses\VB-CABLE-NOTICE.txt. - AgreementUrl: https://vb-audio.com/Cable/ + Punktfunk streams game audio and microphone passthrough through its own instances of + Steam's streaming audio drivers. Steam only needs to be installed — it never has to run. + Without Steam, this host streams video only; installing Steam later is picked up + automatically. + AgreementUrl: https://store.steampowered.com/about/ - AgreementLabel: GameStream (Moonlight) compatibility is OFF by default Agreement: >- Punktfunk's own clients work out of the box. Support for stock Moonlight clients is a separate, diff --git a/scripts/ci/gen-sbom.sh b/scripts/ci/gen-sbom.sh index 5f514348..03558cc0 100755 --- a/scripts/ci/gen-sbom.sh +++ b/scripts/ci/gen-sbom.sh @@ -6,8 +6,8 @@ # their Cargo.locks, the Bun/pnpm/npm trees, the Swift Package.resolved); # compliance/sbom/manual-components.cdx.json contributes the components no lockfile records — # vendored C/C++ trees (pyrowave/Granite/volk/Vulkan-Headers, libvpl), dynamically-linked/bundled -# libraries (FFmpeg, SDL3), the redistributed VB-CABLE driver, and the patched gamescope. Keep -# that file current when vendoring changes (scripts/vendor-pyrowave.sh etc.). +# libraries (FFmpeg, SDL3), and the patched gamescope. Keep that file current when vendoring +# changes (scripts/vendor-pyrowave.sh etc.). # # Usage: scripts/ci/gen-sbom.sh VERSION [OUTPUT] # Requires: syft (pinned install in the workflow), python3 (a proven runner dependency). diff --git a/scripts/ci/provision-windows-punktfunk-extras.ps1 b/scripts/ci/provision-windows-punktfunk-extras.ps1 index 4367316d..2ba2042c 100644 --- a/scripts/ci/provision-windows-punktfunk-extras.ps1 +++ b/scripts/ci/provision-windows-punktfunk-extras.ps1 @@ -95,26 +95,9 @@ if (-not (Test-Path $isccPath) -or ($innoVer -and [version]$innoVer -lt [version } else { Write-Warning "Inno Setup missing or pre-6.6 ($innoVer) and choco unavailable - install/upgrade it for windows-host.yml." } } -# --- VB-CABLE (the streaming virtual microphone the host installer bundles). Pinned official -# package, SHA-256 verified - a silent hash change means VB-Audio shipped a new pack: verify it, -# then update BOTH the pin here and the notice if terms changed (packaging/windows/licenses/ -# VB-CABLE-NOTICE.txt). Donationware by VB-Audio (https://vb-audio.com), redistributed under -# VB-Audio's bundling grant; only the base cable, never A+B/C+D. windows-host.yml points -# VBCABLE_DIR here so pack-host-installer.ps1 bundles it. --- -$vbDir = "C:\Users\Public\vbcable" -$vbUrl = "https://download.vb-audio.com/Download_CABLE/VBCABLE_Driver_Pack45.zip" -$vbSha = "B950E39F01AF1D04EA623C8F6D8EB9B6EA5C477C637295FABF20631C85116BFB" -if (-not (Test-Path (Join-Path $vbDir 'VBCABLE_Setup_x64.exe'))) { - info "fetching VB-CABLE (official base package, pinned)" - $vbZip = "$vbDir.zip" - Invoke-WebRequest -Uri $vbUrl -OutFile $vbZip -UseBasicParsing - $got = (Get-FileHash $vbZip -Algorithm SHA256).Hash - if ($got -ne $vbSha) { Remove-Item $vbZip -Force; throw "VB-CABLE download hash mismatch (got $got, pinned $vbSha) - vendor package changed; re-verify before re-pinning." } - if (Test-Path $vbDir) { Remove-Item -Recurse -Force $vbDir } - Expand-Archive -Path $vbZip -DestinationPath $vbDir -Force # flat zip (setup exes + signed drivers) - Remove-Item $vbZip -Force - info "VB-CABLE staged at $vbDir" -} else { info "VB-CABLE already present at $vbDir" } +# VB-CABLE provisioning removed (the audio-substrate program, 2026-08): the installer no longer +# bundles a cable - the host mints its audio endpoints from Steam's streaming drivers on the +# target box. A stale C:\Users\Public\vbcable on a runner is harmless and can be deleted. # --- Drop punktfunk's env vars into the generic runner's daemon wrapper extension point (see # unom/infra's scripts/setup-gitea-runner-base.ps1) so the act_runner daemon - and therefore every @@ -122,10 +105,9 @@ if (-not (Test-Path (Join-Path $vbDir 'VBCABLE_Setup_x64.exe'))) { $projectEnv = "C:\Users\Public\act-runner\project-env.ps1" @' $env:FFMPEG_DIR = "C:\Users\Public\ffmpeg" -$env:VBCABLE_DIR = "C:\Users\Public\vbcable" $env:PF_FFVK_VULKAN_INCLUDE = "C:\Users\Public\vulkan-headers\include" $env:PATH = "C:\Users\Public\ffmpeg\bin;" + $env:PATH '@ | Set-Content -Encoding UTF8 $projectEnv -info "wrote $projectEnv (FFMPEG_DIR, VBCABLE_DIR, PF_FFVK_VULKAN_INCLUDE) - restart the gitea-act-runner scheduled task to pick it up" +info "wrote $projectEnv (FFMPEG_DIR, PF_FFVK_VULKAN_INCLUDE) - restart the gitea-act-runner scheduled task to pick it up" info "punktfunk extras provisioned OK."