A tiny, fast Windows CLI to list and switch your default audio devices β from the terminal.
No GUI clicking, no settings panels. Just as set --playback "Headphones" and you're done.
- π List every active playback & recording device, with the current Default and Communications defaults clearly marked.
- β‘ Switch the default output/input device by full name, partial name, or device ID β case-insensitive.
- π Toggle a flow between two devices with one command β perfect for a hotkey that flips speakers β headphones.
- ποΈ Two default slots, your choice β target the multimedia Default Device, the Communications device, or both at once.
- π₯οΈ Interactive picker β a guided two-column TUI that builds the exact command line for you to copy into scripts.
- π¦ Single native binary β Native AOT produces a ~3 MB
as.exewith zero .NET runtime dependency.
- Install
- Quick start
- Commands
- How Windows defaults work
- Build from source
- Tests
- Releases (CI)
- Project structure
- License
Grab as.exe from the latest release and drop it anywhere on your PATH.
It's a single self-contained executable β nothing else to install.
# verify it runs
as --versionπ‘ Prefer building it yourself? See Build from source.
as # launch the interactive picker
as list # list playback + recording devices
as set --playback "Headphones" # set the default playback device
as set --recording "USB Microphone" # set the default recording device
as set --playback "Headphones" --recording "USB Mic" # set both in one go
as set --playback "Headset" --communications # set only the comms default
as set --playback "Speakers" --default # set only the multimedia default
as toggle --playback "Speakers" "Headphones" # flip playback between two devicesDevice matching is case-insensitive and accepts a full name, a partial name, or the device ID.
Lists active devices and marks the current Default (β) and Comms (β) defaults.
| Option | Description |
|---|---|
--playback |
List only playback (output) devices |
--recording |
List only recording (input) devices |
With no option, both playback and recording devices are listed.
Sets the default playback and/or recording device.
| Option | Description |
|---|---|
--playback <name> |
Name or ID of the playback (output) device to set |
--recording <name> |
Name or ID of the recording (input) device to set |
--communications, --comms |
Set only the default communication device |
--default |
Set only the multimedia default (Console + Multimedia) |
Provide --playback, --recording, or both. If neither --communications nor
--default is given, every role is set at once.
Flips the default playback and/or recording device between two devices. Pass two
names (or IDs) per flow; toggle reads the current default and switches to whichever
of the two is not currently active β ideal for binding to a single hotkey.
| Option | Description |
|---|---|
--playback <a> <b> |
Two playback (output) devices to toggle between |
--recording <a> <b> |
Two recording (input) devices to toggle between |
--communications, --comms |
Toggle only the default communication device |
--default |
Toggle only the multimedia default (Console + Multimedia) |
Provide --playback, --recording, or both. The role flags work exactly as they do
for as set; omitting them toggles every role at once.
How the target is chosen: if the current default is the first device, toggle
switches to the second; if it's the second, it switches back to the first; if it's
neither (some other device, or nothing), it switches to the first device.
> as toggle --playback "Speakers" "Headphones"
Toggled playback default and communications device from Speakers to Headphones
> as toggle --playback "Speakers" "Headphones"
Toggled playback default and communications device from Headphones to SpeakersAliases:
as iβ or just runaswith no arguments.
A guided, keyboard-driven picker:
- Pick what to change β Default device, Communication device, or Both.
- Pick the devices β a two-column screen (π Playback Β· π Recording). Navigate with
β/β, switch columns withβ/βorTab, and pick β leave unchanged β to skip a column. - Copy the command β a live panel composes the exact CLI command, e.g.
as set --playback "Headset Earphone" --recording "Headset Microphone" --communications, ready to paste into a script. - Press
Enterto apply (and print the final command) orEscto go back.
Windows tracks two independent default device slots per data flow:
| Slot | Roles | Used by |
|---|---|---|
| Default Device | Console + Multimedia | Media playback, games, system sounds |
| Default Communication Device | Communications | Voice/calling apps (Teams, Discord, β¦) |
Use --default to target the multimedia slot, --communications (--comms) for the
communications slot, or omit both to set every role at once.
The project targets .NET 10 and is configured for Native AOT
(<PublishAot>true</PublishAot>), so dotnet publish produces a single, fully native
as.exe (~3 MB) with no .NET runtime dependency.
dotnet publish -c ReleaseThe executable is written to:
bin/Release/net10.0-windows/win-x64/publish/as.exe
Native AOT compiles and links to native code, so the build machine (not machines that
merely run as.exe) needs:
- The Desktop development with C++ workload (MSVC
link.exe), and - The Windows 11 SDK (provides
advapi32.lib, etc.).
Publish from a Developer Command Prompt / Developer PowerShell for VS (or run
vcvars64.bat first) so the linker can find the MSVC and Windows SDK libraries.
Unit tests live in AudioSwitcher.Tests/ (xUnit) and cover the pure
logic of the app: CliFormat (labels, icons, role-target resolution, the copy-pasteable
set command-line builder, and innermost-error extraction), device name/ID matching in
AudioDeviceService (exact wins over partial, ambiguous partial matches are rejected), the
toggle selection logic and two-value flag parser, the reported version, and the interactive
picker helpers (Wrap, BuildItems, InitialCursor).
The Core Audio COM layers require a real audio endpoint and are exercised manually.
dotnet test AudioSwitcher.slnxPushing a semantic-version tag automatically builds, tests, and publishes as.exe via
.github/workflows/release.yml, attaching the binary, a
zip, and SHA-256 checksums to a GitHub Release.
git tag v1.0.0
git push origin v1.0.0The workflow runs on windows-latest (which ships the MSVC toolchain and Windows SDK needed
for Native AOT), gates the release on the test suite, and derives the build version from
the tag. It can also be triggered manually from the Actions tab to validate a build
without creating a release.
The code is organised by responsibility:
| Path | Contents |
|---|---|
Interop/ |
Native Core Audio COM glue: NativeEnums, NativeTypes, ComInterfaces, CoreAudio. |
Audio/ |
Device model and logic: AudioDevice, RoleTarget, AudioDeviceService. |
Cli/ |
Command-line layer: CliRouter, CliFormat, and the List/Set/Toggle/Interactive commands. |
Program.cs |
Entry point β hands the arguments to CliRouter. |
AudioSwitcher.Tests/ |
xUnit test project. |
Released under the MIT License. Β© 2026 Gabriele Castellani.
