-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat: implement bidirectional microphone pass-through #4078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat: implement bidirectional microphone pass-through #4078
Conversation
This commit adds complete bidirectional microphone support to the Sunshine streaming server, allowing Moonlight clients to send their microphone audio back to the server for output through the host's speakers/headphones. Key Features: - Protocol extensions with new packet types (IDX_MIC_DATA, IDX_MIC_CONFIG) - Dedicated microphone stream on port 12 (MIC_STREAM_PORT) - RTSP protocol integration for microphone capability advertisement - Network infrastructure with micReceiveThread for UDP packet handling - Audio processing pipeline with Opus decoder and audio output - Platform-specific audio output implementations: * Linux: PulseAudio-based mic_output_pa_t * Windows: WASAPI-based mic_output_wasapi_t * macOS: AVFoundation-based av_mic_output_t - Configuration options: enable_mic_passthrough and mic_sink Technical Implementation: - Extended socket handling with socket_e::microphone - Added mic_output_t interface for cross-platform audio output - Integrated with existing audio context and mail system - Thread-safe microphone packet processing - Proper session lifecycle management for microphone threads This implementation solves the long-standing 5-year feature request for microphone pass-through in the Sunshine/Moonlight ecosystem, enabling true bidirectional audio streaming for gaming and communication. Author: [email protected]
|
@cardoza1991 thank you for the PR! There has been a lot of talk about this feature as of late. Would you mind editing the PR body to use our template? You can get the original template from here: https://github.com/LizardByte/.github/blob/master/.github/pull_request_template.md?plain=1 |
|
I think the approach is generally good, but I don't think we need any changes to the control stream. I think we should do all the configuration via RTSP/SDP. The server can advertise mic support via SDP like you're doing here. If the client support mic, then they can send an RTSP PLAY for the mic stream and that will tell Sunshine to expect microphone input. We should also encrypt the microphone packets using AES-GCM like we do with control stream traffic. |
- Update MIC_STREAM_PORT from 12 to 13 as requested by @ReenigneArcher - Add microphone port to UPnP mappings for proper port forwarding - Extend Docker port ranges from 47998-48000 to 47998-48001 - Update EXPOSE directives in all Docker files - Update Network.vue to show correct UDP port range (9-13)
|
My 2 cents regarding the protocol:
|
I believe midstream mic hotplug is a thing that should be supported (at least on the protocol level), and this can be implemented either through Control or Encrypted RTSP. But doing it through Control is probably easier. |
|
@ABeltramo you would probably want to have a look at this too before anything gets finalized. |
|
Thanks for the ping @ns6089 I agree with most of what has been said so far. I think the protocol should be reversed though: a client advertises for a Also, I wouldn't make the mistake of assuming a single global microphone stream. Really excited for this, thanks @cardoza1991 to get the ball rolling! |
|
yeah well I figured I'd tackle a 5 year PR request so here it is. Thnks for the feedback |
|
Data flow can probably be like this:
Communication in Control is kept intentionally unidirectional because it's painful to read async replies from it. Everything doesn't have to be implemented at the same time, for example encryption can be easily delayed. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as resolved.
This comment was marked as resolved.
Implements virtual microphone functionality that allows incoming voice chat from remote clients to be output as a virtual microphone device, enabling lobby-style voice communication where all participants can hear each other. Key features: - Creates virtual microphone device during audio initialization - Routes incoming decoded voice data to both speakers and virtual mic - Linux implementation uses PulseAudio null-sink with monitor source - Windows and macOS implementations stubbed for future development - Applications can select "Sunshine Virtual Microphone" as input device - Enables classic lobby chat experience for gaming and voice applications Technical implementation: - Added virtual microphone interface to audio_control_t - Linux: Uses module-null-sink to create virtual audio device - Automatic cleanup of virtual microphone modules on shutdown - Integrates with existing bidirectional microphone pass-through lol 🤖 Vibe coded with Claude Co-Authored-By: Michael Cardoza, Senior Audio Wizard & Lobby Chat Architect <[email protected]>
|
|
@cardoza1991 question are you still working on this or is this PR stale? |
|
Might be better to merge it in and keep it as experimental until it is perfected? It has been a highly requested feature for 5 years. |
I am asking cause i am considering to take a spin on this if they are no longer working on it |
|
@MNarath1 it appears stale to me. |




Description
This PR implements complete bidirectional microphone support for the Sunshine streaming server, enabling Moonlight clients to send their microphone audio back to the server for output through the host's speakers/headphones.
This addresses the long-standing feature request for microphone pass-through that has been requested by the community for over 5 years, solving a critical gap in the streaming ecosystem.
Key Implementation Details:
IDX_MIC_DATA,IDX_MIC_CONFIG) for microphone data transmissionMIC_STREAM_PORT) for client-to-server audioenable_mic_passthrough,mic_sink)Screenshot
N/A - This is a server-side protocol and audio infrastructure implementation without UI changes.
Issues Fixed or Closed
Type of Change
.github/...)Checklist
Technical Implementation Details
Protocol Extensions
stream.hwithMIC_STREAM_PORT = 12socket_e::microphonefor dedicated mic socket handlingAudio Processing Pipeline
audio::mic_receive()function for processing incoming microphone packetsmic_output_tinterface for platform-specific audio outputPlatform Support
mic_output_pa_tusing PulseAudio for audio outputmic_output_wasapi_tusing WASAPI for low-latency audioav_mic_output_tusing AVFoundation frameworkNetwork Infrastructure
micReceiveThread()for UDP packet reception on port 12Configuration
Add to Sunshine configuration:
Testing
The implementation has been validated for:
Dependencies
No new external dependencies required. Uses existing:
Notes for Reviewers
This is a server-side implementation. Corresponding Moonlight client changes would be needed to complete the bidirectional audio feature. The protocol extensions are designed to be backward-compatible with existing clients.
The implementation follows existing Sunshine patterns for:
config.h/config.cpp)platform/common.h)stream.cpp,rtsp.cpp)audio.h/audio.cpp)Breaking Changes
None. This feature is entirely additive and disabled by default.
Author: [email protected]