Skip to content

GabrieleCastellani/as-audio-switcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎧 AudioSwitcher

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.

Platform CI .NET Native AOT No runtime Built with License GitHub Copilot


AudioSwitcher interactive picker β€” two-column πŸ”Š Playback Β· πŸŽ™ Recording screen

✨ Highlights

  • πŸ”Š 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.exe with zero .NET runtime dependency.

πŸ“‘ Table of contents

πŸ“₯ Install

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.

πŸš€ Quick start

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 devices

Device matching is case-insensitive and accepts a full name, a partial name, or the device ID.

🧭 Commands

as list

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.

as set

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.

as toggle

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 Speakers

as interactive

Aliases: as i β€” or just run as with no arguments.

A guided, keyboard-driven picker:

  1. Pick what to change β€” Default device, Communication device, or Both.
  2. Pick the devices β€” a two-column screen (πŸ”Š Playback Β· πŸŽ™ Recording). Navigate with ↑/↓, switch columns with ←/β†’ or Tab, and pick β€” leave unchanged β€” to skip a column.
  3. 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.
  4. Press Enter to apply (and print the final command) or Esc to go back.

πŸͺŸ How Windows defaults work

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.

πŸ”§ Build from source

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 Release

The executable is written to:

bin/Release/net10.0-windows/win-x64/publish/as.exe

Prerequisites

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.

πŸ§ͺ Tests

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.slnx

🚒 Releases (CI)

Pushing 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.0

The 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.

πŸ—‚οΈ Project structure

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.

πŸ“œ License

Released under the MIT License. Β© 2026 Gabriele Castellani.


Built for Windows with ❀️ and Spectre.Console · Developed with GitHub Copilot & Claude Opus 4.8 · Inspired by NAudio · Native AOT

About

🎧 Tiny, fast Native-AOT Windows CLI (as) to list and switch your default audio playback & recording devices from the terminal β€” no GUI, single ~3MB exe, zero .NET runtime.

Topics

Resources

License

Stars

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages