{"id":35034996,"url":"https://github.com/mr5niper/windowsaudiocontrol-cli-wgui","last_synced_at":"2026-05-10T07:14:01.859Z","repository":{"id":329057513,"uuid":"1116600168","full_name":"Mr5niper/WindowsAudioControl-CLI-wGUI","owner":"Mr5niper","description":"Windows Audio Command Line Interface w/GUI (pycaw + comtypes based)","archived":false,"fork":false,"pushed_at":"2026-04-02T10:54:23.000Z","size":1022,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-02T15:36:33.276Z","etag":null,"topics":["audio-commands","audio-control","audio-controls","command-line","command-line-interface","command-line-tool","windows-audio"],"latest_commit_sha":null,"homepage":"https://github.com/Mr5niper/WindowsAudioControl-CLI-wGUI/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mr5niper.png","metadata":{"files":{"readme":"docs/README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-15T05:41:27.000Z","updated_at":"2026-04-02T04:58:15.000Z","dependencies_parsed_at":"2026-02-06T10:07:42.228Z","dependency_job_id":null,"html_url":"https://github.com/Mr5niper/WindowsAudioControl-CLI-wGUI","commit_stats":null,"previous_names":["mr5niper/windowsaudiocontrol-cli-wgui"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/Mr5niper/WindowsAudioControl-CLI-wGUI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr5niper%2FWindowsAudioControl-CLI-wGUI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr5niper%2FWindowsAudioControl-CLI-wGUI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr5niper%2FWindowsAudioControl-CLI-wGUI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr5niper%2FWindowsAudioControl-CLI-wGUI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mr5niper","download_url":"https://codeload.github.com/Mr5niper/WindowsAudioControl-CLI-wGUI/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mr5niper%2FWindowsAudioControl-CLI-wGUI/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31318132,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T21:35:00.834Z","status":"ssl_error","status_checked_at":"2026-04-02T21:34:59.806Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio-commands","audio-control","audio-controls","command-line","command-line-interface","command-line-tool","windows-audio"],"created_at":"2025-12-27T07:48:22.928Z","updated_at":"2026-05-10T07:14:01.849Z","avatar_url":"https://github.com/Mr5niper.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Windows Audio Control CLI + GUI\n## audioctl.exe (pycaw/comtypes-based)\n\nA Windows audio control utility with a scriptable CLI and an optional GUI. You can:\n\n- **Automate common tasks:** list devices, set default playback/recording endpoints, adjust volume, mute/unmute, toggle “Listen to this device,” and control Enhancements.\n- **Learn vendor toggles:** “Learn Enhancements” and “Learn FX” observe what Windows/drivers change in the registry for a specific device, then store those rules so audioctl can reproduce the same toggle later.\n- **Control individual effects (FX):** once learned, per-effect toggles (e.g., BassBoost, Loudness) can be enabled/disabled on demand, even when the driver does not provide a direct API.\n- **Query state safely:** fast, read-only commands return current volume, mute, listen, enhancements, and FX state for scripts, hotkeys, and status UIs.\n- **Use the GUI when convenient:** the GUI provides context-aware right-click actions and guided learn workflows, while still using the CLI underneath as the source of truth.\n\naudioctl is designed to be CLI-first for repeatability and automation; the GUI is a helper layer on top.\n\n---\n[Quick Start](#quick-start)\n\u003cBR\u003e\n[Command Map (Full Tree)](#command-map-full-tree)\n\u003cBR\u003e\n[List Devices](#list-devices)\n\u003cBR\u003e\n[Set Default Endpoints](#set-default-devices-cli)\n\u003cBR\u003e\n[Adjust Volume / Mute](#set-volume-or-muteunmute-cli)\n\u003cBR\u003e\n[Listen To This Device](#listen-to-this-device-capture-only-cli)\n\u003cBR\u003e\n[Audio Enhancements](#audio-enhancements-sysfx--vendor-toggles-cli)\n\u003cBR\u003e\n[Query Helpers (Read‑Only)](#query-helpers-readonly)\n\u003cBR\u003e\n[Diagnostic Discovery](#diagnostics--discovery-optional-readonly)\n\u003cBR\u003e\n[Wait For A Device](#wait-for-a-device-to-appear-cli)\n\u003cBR\u003e\n[General Exit Codes](#general-exit-codes)\n\u003cBR\u003e\n[Troubleshooting](#troubleshooting)\n\u003cBR\u003e\n[GUI (Graphical User Interface)](#gui-graphical-user-interface)\n\u003cBR\u003e\n\n\n---\n\n# Quick Start\n- Help:\n  ```bash\n  .\\audioctl.exe -h\n  ```\n- No arguments (double‑click or run without args) launches the GUI:\n  ```bash\n  .\\audioctl.exe\n  ```\n\n---\n\n## Selectors (used by most commands)\n- `--id \"{endpoint-id}\"` (exact endpoint ID)\n- `--name \"substring\"` (case-insensitive substring match)\n- `--regex` (treat `--name` as a regex)\n- `--flow Render|Capture` (optional filter for playback/recording device)\n- `--index N` (Number-based index to disambiguate between multiple matches)\n- `--playback-name \"substring\"` (Render-only name selector; for set-default)\n- `--recording-name \"substring\"` (Capture-only name selector; for set-default)\n\nWhen using the `--name`, `--playback-name`, or `--recording-name` options, commands accept partial matches against device names or descriptions. If the specified text uniquely identifies exactly one playback or recording device, that device will be targeted and an index value is not required.\n\n---\n\n# Command map (full tree)\n\n```\naudioctl\n │ \n ├─ list [--all] [--json]\n │ \n ├─ set-default\n │  ├─ --playback-id/--playback-name [--playback-role console|multimedia|communications|all]\n │  └─ --recording-id/--recording-name [--recording-role console|multimedia|communications|all]\n │     [--index] [--regex]\n │ \n ├─ set-volume\n │  └─ (--id | --name) [--flow Render|Capture] (--level 0..100 | --mute | --unmute)\n │     [--index] [--regex]\n │ \n ├─ listen (Capture only)\n │  └─ (--id | --name) (--enable | --disable)\n │     [--playback-target-id [\u003cRenderID\u003e]] [--playback-target-name [\u003cRenderName\u003e]]\n │     [--index] [--regex]\n │ \n ├─ enhancements\n │  ├─ Main switch:\n │  │  └─ (--id | --name) [--flow] (--enable | --disable | --learn)\n │  │     [--index] [--regex] [--prefer-hklm] [--vendor-ini PATH]\n │  │ \n │  └─ FX operations:\n │     ├─ --list-fx [--json]\n │     ├─ --learn-fx \"FX_NAME\"\n │     ├─ --enable-fx \"FX_NAME\" | --disable-fx \"FX_NAME\"\n │     └─ --delete-fx \"FX_NAME\"\n │ \n ├─ get-volume [--id|--name] [--flow] [--index] [--regex]\n │ \n ├─ get-listen [--id|--name] [--index] [--regex]          (Capture)\n │ \n ├─ get-enhancements [--id|--name] [--flow] [--index] [--regex]\n │ \n ├─ get-device-state [--id|--name] [--flow] [--index] [--regex] [--vendor-ini PATH]\n │ \n ├─ diag-sysfx [--id|--name] [--flow] [--index] [--regex]\n │ \n ├─ diag-mmdevices [--id|--name] [--flow] [--index] [--regex]\n │ \n ├─ discover-enhancements [--id|--name] [--flow] [--index] [--regex]\n │  └─ [--output-dir DIR] [--ini-snippet FILE]\n │ \n └─ wait (--id|--name) [--flow] [--timeout] [--index] [--regex]\n```\n\n---\n\n# List Devices\n- Human-readable:\n  ```ps1\n  .\\audioctl.exe list\n  ```\n- Include disabled/disconnected:\n  ```ps1\n  .\\audioctl.exe list --all\n  ```\n- JSON output:\n  ```ps1\n  .\\audioctl.exe list --json\n  ```\n\n---\n\n# Set Default Devices (CLI)\nUse `.\\audioctl.exe set-default` to choose the system’s default playback (Render) and/or recording (Capture) endpoints. Targets must be active (`DEVICE_STATE_ACTIVE`). On some systems, you may need an elevated console (Run as Administrator).\n\nRoles you can set:\n- console - the default device most apps use.\n- multimedia - often resolved to the same device as console on most systems.\n- communications - used by calling/telephony apps.\n- all (applies to all three roles)\n\nDefaults if a role is omitted:\n- Playback role defaults to `all`.\n- Recording role defaults to `communications`.\n\nAbout Windows roles (console vs multimedia):\n- On most Windows systems, “console” and “multimedia” effectively point to the same default device. If you set either one, you will typically see both flags update in the next `audioctl list` output. The tool still lets you set them independently, or set `all` for completeness and for environments where they’re distinct.\n\nMost users want a device to be the default for everything. Use:\n- `--playback-role all` for playback (Render)\n- `--recording-role all` for recording (Capture)\n\nGet IDs first (optional but recommended):\n```ps1\n.\\audioctl.exe list --json\n```\n\nDisambiguation when multiple name matches:\n- If your `--playback-name` or `--recording-name` matches more than one active device, the command will stop and print the matching candidates in GUI order with an index for each. Then rerun with `--index N` to choose the one you want.\n- Example of the prompt:\n  ```\n  Multiple playback matches:\n    [Render idx 0] Speakers (USB DAC)  id={...}  defaults=-\n    [Render idx 1] Speakers (Realtek(R) Audio)  id={...}  defaults=multimedia,console\n  Use --index to disambiguate.\n  ```\n\nNotes about JSON output:\n- Successful commands print compact, single‑line JSON (no pretty‑printing). For pretty output, pipe to a formatter (e.g., `| jq .`).\n\n## Examples (only using “all”)\n### 1) Playback (Render) - by name\n```ps1\n.\\audioctl.exe set-default --playback-name \"Speakers\" --playback-role all --index 0\n```\nSample output:\n```json\n{\"set\":[{\"flow\":\"Render\",\"role\":\"all\",\"id\":\"{RENDER-ENDPOINT-ID}\",\"name\":\"Speakers (Realtek(R) Audio)\"}]}\n```\n\u003cbr\u003e\n\n### 2) Playback (Render) - by ID\n```ps1\n.\\audioctl.exe set-default --playback-id \"{RENDER-ENDPOINT-ID}\" --playback-role all\n```\nSample output:\n```json\n{\"set\":[{\"flow\":\"Render\",\"role\":\"all\",\"id\":\"{RENDER-ENDPOINT-ID}\",\"name\":\"Speakers (USB DAC)\"}]}\n```\n\u003cbr\u003e\n\n### 3) Recording (Capture) - by name\n```ps1\n.\\audioctl.exe set-default --recording-name \"USB Microphone\" --recording-role all --index 0\n```\nSample output:\n```json\n{\"set\":[{\"flow\":\"Capture\",\"role\":\"all\",\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"USB Microphone\"}]}\n```\n\u003cbr\u003e\n\n### 4) Recording (Capture) - by ID\n```ps1\n.\\audioctl.exe set-default --recording-id \"{CAPTURE-ENDPOINT-ID}\" --recording-role all\n```\nSample output:\n```json\n{\"set\":[{\"flow\":\"Capture\",\"role\":\"all\",\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"Headset Mic\"}]}\n```\n\u003cbr\u003e\n\n### 5) Playback + Recording - both “all” in one command\n```ps1\n.\\audioctl.exe set-default \\\n  --playback-id \"{RENDER-ENDPOINT-ID}\"   --playback-role all \\\n  --recording-id \"{CAPTURE-ENDPOINT-ID}\" --recording-role all\n```\nSample output:\n```json\n{\"set\":[{\"flow\":\"Render\",\"role\":\"all\",\"id\":\"{RENDER-ENDPOINT-ID}\",\"name\":\"Speakers (Realtek(R) Audio)\"},{\"flow\":\"Capture\",\"role\":\"all\",\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"USB Microphone\"}]}\n```\n\u003cbr\u003e\n\nAdditional notes:\n- If list output shows both console and multimedia toggled after setting only one, that is expected on most Windows builds, they commonly map to the same endpoint.\n- “device not found (active only)”: verify the device is connected/enabled and visible in `audioctl list`.\n- If multiple name matches occur, rerun with `--index N` using the indices printed in the disambiguation prompt.\n\u003cbr\u003e\n\n---\n\n# Set Volume or Mute/Unmute (CLI)\nUse `audioctl set-volume` to change an endpoint’s master volume (0–100%) or toggle its mute state. Targets must be active (`DEVICE_STATE_ACTIVE`). On name selection, prefer adding `--flow` to disambiguate between Render (playback) and Capture (recording). If multiple matches remain, add `--index N` (0‑based, GUI‑order within the flow).\n\nRules:\n- You must specify exactly one of: `--level`, `--mute`, or `--unmute`.\n- `--level` is an integer 0–100 (values outside this range are clamped by the tool).\n- Either `--id` or `--name` is required for selection (with optional `--regex` for pattern matching).\n\nCommand template:\n```bash\naudioctl set-volume\n  (--id \u003cID\u003e | --name \u003cNAME\u003e) [--flow \u003cRender|Capture\u003e]\n  (--level \u003c0..100\u003e | --mute | --unmute)\n  [--index \u003cN\u003e] [--regex]\n```\n\nDisambiguation behavior:\n- If name selection matches more than one active device and you don’t pass `--index`, the tool returns:\n  ```\n  ERROR: multiple matches; specify --index\n  ```\n  Rerun the command with `--flow` and/or `--index N`. Use `.\\audioctl.exe list` (or `--json`) to see devices in the same GUI order.\n\nNotes about JSON output:\n- Successful commands print compact, single‑line JSON. Pipe to a formatter (e.g., `| jq .`) if you want pretty output.\n\u003cbr\u003e\n\n## Examples\n### 1) Set playback volume by name (Render, 30%)\n```ps1\n.\\audioctl.exe set-volume --name \"Speakers\" --flow Render --level 30\n```\nSample output:\n```json\n{\"volumeSet\":{\"id\":\"{RENDER-ENDPOINT-ID}\",\"name\":\"Speakers (Realtek(R) Audio)\",\"level\":30}}\n```\n\u003cbr\u003e\n\n### 2) Set recording volume by ID (Capture, 70%)\n```ps1\n.\\audioctl.exe set-volume --id \"{CAPTURE-ENDPOINT-ID}\" --level 70\n```\nSample output:\n```json\n{\"volumeSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"USB Microphone\",\"level\":70}}\n```\n\u003cbr\u003e\n\n### 3) Mute a playback device by name (Render) with index disambiguation\nIf multiple “Speakers” exist, specify which one using `--index` (0‑based, GUI‑order for Render).\n```ps1\n.\\audioctl.exe set-volume --name \"Speakers\" --flow Render --mute --index 0\n```\nSample output:\n```json\n{\"muteSet\":{\"id\":\"{RENDER-ENDPOINT-ID}\",\"name\":\"Speakers (USB DAC)\",\"muted\":true}}\n```\n\u003cbr\u003e\n\n### 4) Unmute a recording device by ID (Capture)\n```ps1\n.\\audioctl.exe set-volume --id \"{CAPTURE-ENDPOINT-ID}\" --unmute\n```\nSample output:\n```json\n{\"muteSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"USB Microphone\",\"muted\":false}}\n```\n\u003cbr\u003e\n\n### 5) Use regex name matching (Render)\n```ps1\n.\\audioctl.exe set-volume --name \"^Speakers .* Realtek\\\\(R\\\\) Audio$\" --regex --flow Render --level 15\n```\nSample output:\n```json\n{\"volumeSet\":{\"id\":\"{RENDER-ENDPOINT-ID}\",\"name\":\"Speakers (Realtek(R) Audio)\",\"level\":15}}\n```\n\u003cbr\u003e\n\n### 6) Name match without `--flow` and multiple results\nIf both Render and Capture have a device matching “USB”, you’ll see:\n```\nERROR: multiple matches; specify --index\n```\nDisambiguate by flow and/or index:\n```ps1\n.\\audioctl.exe set-volume --name \"USB\" --flow Capture --unmute --index 0\n```\nSample output:\n```json\n{\"muteSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"USB Microphone\",\"muted\":false}}\n```\n\u003cbr\u003e\n\n### 7) Error safeguard: `--level` cannot be combined with `--mute/--unmute`\nInvalid example (will return an error):\n```ps1\n.\\audioctl.exe set-volume --name \"Speakers\" --flow Render --level 20 --mute\n```\nError:\n```\nERROR: Cannot specify both --level and --mute/--unmute\n```\n\nTips:\n- Prefer `--id` for exact targeting (no disambiguation needed).\n- If you get “device not found (active only)”, verify the endpoint is connected/enabled and visible in `.\\audioctl.exe list`.\n- The command controls the endpoint’s master scalar level and mute state (not per‑app volumes).\n\n---\n\n# “Listen to this device” (Capture Only, CLI)\nUse `.\\audioctl.exe listen` to enable or disable “Listen to this device” on a capture (recording) endpoint. The target must be active (`DEVICE_STATE_ACTIVE`). This command only operates on Capture devices; Render devices are not eligible.\n\nYou must specify exactly one of:\n- `--enable`\n- `--disable`\n\nOptional playback routing:\n- `--playback-target-id \"{RENDER-ENDPOINT-ID}\"` routes the monitored audio to a specific playback (Render) endpoint.\n- `--playback-target-id \"\"` routes to the Windows “Default Playback Device.”\n- `--playback-target-name` mirrors the above using a name match; passing the flag without a value selects “Default Playback Device.”\n- If the target flag is omitted, the current routing is preserved.\n\nCommand template:\n```bash\naudioctl listen\n  (--id \u003cCAPTURE-ENDPOINT-ID\u003e | --name \u003cNAME\u003e)\n  (--enable | --disable)\n  [--playback-target-id [\u003cRenderEndpointID\u003e]]\n  [--playback-target-name [\u003cRenderEndpointName\u003e]]\n  [--index \u003cN\u003e] [--regex]\n```\n\nDisambiguation behavior:\n- If name selection matches more than one active capture device and you don’t pass `--index`, the command prints the matching candidates in GUI order (with indices) and exits with:\n  ```\n  ERROR: multiple matches; specify --index\n  ```\n  Rerun with `--index N` (0‑based, GUI‑order for the Capture flow). Use `.\\audioctl.exe list` (or `--json`) to see the same order.\n\nNotes about JSON output:\n- Success prints compact, single‑line JSON.\n- When a retry/verification path is used, the JSON may include a `verifiedBy` field (`\"com\"` or `\"registry\"`).\n\u003cbr\u003e\n\n## Examples\n### 1) Enable Listen for a microphone by name (preserve current playback target)\n```ps1\n.\\audioctl.exe listen --name \"Microphone\" --enable\n```\nSample output:\n```json\n{\"listenSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"Microphone\",\"enabled\":true}}\n```\n\u003cbr\u003e\n\n### 2) Enable listen with specific playback routing\n```ps1\n.\\audioctl.exe listen --name \"Microphone\" --enable --playback-target-name \"Speakers\"\n```\nor\n```ps1\n.\\audioctl.exe listen --id \"{CAPTURE-ENDPOINT-ID}\" --enable --playback-target-id \"{RENDER-ENDPOINT-ID}\"\n```\nSample output:\n```json\n{\"listenSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"Microphone\",\"enabled\":true,\"playbackTargetId\":\"{RENDER-ENDPOINT-ID}\",\"playbackTargetName\":\"Speakers\"}}\n```\n\u003cbr\u003e\n\n### 3) Enable Listen and route to the Default Playback Device\nPassing the target flags without a value selects the Windows default.\n\n```ps1\n.\\audioctl.exe listen --name \"Microphone\" --enable --playback-target-name\n```\nor\n```ps1\n.\\audioctl.exe listen --id \"{CAPTURE-ENDPOINT-ID}\" --enable --playback-target-id\n```\nSample output:\n```json\n{\"listenSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"Microphone\",\"enabled\":true,\"playbackTargetId\":\"default\",\"playbackTargetName\":\"Default Playback Device\"}}\n```\n\u003cbr\u003e\n\n### 4) Disable Listen by exact ID\n```ps1\n.\\audioctl.exe listen --id \"{CAPTURE-ENDPOINT-ID}\" --disable\n```\nSample output:\n```json\n{\"listenSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"USB Microphone\",\"enabled\":false}}\n```\n\u003cbr\u003e\n\n### 5) Use regex name matching with index disambiguation (Capture)\n```ps1\n.\\audioctl.exe listen --name \"Mic\" --regex --enable --index 0\n```\nSample output:\n```json\n{\"listenSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"Studio Mic\",\"enabled\":true}}\n```\n\u003cbr\u003e\n\n### 6) Example with verification source included\n```json\n{\"listenSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"Microphone\",\"enabled\":true,\"verifiedBy\":\"com\"}}\n```\nor:\n```json\n{\"listenSet\":{\"id\":\"{CAPTURE-ENDPOINT-ID}\",\"name\":\"Microphone\",\"enabled\":true,\"verifiedBy\":\"registry\"}}\n```\n\u003cbr\u003e\n\nTips:\n- This command only targets Capture devices. If you try a Render device, it won’t match.\n- Use `audioctl list --json` to get both Capture (for `--id`) and Render endpoints (for routing).\n- If the name matches multiple capture devices, rerun with `--index N`.\n\n---\n\n# Audio Enhancements (SysFX) – Vendor Toggles (CLI)\nUse `.\\audioctl.exe enhancements` to enable or disable “Audio Enhancements” (SysFX) on an endpoint using a vendor‑first method. Many drivers (e.g., Realtek/Waves) expose Enhancements via device‑specific registry DWORDs under MMDevices; this tool writes those DWORDs (when known) and verifies the change.\n\nKey points:\n- Control is vendor‑only at runtime: if no vendor toggle is known for the target endpoint, the command fails and asks you to use `--learn` first.\n- Windows’ `Disable_SysFx` is still read for diagnostics, not used to control state here.\n- HKLM writes require Administrator privileges; use `--prefer-hklm` if your driver only honors HKLM.\n\nYou must specify exactly one of:\n- `--enable`    (turn Enhancements ON)\n- `--disable`   (turn Enhancements OFF)\n- `--learn`     (guided manual learning to append a vendor entry to INI)\n\nCommand template:\n```bash\n# Toggle using vendor DWORDs (if known)\naudioctl enhancements\n  (--id \u003cENDPOINT-ID\u003e | --name \u003cNAME\u003e) [--flow \u003cRender|Capture\u003e]\n  (--enable | --disable)\n  [--index \u003cN\u003e] [--regex]\n  [--prefer-hklm]\n  [--vendor-ini \u003cPATH\u003e]\n\n# Learn a vendor DWORD (you toggle the Windows UI; the tool captures A/B and appends to INI)\naudioctl enhancements\n  (--id \u003cENDPOINT-ID\u003e | --name \u003cNAME\u003e) [--flow \u003cRender|Capture\u003e]\n  --learn\n  [--index \u003cN\u003e] [--regex]\n  [--vendor-ini \u003cPATH\u003e]\n```\n\u003cbr\u003e\n\n## Enhancement Effects (FX)\nBeyond the main switch, you can manage individual effects (per-device) after learning them.\n\n- List learned effects for a device:\n  ```ps1\n  .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --list-fx\n  .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --list-fx --json\n  ```\n  \u003cbr\u003e\n\n- Learn a specific effect (guided, two-pass A/B):\n  ```ps1\n  .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --flow Render --learn-fx \"BassBoost\"\n  ```\n  \u003cbr\u003e\n\n- Toggle an effect:\n  ```ps1\n  .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --flow Capture --enable-fx \"Loudness\"\n  .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --flow Capture --disable-fx \"Loudness\"\n  ```\n  \u003cbr\u003e\n\n- Delete a learned effect association for this device:\n  ```ps1\n  .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --delete-fx \"BassBoost\"\n  ```\n\u003cbr\u003e\n\nNotes about JSON output:\n- Success prints compact, single‑line JSON, e.g.:\n  ```json\n  {\"enhancementsSet\":{\"id\":\"{ENDPOINT-ID}\",\"name\":\"Speakers (Realtek(R) Audio)\",\"enabled\":true,\"verifiedBy\":\"vendor:realtek_waves_primary\"}}\n  ```\n  \u003cbr\u003e\n\n- FX toggles:\n  ```json\n  {\"fxSet\":{\"id\":\"{ENDPOINT-ID}\",\"name\":\"Speakers\",\"fx_name\":\"BassBoost\",\"enabled\":true,\"verifiedBy\":\"vendor-fx:multi:BassBoost\"}}\n  ```\n\n---\n\u003cbr\u003e\n\n# Query helpers (read‑only)\nFast, side‑effect‑free commands perfect for status bars, hotkeys, and scripts.\n\n- Get current volume/mute:\n  ```ps1\n  .\\audioctl.exe get-volume --id \"{ENDPOINT-ID}\"\n  ```\n  or use --name (--regex if needed)\n  ```ps1\n  .\\audioctl.exe get-volume --name \"Speakers\" --flow Render --index 0 --regex\n  ```\n  Returns:\n  ```json\n  {\"id\":\"{ENDPOINT-ID}\",\"name\":\"NAME\",\"flow\":\"Render\",\"volume\":78,\"muted\":false}\n  ```\n  \n\u003cbr\u003e\n\n- Get current “Listen” state (Capture):\n  ```ps1\n  .\\audioctl.exe get-listen --id \"{ENDPOINT-ID}\"\n  ```\n  or use --name (--index and --regex if needed)\n  ```ps1\n  .\\audioctl.exe get-listen --name \"Microphone\" --index 0 --regex\n  ```\n  Returns:\n  ```json\n  {\"id\":\"{ENDPOINT-ID}\",\"name\":\"NAME\",\"flow\":\"Capture\",\"listenEnabled\":true}\n  ```\n\n\u003cbr\u003e\n\n- Check status with playback routing details:\n  Use the `--playback-target-id` or `--playback-target-name` flags (even without values) to force the inclusion of routing data.\n  ```ps1\n  .\\audioctl.exe get-listen --id \"{ENDPOINT-ID}\" --playback-target-id\n  ```\n  ```json\n  {\"id\":\"{ENDPOINT-ID}\",\"name\":\"Microphone\",\"flow\":\"Capture\",\"listenEnabled\":true,\"playbackTargetId\":\"{RENDER-GUID}\",\"playbackTargetName\":\"Headphones (External DAC)\"}}\n  ```\n\n\u003cbr\u003e\n\n- Get current Enhancements state (vendor‑only):\n  ```ps1\n  .\\audioctl.exe get-enhancements --id \"{ENDPOINT-ID}\"\n  ```\n  or use --name (--index and --regex if needed)\n  ```ps1\n  .\\audioctl.exe get-enhancements --name \"Speakers\" --flow Render --index 0 --regex\n  ```\n  Returns:\n  ```json\n  {\"id\":\"{ENDPOINT-ID}\",\"name\":\"Speakers\",\"flow\":\"Render\",\"enhancementsEnabled\":true}\n  ```\n  \n\u003cbr\u003e\n\n- Aggregated device state (for GUI/scripts):\n  ```yaml\n  .\\audioctl.exe get-device-state [--id \u003cID\u003e | --name \u003cNAME\u003e] [--flow Render|Capture] [--index \u003cN\u003e] [--regex] [--vendor-ini PATH]\n  ```\n  Returns:\n  ```json\n  {\"id\":\"{ENDPOINT-ID}\",\"name\":\"NAME\",\"flow\":\"Render\",\"volume\":78,\"muted\":false,\"listenEnabled\":null,\"enhancementsEnabled\":true,\"availableFX\":[{\"fx_name\":\"BassBoost\",\"state\":true,\"source\":\"ini\"}]}\n  ```\n\n---\n\n# Diagnostics \u0026 Discovery (Optional, Read‑Only)\n- View live Enhancements status and vendor state:\n  ```ps1\n  .\\audioctl.exe diag-sysfx --name \"Speakers\" --flow Render\n  ```\n- Dump all MMDevices values for an endpoint (HKCU/HKLM; FxProperties/Properties):\n  ```ps1\n  .\\audioctl.exe diag-mmdevices --id \"{RENDER-ENDPOINT-ID}\" --flow Render\n  ```\n- Interactive discovery with reports (TXT/JSON) and optional INI snippet:\n  ```ps1\n  .\\audioctl.exe discover-enhancements --name \"Speakers\" --flow Render --output-dir \".\" --ini-snippet \".\\vendor_snippets.ini\"\n  ```\n\n---\n\n# Wait for a Device to Appear (CLI)\nUse `.\\audioctl.exe wait` to block until a device becomes active (appears) or until a timeout expires. Matching is against active endpoints only (`DEVICE_STATE_ACTIVE`). When a match is found, the command prints a compact, single‑line JSON object and exits with code 0.\n\n- Template:\n  ```bash\n  audioctl wait\n    (--id \u003cENDPOINT-ID\u003e | --name \u003cNAME\u003e) [--flow \u003cRender|Capture\u003e]\n    [--timeout \u003cseconds\u003e] [--index \u003cN\u003e] [--regex]\n  ```\n- Exit codes:\n  - 0: found a matching active device\n  - 3: timeout\n  - 4: multiple matches (rerun with `--index`)\n- Tips:\n  - Prefer `--id` when you know it.\n  - Add `--flow` when the name appears in both flows.\n \n## Examples\n  ```ps1\n  .\\audioctl.exe wait --name \"USB Headset\" --timeout 30\n  ```\n  When the device is found, the CLI prints the following device dictionary as a compact string:\n  ```json\n  {\"found\":{\"id\": \"{ENDPOINT-ID}\", \"name\": \"Headset Earphone (USB Audio Device)\",\"flow\":\"Render\",\"state\":\"active\",\"isDefault\":{\"console\":true,\"multimedia\":true,\"communications\":false},\"guiIndex\": 2}}\n  ```\n  \u003cbr\u003e\n---\n\n# General Exit Codes\n- `0` – success\n- `1` – runtime failure or invalid option combo\n- `3` – device not found or wait timeout\n- `4` – multiple matches; provide `--index`\n- `130` – Ctrl‑C interrupted\n\n---\n\n# Troubleshooting\n- **Set-default fails**:\n  - Try running in an elevated PowerShell / Command Prompt (Run as Administrator).\n- **comtypes/automation errors in the EXE**:\n  - The build already includes a compatibility shim at the top of `audioctl/compat.py`.\n  - Rebuild with the provided PyInstaller command if you change Python or comtypes versions.\n- **“Listen” seems unchanged**:\n  - Use explicit default routing: `--playback-target-id \"\"` (Default Playback Device).\n  - Check JSON output: look at `enabled` and `verifiedBy` (`\"com\"` or `\"registry\"`).\n- Enhancements don’t toggle:\n  - First try the toggle directly:\n    ```ps1\n    .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --flow Render --enable\n    ```\n    If you get:\n    ```\n    ERROR: No vendor toggle available for this device. Use --learn to teach a vendor method.\n    ```\n    then proceed to learn.\n  - Learn the vendor toggle (manual A/B):\n    ```ps1\n    .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --flow Render --learn\n    ```\n    After a successful learn, re-run the toggle:\n    ```ps1\n    .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --flow Render --disable\n    ```\n  - If learn fails or the result can’t be verified:\n    - Inspect live state vs vendor with:\n      ```ps1\n      .\\audioctl.exe diag-sysfx --id \"{ENDPOINT-ID}\" --flow Render\n      ```\n    - Capture ON/OFF snapshots and generate a report/snippet:\n      ```ps1\n      .\\audioctl.exe discover-enhancements --id \"{ENDPOINT-ID}\" --flow Render --output-dir \".\" --ini-snippet \".\\vendor_snippets.ini\"\n      ```\n      Use the suggested INI snippet or share the TXT/JSON for analysis.\n  - Permissions and hive preference:\n    - Some drivers only honor HKLM. Re-run the toggle with:\n      ```ps1\n      .\\audioctl.exe enhancements --id \"{ENDPOINT-ID}\" --flow Render --enable --prefer-hklm\n      ```\n      (Run an elevated console if HKLM writes are required.)\n  - Confirm selection and INI placement:\n    - Make sure you’re targeting the correct endpoint/flow (use `--flow` and `--index` if needed).\n    - Verify `vendor_toggles.ini` is at the expected path (exe directory if writable, otherwise `%LOCALAPPDATA%\\audioctl\\vendor_toggles.ini`) and that your endpoint GUID is listed under `devices =` in the learned section.\n\n---\n\n# GUI (Graphical User Interface)\n### Launch the GUI:\n- Double-click `audioctl.exe` (no arguments), or run it without command-line options.\u003cbr\u003e\n  \u003cbr\u003e\n    \u003cimg width=\"98\" height=\"130\" alt=\"image\" src=\"https://github.com/user-attachments/assets/46adf78b-c222-4aaa-8e5d-0bd5bcc5b9bb\" /\u003e\n  \u003cbr\u003e\n  \n\u003cimg width=\"1980\" height=\"754\" alt=\"image\" src=\"https://github.com/user-attachments/assets/c206ea76-0efe-4e95-9b63-e76385ca0f3d\" /\u003e\n\n\n\u003cbr\u003e\n\n### Features\n- A visual overview of all playback (Render) and recording (Capture) devices, clearly grouped and sorted for easy navigation and management.\n- **Right-click** or **double-click** a device for actions:\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003cimg width=\"356\" height=\"237\" alt=\"image\" src=\"https://github.com/user-attachments/assets/460f6740-1eac-4f92-8afe-db89675661f8\" /\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u003cbr\u003e\n\n  - **“Set as Default (all roles)”**\n    - Sets the selected device as the system default for Console, Multimedia, and Communications roles.\n  - “Set Volume…”\n    - Opens a volume control dialog to precisely adjust the device’s output or input level.\n    \u003cbr\u003e\n    \u003cimg width=\"218\" height=\"146\" alt=\"image\" src=\"https://github.com/user-attachments/assets/b58c8b9e-df50-411a-ae13-d341d61ce332\" /\u003e\n    \u003cbr\u003e\n  - **“Mute” / “Unmute”**\n    - Switch the device between muted and active audio states.\n  - **“Toggle Listen (capture only)”**\n    - Enable or disable “Listen to this device” for microphones and other recording inputs.\n  - **“Enable/Disable Enhancements”**\n    - Turn vendor-provided audio enhancements on or off when a known enhancement toggle is available.\n  - **“Enhancement Effects”**\n    - Individually toggle specific enhancement effects discovered and stored in your **vendor_toggles.ini** file.\n    \u003cimg width=\"642\" height=\"237\" alt=\"image\" src=\"https://github.com/user-attachments/assets/d79cf646-6fb0-43fc-b417-85c88885583e\" /\u003e\n  \n  - **“Learn Enhancements”** (discover a vendor DWORD and/or effects for that device)\n    - Scan and identify vendor-specific enhancement DWORDs and per-effect settings for the selected device.\u003cbr\u003e\n    \u003cimg width=\"346\" height=\"238\" alt=\"image\" src=\"https://github.com/user-attachments/assets/ebb033e9-89fb-4a34-a92a-165d443fdd7a\" /\u003e\n\n\n### Print CLI Commands\n- Enable **“Print CLI commands”** in the top bar.  \n    \n    \u003cimg width=\"320\" height=\"85\" alt=\"image\" src=\"https://github.com/user-attachments/assets/f062528a-3729-4639-8a35-f593d894da33\" /\u003e\n\n- Every GUI action will print the equivalent `audioctl.exe` command to the console in blue font\n  \u003cbr\u003e(useful for learning the CLI and scripting).\n\n    \u003cimg width=\"1602\" height=\"184\" alt=\"image\" src=\"https://github.com/user-attachments/assets/892334e9-6409-4eed-941b-7659fbd010b1\" /\u003e\n\n\n- Highlight a command, right-click, and copy it directly from the console:\n    \n    \u003cimg width=\"820\" height=\"131\" alt=\"image\" src=\"https://github.com/user-attachments/assets/1d64ee6f-7c83-4649-8ee3-b59ba0a880a2\" /\u003e\n\n### Refresh Devices\n- Click **\"Refresh\"** or press `F5`.\n  (Processing time varies based on device count and enhancement effects)\n\n### Notes\n- Setting default devices via the GUI may require Administrator privileges; the GUI will warn when recommended.\n- Group header rows (e.g., “Playback (Render)”) are not selectable and have no actions; right-click the actual device entries.\n\n---\n\n## Credits\n### Mr5niper: \n\u003chttps://github.com/Mr5niper\u003e\n\nLead Developer.  Performed the original research and reverse-engineering of the Windows registry-based \"Learn\" logic for Enhancements and FX.  Implemented critical stability shims for comtypes and pycaw to resolve apartment-lifetime issues, prevents shutdown crashes, and ensures thread-safe COM interactions.  Designed the CLI-to-GUI architecture.\u003cbr\u003e\n### Pycaw: \n\u003chttps://github.com/AndreMiras/pycaw\u003e\n\nUsed for the underlying Windows Core Audio API endpoint wrappers.\u003cbr\u003e\n### comtypes: \n\u003chttps://github.com/enthought/comtypes\u003e\n\nUsed for COM interface handling and PROPVARIANT support.\u003cbr\u003e\n### The Windows Audio Community:\nFor historical research into the undocumented IPolicyConfig and IPolicyConfigFx interfaces used for default endpoint selection.\n\n---\n\n## Third‑Party License Texts\n\n### pycaw - MIT License\n```text\nCopyright (c) Andre Miras and contributors\nPermission is hereby granted, free of charge, to any person obtaining a copy\n...\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n...\n```\nSource: \u003chttps://github.com/AndreMiras/pycaw\u003e\n\n---\n\n### comtypes - MIT License\n```text\nCopyright (c) Thomas Heller, Enthought, Inc., and contributors\nPermission is hereby granted, free of charge, to any person obtaining a copy\n...\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n...\n```\nSource: \u003chttps://github.com/enthought/comtypes\u003e\n\n---\n\n### PyInstaller License Notice (for binary distributions)\nIf you distribute a PyInstaller-built executable of this project, PyInstaller is licensed under the GNU General Public License v2 (GPL-2.0) with a special exception that permits using PyInstaller to build and distribute executables, regardless of your program’s license.\nFull text: \u003chttps://github.com/pyinstaller/pyinstaller/blob/develop/COPYING.txt\u003e  \nProject page: \u003chttps://www.pyinstaller.org/\u003e\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmr5niper%2Fwindowsaudiocontrol-cli-wgui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmr5niper%2Fwindowsaudiocontrol-cli-wgui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmr5niper%2Fwindowsaudiocontrol-cli-wgui/lists"}