Help us improve
Share bugs, ideas, or general feedback.
From media-os
Controls Windows audio via WASAPI: list/change default devices, mute/unmute, set volume, test exclusive mode, install VB-Cable or VoiceMeeter virtual audio devices.
npx claudepluginhub damionrashford/media-os --plugin media-osHow this skill is triggered — by the user, by Claude, or both
Slash command
/media-os:audio-wasapi [action][action]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Context:** $ARGUMENTS
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
Context: $ARGUMENTS
winaudio.py list-devices)winaudio.py get-default)winaudio.py set-default)winaudio.py mute/unmute/volume)winaudio.py exclusive-test)winaudio.py vbcable-install)winaudio.py voicemeeter-config)Not for: macOS (use audio-coreaudio), Linux (use audio-pipewire).
The script exits 2 with a helpful message if run on non-Windows.
Read references/exclusive-vs-shared.md
when the user asks about latency, bit-perfect playback, or
IAudioClient::Initialize errors.
Read references/virtual-cable.md when the user
asks about OBS system-audio capture or VoiceMeeter routing.
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py list-devices
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py list-devices --kind playback
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py list-devices --kind recording
Calls Get-AudioDevice -List (from the AudioDeviceCmdlets PowerShell module).
If the module isn't installed the PowerShell errors out — install with:
Install-Module -Name AudioDeviceCmdlets -Scope CurrentUser
Output columns: Index, Default, Type, Name, ID.
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py get-default
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py get-default --kind recording
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py get-default --kind communications
Windows has three separate default roles:
| Role | Used by |
|---|---|
playback (eMultimedia) | Music/movie apps that request "default" device |
recording (eMultimedia for capture) | Your default mic |
communications (eCommunications) | Zoom / Teams / Discord for voice |
Pass the device name exactly as list-devices printed it (quote for spaces):
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py set-default "Speakers (Realtek High Definition Audio)"
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py set-default "Focusrite USB Audio" --kind recording
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py set-default "Shure MV7+" --kind communications
Alternatives not wrapped here (also valid):
nircmd setdefaultsounddevice "<Name>" — older NirCmd, smaller.svcl.exe /SetDefault "<Name>" Playback — NirSoft command-line version
of SoundVolumeView. See references/virtual-cable.md
for full svcl flags.uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py mute "Speakers (Realtek High Definition Audio)"
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py unmute "Speakers (Realtek High Definition Audio)"
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py volume "Speakers (Realtek High Definition Audio)" --level 50
For per-app (not per-device) volume, use NirSoft's SoundVolumeView GUI or
svcl.exe /SetAppDefault <process>.exe Playback. Per-app volume is not
wrapped here because the app-vs-device distinction deserves explicit CLI args.
Exclusive mode gives an app sole ownership of the device at a negotiated format. Bit-perfect, lowest latency, but blocks every other app.
Each endpoint has a registry flag "Allow applications to take exclusive control of this device". The wrapper reads it:
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py exclusive-test "Speakers (Realtek High Definition Audio)"
Output:
Speakers (Realtek High Definition Audio) -> exclusive mode: allowed|blocked|unknown
allowed = apps can request exclusive mode. blocked = Windows will always
return AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED. The toggle lives in Sound
Control Panel → Properties → Advanced.
To set that flag from script you need elevation + registry write — not
wrapped here deliberately. See
references/exclusive-vs-shared.md for
the manual path and the audio-engine implications.
The go-to free virtual audio cable on Windows. Creates two endpoints (CABLE Input = a virtual speaker, CABLE Output = a virtual mic) that are internally wired. Anything played to CABLE Input is captured from CABLE Output.
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py vbcable-install
Prints the download URL and install steps (does not auto-download). The script refuses to fetch the installer itself — VB-Audio is donationware + has paid tiers; auto-install risks violating their T&Cs.
Typical OBS system-audio pattern:
VoiceMeeter is a virtual mixer that ships its own set of virtual WDM devices (VAIO1/2/3) and acts as an ASIO host. Free for the 2-bus version, donationware for Banana (3 physical + 2 virtual) and Potato (5+3).
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py voicemeeter-config
Prints the install URL and basic setup. Configuration is primarily GUI; the
config XML lives under %APPDATA%\VB\Voicemeeter. Scriptable via the
C API (VoicemeeterRemote.dll) or the unofficial Python binding
pip install voicemeeter-api. See
references/virtual-cable.md for a worked
routing example.
Install-Module from
PSGallery is trust-by-repository. Users with strict execution policy may
need Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.Id GUID from Get-AudioDevice -List.set-default via AudioDeviceCmdlets changes the Multimedia default;
communications is a separate flag. Zoom/Discord pull from the
communications endpoint by default, not the multimedia one. To change both,
call set-default --kind playback then set-default --kind communications.IAudioClient::Initialize returns
AUDCLNT_E_UNSUPPORTED_FORMAT.audiodg.exe) always resamples shared-mode
streams to the endpoint's fixed "mix format". If the mix format is
48 kHz 24-bit, a 44.1 kHz 16-bit track gets resampled before it even hits
the device. This is why bit-perfect listeners use exclusive mode.IAudioClient3::InitializeSharedAudioStream gives sub-3 ms
latency without exclusive mode, but requires Windows 10+ and an endpoint
whose audio engine period is small enough (GetSharedModeEnginePeriod).
Not every driver / hardware combo supports it.HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\ <GUID>\Properties\{b3f8fa53-0004-438e-9003-51a46e139bfc},2 — that's what
exclusive-test reads. Writing requires SYSTEM / admin + a reboot to take
effect for some driver stacks.uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py list-devices --kind playback
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py set-default "Headphones (Sony WH-1000XM5 Stereo)"
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py set-default "Microphone (USB PnP Sound Device)" --kind communications
# Multimedia default stays on your studio interface for music/games.
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py vbcable-install
# (run the printed installer; reboot)
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py set-default "CABLE Input (VB-Audio Virtual Cable)"
# Point OBS Audio Input Capture at "CABLE Output (VB-Audio Virtual Cable)"
uv run ${CLAUDE_SKILL_DIR}/scripts/winaudio.py exclusive-test "Speakers (Realtek High Definition Audio)"
# If output says "blocked", open Sound Control Panel -> the device -> Properties
# -> Advanced tab -> check "Allow applications to take exclusive control".
# If "allowed", the app's requested format is not supported at the hardware
# level — try 44100 Hz 16-bit to match CD, or inspect the endpoint's supported
# formats in that same Advanced tab.
# Skip the Python wrapper; call AudioDeviceCmdlets directly:
Import-Module AudioDeviceCmdlets
$d = Get-AudioDevice -List | Where-Object { $_.Name -like '*Focusrite*' -and $_.Type -eq 'Playback' }
Set-AudioDevice -Index $d.Index
The wrapper is a convenience layer; any PowerShell script targeting the same cmdlet works fine.
Import-Module: The specified module 'AudioDeviceCmdlets' was not loadedCause: Module not installed. Fix:
Install-Module -Name AudioDeviceCmdlets -Scope CurrentUser -Force
Get-AudioDevice : Running scripts is disabled on this systemCause: Execution policy Restricted (default on Windows Server).
Fix:
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
set-default succeeded but the app still plays through old deviceCause: Many apps cache the endpoint at startup and don't listen for
MMDevice default-change notifications. Restart the app.
Fix: Restart the app, or for Chromium-based apps use their internal
"Audio output" setting in site permissions.
AUDCLNT_E_UNSUPPORTED_FORMATCause: Requested format isn't natively supported by the driver in exclusive mode. No resampler runs in exclusive mode. Fix: Match exactly what the Properties → Advanced tab lists as a supported format, or switch to shared mode (accepts the engine mix format via resampling).
Cause: Installer ran but driver signing was blocked; reboot skipped. Fix: Reboot. If still missing, reinstall as Administrator and approve the UAC / driver-signing prompt when it appears.
Cause: Sample-rate mismatch between physical A1 output and VoiceMeeter's internal engine rate. Fix: Menu → System Settings/Options → set engine rate to match the physical interface's configured sample rate.
references/exclusive-vs-shared.md.svcl.exe flag reference, VoiceMeeter routing examples →
references/virtual-cable.md.