Repository navigation
Releases: oparada1988/WaveController
Release list
WaveController v0.0.4.3 Pre-Alpha
[0.0.4.3] - 2026-10-27 (Pre-Alpha)
Added
- Native Keyboard Shortcuts Dialog & Desktop Accelerators:
- Integrated native GTK4/Libadwaita shortcuts window (
ShortcutsManager) accessible viaF1,Ctrl+?, orCtrl+/. - Added global view switching accelerators:
Ctrl+1(Mixes),Ctrl+2(Effects Rack),Ctrl+3(Audio Flow), andCtrl+4(Settings). - Added window management shortcuts:
Ctrl+Mto toggle Compact Mode,Ctrl+Bto toggle the left navigation sidebar, andEscapeto exit Compact Mode.
- Integrated native GTK4/Libadwaita shortcuts window (
- Mixer Header Quality-of-Life Controls:
- Implemented mouse scroll wheel volume adjustments directly over
MixHeaderCardheaders for fast, precise volume trimming. - Added double-click reset to return mix master levels back to 100% instantly.
- Implemented mouse scroll wheel volume adjustments directly over
- Compact Mode IPC Integration:
- Added IPC server endpoints (
get_compact_mode,toggle_compact_mode,set_compact_mode) inIPCServerfor programmatic control and Stream Deck plugin integration.
- Added IPC server endpoints (
- Comprehensive Documentation & Visual Showcases:
- Updated
README.mdwith high-resolution visual guides for Audio Flow (patchbay routing graph) and Compact Mode (Horizontal & Vertical layouts). - Expanded the hardware compatibility and feature support matrix.
- Updated
Performance & Optimization
- Port Metadata Caching & CPU Overhead Reduction:
- Added an 800ms thread-safe TTL cache in
get_active_port_metadata_mapto prevent repetitivepw-dumpsubprocess executions during audio graph changes, significantly reducing idle and active CPU usage.
- Added an 800ms thread-safe TTL cache in
- Thread-Safe Debounced Configuration Saving:
- Hardened
ConfigManager.schedule_savewith mutex locking to prevent disk thrashing and race conditions during rapid volume fader movements.
- Hardened
WaveController v0.0.4.2 Alpha
[0.0.4.2] - 2026-10-17 (Pre-Alpha)
Added
- Native Linux Packaging (.deb and .rpm):
- Added complete Debian packaging infrastructure (
packaging/debian/control,postinst,postrm) for Ubuntu/Debian distributions. - Added Red Hat / Fedora RPM packaging infrastructure (
packaging/rpm/wavecontroller.spec) supportingx86_64architecture, systemd user service integration, and udev rule deployment. - Automated package creation via
scripts/build_packages.shfor local builds. - Added GitHub Actions CI/CD workflow (
.github/workflows/build-packages.yml) automatically building.deband.rpmartifacts and attaching them along with SHA256 checksums to GitHub Releases.
- Added complete Debian packaging infrastructure (
- Contextual Signal Strip in Audio Flow:
- Implemented an interactive
SignalStripproperty bar embedded in the Audio Flow toolbar for selected nodes. - Real-time controls for output target device selection, volume faders, mute toggles, and hardware microphone preamps (48V phantom power status badge & Clipguard toggle).
- Implemented an interactive
- Embedded FX Rack Inspector in Audio Flow:
- Integrated slide-over
FXSidebarinto the Audio Flow graph view with quick-access DSP parameter sliders. - Added a reactive
.wave-fx-badgeto the toolbar that glows violet when channel effects are active and dims when bypassed.
- Integrated slide-over
- Personal Mix Target Flexibility:
- Unlocked the output target selector dropdown in
MixHeaderCardfor the Personal Mix, allowing personal monitoring to be routed to any hardware audio sink. - Updated
SinkManagerto honor custom Personal Mix sink routing while preserving OOBE wizard defaults.
- Unlocked the output target selector dropdown in
- Bidirectional Matrix & Graph Synchronization:
- Connected mixer matrix cross-point cells directly to Audio Flow connection states so linking or severing channels in one view instantly updates the other in real time.
Changed
- Unified Toolbar Button Styling:
- Matched the
Add Channelbutton style to the standard mutedAdd Mixbutton style. - Locked toolbar height to 46px to eliminate view jumping between Mixer Matrix and Audio Flow.
- Matched the
- Repository Cleanup & Optimization:
- Removed deprecated scratch test scripts (
scripts/live_hardware_test.py) and eliminated unused internal routing variables.
- Removed deprecated scratch test scripts (
WaveController 0.0.4.0 Alpha
[0.0.4.0] - 2026-09-26 (Alpha 4)
Added
- Slide-out FX Inspector Sidebar:
- Added an interactive, collapsible FX sidebar in the mixer matrix with smooth slide-left animation (
Gtk.Revealer, 240ms) and click-away background dismissal. - Quick, real-time toggling and intensity adjustments (0–100% sliders) for built-in DSP effects (Equalizer, Compressor, Noise Gate, RNNoise, De-Esser, Limiter, Highpass) and hostable external LV2 plugins.
- Added an interactive, collapsible FX sidebar in the mixer matrix with smooth slide-left animation (
- Granular Stream Deck & IPC Effects Control:
- Added
get_fx_statuscommand over the Unix IPC socket, returning comprehensive rack state: master bypass, active built-in DSP toggles, and hostable external LV2 plugins. - Added
toggle_fxfor channel master rack bypass, andtoggle_channel_effect/set_channel_effectfor targeted per-effect control over individual DSP and LV2 modules. - Decoupled rack bypass logic: enabling any individual effect automatically awakens the master channel rack if it was bypassed.
- Added
- Virtual System Output Device Exposure for App Channels:
- Single application channels can now be exposed as independent virtual sound cards (
Audio/Sink) directly to the OS, allowing granular routing in external applications without requiring a group channel.
- Single application channels can now be exposed as independent virtual sound cards (
- System Default Output Channel ("Desktop Audio"):
- WaveController can now automatically provision and manage a dedicated "Desktop Audio" virtual sink channel for unassigned application audio streams.
- Updated Settings and the Setup Wizard to select the default virtual channel directly.
Changed
- OOBE Setup Wizard Modernization:
- Redesigned Page 5 to remove redundant primary device selectors in favor of automatic hardware mapping and unified system default toggles.
- Added automatic provisioning of the Desktop Audio channel when enabling system defaults during initial setup.
- Settings View Layout:
- Wrapped the Preferences page in an automatic
Gtk.ScrolledWindowto prevent UI overflow or footer truncation on compact screen resolutions.
- Wrapped the Preferences page in an automatic
Fixed
- Wave Hardware Disconnect Shield:
- Added
_is_live_elgato_devicechecks to prevent physical Wave XLR and Wave microphones from falsely transitioning to "Disconnected" while PipeWire dynamically reloads or switches audio profiles.
- Added
- System Resume & Power Lifecycle Stability:
- Fixed a native segmentation fault on Linux system resume by declaring explicit 64-bit ctypes function signatures for
libusb_detach_kernel_driverandlibusb_control_transfer.restype. - Offloaded USB hardware reconnection routines to worker threads to eliminate UI freezes on wake.
- Added hardware suspend awareness to blackout LED rings during sleep and prevent dial event dropouts.
- Fixed a native segmentation fault on Linux system resume by declaring explicit 64-bit ctypes function signatures for
- Cross-Device Microphone Isolation:
- Fixed an audio routing edge case to prevent physical microphones or auxiliary inputs from linking or leaking across unrelated audio devices.
- Capacitive Mute Hardware Sync:
- Restored visual capacitive mute styling on
MixHeaderCardwhen hardware mute states change via physical touch.
- Restored visual capacitive mute styling on
WaveController 0.0.3.2 prealpha
[0.0.3.2] - 2026-09-10
Added
- Per-effect intensity dial: each DSP effect in the channel FX popover now has its own rotary dial (drag vertically, scroll wheel to nudge, double-click to reset) controlling how aggressively that effect is applied, in addition to its existing on/off toggle. Includes a 50% neutral-position marker and dims visually when its effect is disabled.
- Plugin management ("Install Effect"): Effects Manager can now install external VST3/LV2 plugin bundles via a folder picker or drag-and-drop. Installed plugins are symlinked into
~/.vst3/~/.lv2and tracked in a manifest so they can be safely removed later — built-in effects, system-found plugins, and pre-existing user-directory plugins are never removable, only ones the app itself installed. - Custom plugin scan paths: Effects Manager can now scan additional user-specified directories for VST3/LV2 bundles (e.g. Flatpak-sandboxed or DAW-bundled plugin folders).
Changed
- OOBE Page 5 redesigned: replaced the redundant "Primary Input/Output Device" dropdowns with the same "Allow WaveController to set system input/output defaults?" toggle used in Settings. Primary device selection is now derived automatically from the hardware chosen on Page 4 instead of asking twice.
- "Indexed Plugins Library" now hides internal duplicates: Built-in effects (already shown as toggles in the DSP Chain section) and the raw LADSPA re-discovery of WaveController's own bundled engine files no longer clutter the plugin list — only genuinely external/user plugins are shown.
Fixed
- FX master enable/disable toggle didn't reliably stop the DSP chain.
reload_channel_fx()treated the literal channel id"mic"as a "no specific channel" sentinel and always re-derived the channel list via heuristics instead of trusting a real, currently-registered channel id — made the toggle's effective behavior fragile and hard to diagnose. Now resolves a known channel id directly. - Effects Manager's global per-effect toggles didn't actually disable effects for channels with a stale per-channel override. An effect turned off globally could still run if a channel's saved FX record had that effect explicitly enabled. The global toggle is now a hard kill-switch (
enabled = global AND per-channel), and per-channel FX popovers hide rows for globally-disabled effects, refreshing live the instant a global toggle changes (no restart or channel recreation needed). - Mic silence / audio routing drift after extended sessions, root-caused to config state (mix/channel ids, per-channel FX flags) drifting out of sync with the live PipeWire graph over long-running sessions with lots of manual reconfiguration. Documented the recurring symptom and the reliable fix (full config wipe + reinstall) in repo memory for faster recovery; a lighter in-app "Reset Audio Routing" action was identified as a good follow-up but not built this session.
Internal / Maintenance
- Removed 3 confirmed-dead functions with zero call sites anywhere in the repo:
reconcile_meter_ports()(stream_resolver.py),bind_app_to_target_sink()/unbind_app_from_target_sink()(app_tracker.py),sync_source_to_mixes()(source_manager.py) — all abandoned duplicate/experimental routing paths superseded by the logic actually running inpipewire_manager.py. - Removed unused legacy attributes
output_devices/connected_audio_devicesfromusb_hardware.py(written but never read anywhere). - Added timeouts to the hot-path PipeWire routing sync subprocess calls (
pw-link,pw-dump,wpctl) so a hung call can no longer freeze the background sync thread indefinitely. - Hoisted a redundant per-channel×mix
pw-dumpcall in_sync_channel_audio_routing()'s link-verification step to run once per sync pass instead of once per channel/mix combination. - Fixed two test-isolation bugs in
tests/test_fx_chain.pythat depended on the real, mutable~/.config/WaveController/config.jsoninstead of mockingconfig_manager— these were exposed (not caused) by the FX kill-switch fix above. - Updated
WaveController_PipeWire_Node_Reference.txt: added the pre-fader FX chain node/routing section, live-verified the Group Channel contract against a real capture, documented the Discord-reports-as-"Chromium" PipeWire naming quirk, and recorded both bug fixes above. - Full test suite passes (86/86) after every change this session.
WaveController v0.0.3.0 (Alpha 3)
[0.0.3.0] - 2026-09-03 (Alpha 3)
Added
- Sidebar slide animation: collapsing/expanding the sidebar now smoothly animates its width (220ms, ease-out-cubic via
Adw.TimedAnimation) instead of snapping instantly between 68px/225px. Labels hide immediately on collapse and reveal once the expand animation completes, avoiding text clipping mid-transition. wavecontroller/utils/css_helpers.py: sharedinstall_palette_css()helper for installing solid-color CSS classes from a palette, used by both the LED ring color picker and mix accent color picker.wavecontroller/utils/gtk_helpers.py: sharedblocked_handler()context manager for temporarily blocking a GTK signal handler while setting a widget's value programmatically (replaces ~13 duplicatedhandler_block()/try/finally/handler_unblock()blocks acrossdevice_settings.py,mix_header.py, andsettings_view.py).led_color_picker.build_led_color_row(): shared builder for the "label + LED color button" row, used by both the microphone gain LED row (channel_card.py) and headphone LED row (mix_header.py).
Changed
- Background autostart consolidated to systemd user service: the "Start Automatically on Login" toggle is now "Enable Background Service (systemd)" and drives
systemctl --user enable/disable --now wavecontroller.serviceinstead of writing an XDG~/.config/autostartdesktop entry. The systemd unit provides crash auto-restart (Restart=on-failure) and waits for PipeWire/WirePlumber to be ready (After=pipewire.service wireplumber.service), and requires nosudo(user-space unit). Any leftover XDG autostart entry from older versions is automatically cleaned up. - Installer consolidation: removed the stale, divergent
scripts/install.shduplicate. The rootinstall.shis now the single canonical installer;README.md's curl bootstrap command has been updated to point at it.install.sh --autostart/--disable-autostartnow manage the systemd unit to match its documented behavior. - Window geometry saves are now debounced: resizing/maximizing the window no longer writes to disk on every single
notify::default-width/heightevent during a live drag. The final state is still flushed immediately on window close so nothing is lost on quit.
Fixed
- Duplicate channel subtitle text: channels auto-created for a single detected app (e.g. "Google Chrome", "Spotify") no longer show the same name twice (once as the title, once as the subtitle). The subtitle is now hidden when it would just repeat the title, and still shows normally for multi-app group channels.
- Hardware listener leaks:
ChannelCard,UnifiedDeviceSettingsView, andLEDColorButtonnow store theirhardware_mgrlistener callback as a named reference and exposecleanup(), which is called at every real teardown point (channel deletion inmixer_matrix.py, and all 5 device-view teardown paths inwindow.py, now consolidated into one_teardown_device_views()helper). Previously, repeatedly removing/re-adding a hardware device would leave stale listener closures registered forever. NameErrorrisk inchannel_card.py: the hardware listener callback usedGLib.idle_add(...)butGLibwas never imported in the file, which would have raisedNameErrorat runtime whenever the hardware sync callback fired.- Orphaned config
.tmpfiles:ConfigManager.save_now()now cleans up the temporary file if the atomic write fails partway through, instead of leaving it behind. - Unused dead import: removed an unused
LEDColorButtonimport fromdevice_settings.py(it was never instantiated there).
Internal / Maintenance
- Full audit of the codebase for dead code, duplicate logic, and UI/IO performance issues; most flagged concerns (40 FPS tick loop, grid rebuild cost, CSS provider recreation, subprocess polling frequency, signal-handler-in-rebuild-loop) were verified as already correctly implemented and did not require changes.
- All changes verified via the full audio invariant regression suite (73 tests passed, 2 skipped) and a full-file
get_errorssweep after each change.
WaveController 0.0.2.4 prealpha
- System Default Output & Input Management:
• Interactive Default Toggle: Added "Make OS System Default Output / Input" switch in the Mix Edit popover with active
green badge indicators.
• Mutual Exclusivity: Enforced single-default constraints across mixes of the same type (toggling a new default
automatically demotes the previous default).
• WirePlumber Compatibility: Upgraded virtual input mix node class to Audio/Source to support OS-level default input
designation via wpctl set-default.
• Clean Teardown Fallback: When an active default mix is deleted, WaveController automatically falls back and designates
Personal Mix (or Chat Mix) as the active OS system default. - Device Settings & Dynamic UI Anchoring:
• Permanent Top Anchor: Pinned the Primary Default Device / Set as Default Device card at Position 1 on the Device Settings
page.
• In-Place UI Updates: Replaced destructive DOM re-attachment with non-destructive visibility toggling and inner row
updating to prevent the section from dropping to the bottom on runtime refreshes. - Port Sanitization & Group Channel Presentation:
• Numbered Port ID Filtering: Stripped raw PipeWire port numbers (121, 90) and numbered prefixes (121 Shortwave:output_FL →
Shortwave:output_FL) from Grouped Application lists.
• Deduplication & App Mapping: Unified multi-channel Left/Right stream links into single, clean application cards. - VU Metering Isolation & Zero-Bleed Invariants:
• Zero-Fallback Autoconnect Gating: Added -P node.autoconnect=false and -P stream.dont-remix=true to all pw-record meter
processes, preventing WirePlumber from re-linking orphaned meter taps to Discord when YouTube/Chrome stops playing.
• Strict Canonical Token Matching: Filtered container wrappers (chromium, webrtc voiceengine) and replaced fuzzy substring
matching with strict exact-token lookups so quiet channels strictly report 0.0. - Performance & DOM Caching:
• Matrix Cell State Caching: Prevented unnecessary GTK widget and slider recreation during matrix redraws and channel
reordering.
• Group Drawer Sub-Strip Caching: Cached member application lists to eliminate UI churn when expanding or collapsing group
drawers.
WaveController 0.0.2.3 prealpha
Release Notes: v0.0.2.3-prealpha
Unified Fallback Sink & Zero-Bleed Routing
• Unified PipeWire Adapter Sink: Provisioned WaveController_Fallback_Sink as a permanent 1:1 null-sink adapter node
(playback_FL/FR inputs, monitor_FL/FR outputs).
• Permanent Monitor DAC Link: Permanently linked WaveController_Fallback_Sink to your primary monitoring DAC (Elgato Wave XLR
Analog Stereo:playback_FL/FR).
• Automatic Unassigned Stream Reconciliation: Any application stream not assigned to a channel strip (or unassigned/removed
from a group channel) automatically flows into WaveController_Fallback_Sink with zero audio dropouts and zero direct ALSA
hardware leaks.
• Pruning & Cleanup: Automatically cleans up residual background loopbacks on startup, ensuring a clean 1-node topology in
graph visualizers (qpwgraph).
Word-Boundary Process Token Matching
• Eliminated Substring Collisions: Upgraded port_matches_tokens() to use strict word-boundary matching, resolving false
positives where generic tokens (e.g. 'wave') erroneously matched applications like 'Shortwave'.
Default Hardware Devices Preferences
• Dedicated Preferences Group: Added top-level Default Hardware Devices in Settings with Primary Microphone and Primary Monitor
Output dropdowns.
• Tracked-Only Scope: Dropdowns strictly list added/tracked devices in WaveController.
• Dynamic Hotplug & Rescan: Added a manual Refresh Devices button with dynamic auto-refresh on settings tab selection and
hotplug events.
Dynamic Device Removal & Real-Time Target Failover
• Instant Removal Sync: Removing a device from WaveController immediately prunes it from the Settings dropdowns.
• Instant Target Failover: If the removed device was the active default, WaveController automatically fails over to the next
remaining tracked device (Wave XLR), updates Personal Mix target device, and re-wires Fallback Sink and Personal Mix in real-
time.
First-Time Setup (OOBE) Wizard
• Guided Setup Dialog: Created setup_wizard.py for new installations or initial configurations to select primary microphone and
monitor devices and auto-name the primary mic channel after the connected hardware.
Personal Mix Header Refinement
• Protected Monitoring Route: Omitted the Target Output Device dropdown on the Personal Mix edit popup to prevent accidental
routing breaks and guide users to global preferences.