Repository navigation
ci: test host audio on Windows and macOS through virtual loopback devices - #666
Open
jamesbraid wants to merge 3 commits into
Open
jamesbraid wants to merge 3 commits into
jamesbraid wants to merge 3 commits into
Conversation
jamesbraid
marked this pull request as draft
November 12, 2026 08:21
jamesbraid
force-pushed
the
ci/audio-ci-phase2
branch
from
November 12, 2026 09:06
1938f43 to
db852c8
Compare
jamesbraid
force-pushed
the
ci/audio-ci-phase2
branch
from
November 12, 2026 09:12
db852c8 to
ca60085
Compare
jamesbraid
marked this pull request as ready for review
November 12, 2026 09:37
jamesbraid
force-pushed
the
ci/audio-ci-phase2
branch
2 times, most recently
from
November 12, 2026 14:45
63528ae to
abcf2be
Compare
… and macOS The real-device audio tests could only record on Linux; elsewhere IRIS_AUDIO_LOOPBACK made them panic, so cpal's WASAPI and CoreAudio output paths had no test. Both platforms can loop the default output back inside the test process. Windows: `default-render` records the default output through WASAPI loopback, which cpal enables for an input stream on a render device. The mix format comes from default_output_config, because cpal's default_input_config refuses render devices. A loopback delivers nothing while nothing renders, so a late buffer has the silence before it filled in from the wall clock; the tests look for the pause. macOS: the source is an input device's name, such as `BlackHole 2ch`, recorded at 48 kHz. cpal's process-tap loopback is not used: it needs a system-audio-recording grant a runner cannot give. Unproven: the recorder compiles for x86_64-pc-windows-gnu, x86_64-pc-windows-msvc and aarch64-apple-darwin in a stand-in crate holding only this module, and has not recorded on either platform.
Hosted Windows and macOS runners have no sound device, so the real-device audio tests have nothing to play into, and GitHub will not preinstall one (actions/runner-images#6983). Mozilla's cubeb installs VB-CABLE on windows-2025 and BlackHole on macos-15 in CI and its run 39754653738 passed with both. audio-loopback-windows.ps1 downloads VB-CABLE pack 43 and devcon, checks both against pinned SHA-256 sums, trusts the driver's publisher, installs the cable and waits up to 60 s for its render endpoint. Windows names the endpoints after the driver model, not the cable's ends: a run on windows-latest listed "Speakers (VB-Audio Virtual Cable)" and "CABLE Output (VB-Audio Virtual Cable)". The script therefore picks the render side by its instance ID and the cable's name, prints every endpoint it found, and fails if another render endpoint exists, since the tests play into the default output and the cable is the default only while it is the sole one. audio-loopback-macos.sh installs BlackHole 2ch from Homebrew, restarts coreaudiod and makes it the default output and input. VB-CABLE is donationware and is downloaded from the vendor on every run, never kept in the repository. A setup failure fails the script loudly, but the workflow step is continue-on-error, so the job stays green and the real-device tests do not run. Unproven: the macOS script has not run on a runner (it runs only on pushes to main); on Windows the install is shown to work on windows-latest, but the endpoint selection and the recording after it have not run.
…ual devices The real-device audio tests ran in CI on Linux only, so a break in cpal's WASAPI or CoreAudio path would first show on someone's desk. The Test job now installs VB-CABLE on Windows and BlackHole on macOS with the new scripts and runs the tests recorded back through them. Both steps have continue-on-error, so a failure does not turn the job red even where the platform gates. Neither install has run on these images; they become blocking once one run of each has passed.
jamesbraid
force-pushed
the
ci/audio-ci-phase2
branch
from
November 12, 2026 14:49
abcf2be to
465ac0f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The real-device audio tests (a card plays through cpal into the host's default output, and the test records it back) run in CI on Linux only. A break in cpal's WASAPI or CoreAudio path, such as the wrong device or rate, would only show up on a desk. This adds Windows and macOS: the runner is given a virtual sound device, the test records it in-process through cpal, and the same tests run.
Neither new step has run on a hosted runner. They are non-blocking (
continue-on-error: true) until one run of each has passed. Linux stays blocking, as in the PR it builds on. Windows now gates on main, but the new Windows step has its owncontinue-on-error, so it does not.What is in it
audio: record the real-device tests' loopback through cpal on Windows and macOS. A second recorder behind the existingBackend::RealDevice, withIRIS_AUDIO_LOOPBACK=default:default-renderon Windows (cpal builds a WASAPI loopback when an input stream is opened on a render device) anddefault:BlackHole 2chon macOS (an ordinary input at 48 kHz). No new crate. cpal's macOS process-tap loopback is not used: it needs a system-audio-recording permission a runner cannot grant, and it delivers silence without it, which would look like the bug under test.scripts: set up a virtual loopback device on Windows and macOS runners.audio-loopback-windows.ps1(VB-CABLE pack 43 and devcon, both pinned by SHA-256, then waits for the endpoint) andaudio-loopback-macos.sh(Homebrewblackhole-2chandswitchaudio-osx, restart coreaudiod, set defaults).ci: run the real-device audio tests on Windows and macOS through virtual devices. Two steps in the Test job, plus TESTING.md.What was run
cargo check --tests -p iris, default and--features jitv2, andcargo test -p iris --lib host_audio(8 passed; the real-device test skips with the variable unset). The diff touches onlyhost_audioamong source modules.x86_64-pc-windows-gnu,x86_64-pc-windows-msvcandaarch64-apple-darwin, checked in a stand-in crate holding only that module. The full crate does not cross-compile on the Linux host because its C dependencies need a target toolchain.What the hosted runners offer
windows-2025and BlackHole onmacos-15andmacos-15-intel, then runs its device tests (build.yml, setup_windows_audio.ps1). In run 39754653738 (2026-10-22) every install and test step on those platforms succeeded.macos-26andwindows-latest, which are the images iris uses, and, on macOS, whether the recording returns samples or silence under the runner's microphone permission (the image pre-grants that permission to its own provisioner binaries, configure-tccdb-macos.sh, not to arbitrary processes). cubeb does not wait for the VB-CABLE endpoint to appear; this script does, for up to 60 s.Licences
First run to watch
The first push-to-main Test job (macOS only runs on pushes; Windows also runs on ready pull requests). On Windows the step "Test audio through VB-CABLE", on macOS "Test audio through BlackHole". If only
a_tone_survives_an_underrun_on_the_real_device(the bare host output, no card) fails, the setup is broken, not a card.