Skip to content

feat: mic passthrough via VB-Audio Virtual Cable#1

Closed
xenstalker02 wants to merge 0 commit into
masterfrom
feature/mic-passthrough-vbcable
Closed

feat: mic passthrough via VB-Audio Virtual Cable#1
xenstalker02 wants to merge 0 commit into
masterfrom
feature/mic-passthrough-vbcable

Conversation

@xenstalker02
Copy link
Copy Markdown
Owner

Summary

Adds encrypted client microphone passthrough to the Windows host during a streaming session. Mic audio routes through VB-Audio Virtual Cable — no Steam Remote Play session required, always active.

How it works

  • Vibelight (client) captures mic via SDL, Opus-encodes at 96kbps mono
  • Sends as 0x3003 packets over the existing encrypted control stream (SS_ENC_CONTROL_V2)
  • Vibepollo decodes Opus → writes PCM to CABLE Input via WASAPI (speaker_wasapi_t)
  • Windows routes CABLE InputCABLE Output automatically
  • Session start: switches Windows default capture to CABLE Output so Discord (set to Default) picks up the mic automatically
  • Session end: restores previous default capture device (e.g. AT2040)

No manual Discord configuration needed. Encrypted sessions only — plaintext mic is refused.

Requirements (host)

Client

Pairs with xenstalker02/Vibelight — a Moonlight fork with SDL2 mic capture, Opus encoding, and stereo-to-mono downmix for PipeWire compatibility.

Relation to Logan's PR #1428 on ClassicOldSong/Apollo

Logan's implementation uses a dedicated UDP port negotiated via RTSP with LiSendMicrophoneOpusDataEx (requires a fork of moonlight-common-c) and renders to Steam Streaming Microphone. That approach requires an active Steam Remote Play session to activate the loopback.

This implementation reuses the existing encrypted control stream transport (no moonlight-common-c changes, no new UDP port) and VB-Cable (always-active loopback). Both approaches are valid — this one has fewer dependencies.

Files changed

  • src/stream.cpp — IDX_MIC_AUDIO_DATA handler, per-session Opus decoder, jitter buffer, FEC/PLC, session init/teardown
  • src/platform/windows/audio.cppspeaker_wasapi_t WASAPI render client, virtual_microphone(), VB-Cable device lookup
  • src/config.h / src/config.cppmic_sink, mic_capture_device config options
  • Web UI strings (en.json, Troubleshooting.vue), README

Testing

Validated end-to-end: mic packets received, decoded, written to CABLE Input, audible in Discord on host. Tested on LAN and over Tailscale. Per-session stats (packets, PLC, decode errors, latency) logged every 30s.

@xenstalker02 xenstalker02 force-pushed the feature/mic-passthrough-vbcable branch from e00fdd6 to 4d8bc5d Compare March 23, 2026 01:49
@xenstalker02
Copy link
Copy Markdown
Owner Author

Closing — feature/mic-passthrough-vbcable has been fully absorbed into master via rebase. The PR diff is now empty (feature branch is identical to master). A clean upstream PR has been opened at Nonary/Vibepollo#168 using a properly scoped branch (upstream-pr/mic-passthrough) based on Nonary's upstream/master.

@xenstalker02 xenstalker02 deleted the feature/mic-passthrough-vbcable branch April 2, 2026 04:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant