feat: VB-Cable integration for seamless Discord audio routing - #89
Conversation
- Add com-policy-config 0.6 and windows 0.61 dependencies - Create vbcable/ module with detection and default device management - VB-Cable detection via cpal (looks for "CABLE Input") - Windows default device save/restore via COM IPolicyConfig - Register 4 new Tauri commands: check_vb_cable_status, get_vb_cable_device_name, save_default_audio_device, restore_default_audio_device - Update STATE.md and ROADMAP.md for Phase 2 progress
Problem: - Users had to manually download and install VB-Cable - Installation changed Windows default audio devices without restoration - No visual feedback during installation process Solution: - Created installer.rs with download, ZIP extraction, and UAC-elevated launch - Save/restore ALL 4 Windows default audio devices (render/capture x console/communications) - VbCableSettings component with 8-step installation flow and status feedback - Auto-select VB-Cable as broadcast device after installation Backend (Rust): - Added installer.rs with ShellExecuteExW for UAC elevation - Extended default_device.rs with SavedDefaults for all 4 device types - New commands: save_all_default_devices, restore_all_default_devices - Added reqwest (blocking), zip 7.0, open crate dependencies Frontend (React): - Created VbCableSettings.tsx with install button and status display - Added SavedDefaults TypeScript interface - Integrated VbCableSettings in Settings.tsx
- 02-03: Donationware notice (license requirement) + smart retry logic
- 02-04: Microphone routing ("Abhören") for Discord voice + sounds
- 02-05: Disable unused "CABLE In 16 Ch" device
- Add always-visible donationware notice for VB-Audio license compliance - Implement smart retry logic (5 attempts x 1s) for device detection - Replace static 3s delay with wait_for_vb_cable_device command - Early return when device found, faster installation on quick systems
- Add microphone enumeration (excludes VB-Cable devices) - Implement audio routing via cpal background thread with ring buffer - Add Enable/Disable toggle in VbCableSettings UI - Persist microphone routing settings across app restarts - Auto-enable routing on startup if previously enabled - Convert all UI strings to English
Problem: - Ring buffer was sized for 1 second, causing noticeable voice delay - No buffer prefill caused audio glitches at routing start Solution: - Reduce buffer to 100ms (good balance between latency and stability) - Add buffer prefill with silence to prevent startup underruns - Remove unused code (is_vb_cable_installed, restore_default method) Related to #83
Problem: - Auto-disable of CABLE In 16ch device requires admin rights - SetupAPI reports success but device remains enabled - Users have no way to uninstall VB-Cable from within the app Solution: - Removed device_control.rs (feature abandoned due to admin requirements) - Added VB-Cable uninstall button in Settings - Added step-by-step guide for manually disabling CABLE In 16ch - Created issue #88 for future uninstaller integration Backend (Rust): - Added uninstall_vbcable() function using -u -h flags - Added start_vb_cable_uninstall command - Removed device control commands and Windows features Frontend (React): - Added uninstall button with progress feedback - Added help section with manual disable instructions - Opens Windows sound settings for easy access
Problem: - VB-Cable module had only 8 unit tests - Coverage for default_device.rs was at 9.68% Solution: - Added 5 new tests for SavedDefaults and DefaultDeviceManager - Total vbcable tests now: 13
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Problem: - VbCableSettings.tsx had 0% test coverage - codecov/patch check failed due to missing tests Solution: - Added 14 component tests covering: - Render states (installed/not installed) - Install/uninstall buttons - Microphone dropdown and selection - Enable/disable routing functionality - Sound settings link - Donationware notice
- Added disable routing tests (4) - Added install flow tests (3) - Added uninstall flow tests (2) - Added error handling tests (2) - Added website link tests (2) Total: 27 tests (up from 14)
|
Claude finished @dranelixx's task in 2m 12s —— View job Comprehensive Code ReviewI've thoroughly reviewed this VB-Cable integration PR. Overall, this is excellent work - the implementation is well-structured, follows project conventions, and includes good test coverage. Below are my findings organized by severity. 🎯 SummaryStrengths:
Areas for Improvement:
🔴 Critical Issues1. Unsafe Windows API - Missing Error Validation (src-tauri/src/vbcable/installer.rs:165-182)The if !sei.hProcess.is_invalid() {
// Wait for installer
let wait_result = unsafe { WaitForSingleObject(sei.hProcess, INFINITE) };
// ...
} else {
warn!("No process handle returned - installer may have failed to start");
}Problem: If the user cancels the UAC prompt, the function returns Solution: Check the process handle validity and return an error if it's invalid: if sei.hProcess.is_invalid() {
error!("No process handle - installation cancelled or failed");
return Err("Installation cancelled or failed to start".to_string());
}2. Blocking Operations on Main Thread (src-tauri/src/vbcable/installer.rs:188-202, 291-319)Both pub fn install_vbcable() -> Result<(), String> {
let zip_path = download_vbcable()?; // Blocking HTTP download
let installer_path = extract_installer(&zip_path)?;
launch_installer(&installer_path)?; // Blocks until installer completes
// ...
}Problem: This freezes the UI during installation (though the PR description mentions "Windows will show a driver approval dialog", so blocking may be intentional). Recommendation: Document this behavior clearly in the function doc comments, or consider using Tauri's async command pattern if non-blocking is desired.
|
Problem: - launch_installer returned Ok(()) even when user cancelled UAC prompt - This caused incorrect success status in UI Solution: - Return Err() when process handle is invalid (UAC cancelled) - Changed log level from warn to error for this case - Ok() only returned after successful process completion
Ring Buffer: - Add overflow detection with warning log - Add overflow_logged flag to prevent log spam Error Handling: - Return structured RestoreResult instead of generic error - Frontend shows specific failed devices to user - Add RestoreResult/RestoreFailure types Code Quality: - Change warn! to debug! for expected no-op case - Define RPC_E_CHANGED_MODE constant (remove magic number) - Add latency documentation to microphone module - Rename test to clarify intent (test_list_capture_devices_excludes_cable) Tests: - Add RestoreResult serialization tests - Update frontend mock for new RestoreResult type
Code Review ResponseAddressed in this PR
Deferred to separate issues
Intentionally not addressed
|
Summary
Complete VB-Cable integration enabling users to share sounds with Discord friends while still being heard themselves.
Features Implemented
1. VB-Cable Detection
check_vb_cable_statuscommand2. One-Click Installation
-i -hflags3. Windows Default Device Preservation
com-policy-configcrate for Windows IPolicyConfig interface4. Smart Device Detection Retry
5. Microphone Routing
6. VB-Cable Uninstall
-u -hflags7. User Guidance
8. Donationware Notice
Related Issues
Closes #39 (VB-Cable Integration)
Closes #83 (Microphone routing: Reduce latency)
Deferred to Future Work
Technical Details
New Rust Module:
vbcable/detection.rsinstaller.rsdefault_device.rsmicrophone.rsmod.rsNew Tauri Commands
check_vb_cable_status- Detection statusstart_vb_cable_install- Install flowstart_vb_cable_uninstall- Uninstall flowsave_all_default_devices/restore_all_default_devices- Device preservationwait_for_vb_cable_device- Post-install detectionlist_microphones- Available capture devicesenable_microphone_routing/disable_microphone_routing- Routing controlget_microphone_routing_status- Current routing stateopen_sound_settings- Opens mmsys.cplNew Dependencies
com-policy-config 0.6: Windows IPolicyConfig interfacereqwest 0.12: HTTP client (blocking)zip 7.0: ZIP extractionTest Coverage
Test Plan
cargo test