Managing Voice Chat
Overview
Section titled “Overview”Voice calls are a core feature of the Discord Social SDK that enable real-time voice communication between players in your game within lobbies.
This guide will show you how to:
- Start and join voice calls in lobbies
- Control voice settings like mute, deafen, and volume
- Process audio data with custom callbacks
- Integrate with external audio systems
- Check voice call status and participant states
Prerequisites
Section titled “Prerequisites”Before you can start a voice call, you must complete these essential steps:
1. Lobby Management
Section titled “1. Lobby Management”Voice calls require an active lobby with participants. You must:
- Create or join a lobby using the Discord Social SDK
- Add players to the lobby - voice calls only work with lobby members
2. Lobby Size Limitations
Section titled “2. Lobby Size Limitations”While Discord lobbies technically support up to 1,000 members, voice calls should be limited to much smaller groups. We strongly recommend keeping voice calls to 25 members or fewer for optimal performance and user experience.
Starting and Joining Voice Calls
Section titled “Starting and Joining Voice Calls”The Discord Social SDK makes it simple to start and join voice calls - both operations use the same functions whether you're creating something new or joining something that already exists.
Creating/Joining a Lobby and Starting/Joining a Call
Section titled “Creating/Joining a Lobby and Starting/Joining a Call”Here's a complete example of joining a lobby and starting a voice call:
// First, create or join a lobby using a shared secret
const std::string lobbySecret = "my-game-lobby-secret";
client->CreateOrJoinLobby(lobbySecret, [client](const discordpp::ClientResult& result, uint64_t lobbyId) {
if (result.Successful()) {
std::cout << "🎮 Successfully joined lobby!" << std::endl;
// Now start or join the voice call in this lobby
// StartCall returns a Call object but has no callback
const auto call = client->StartCall(lobbyId);
// StartCall returns null if user is already in this voice channel
if (call) {
std::cout << "🎤 Voice call operation initiated..." << std::endl;
} else {
std::cout << "ℹ️ Already in this voice channel" << std::endl;
}
} else {
std::cerr << "❌ Failed to join lobby: " << result.Error() << std::endl;
}
});How It Works
Section titled “How It Works”Both Client::CreateOrJoinLobby and Client::StartCall are designed to handle existing and new scenarios automatically:
Client::CreateOrJoinLobby: If a lobby with the given secret already exists, you'll join it. If not, a new lobby is created with that secret.Client::StartCall: If a voice call is already active in the lobby, you'll join it. If not, a new voice call is started.
Controlling Voice Features
Section titled “Controlling Voice Features”The Discord Social SDK provides comprehensive voice control options at both the individual call level and globally across all calls.
Global Voice Controls
Section titled “Global Voice Controls”These methods control voice settings across all active calls using the Client object:
Client::SetSelfMuteAll- Mutes your microphone across all active callsClient::SetSelfDeafAll- Deafens you across all active callsClient::SetInputVolume- Sets microphone volumeClient::SetOutputVolume- Sets speaker volume
Per-Call Voice Controls
Section titled “Per-Call Voice Controls”These methods control voice settings for a specific call using the Call object:
Call::SetSelfMute- Mutes your microphone so other participants in this call cannot hear youCall::SetSelfDeaf- Mutes all audio from this call so you cannot hear other participants, and they cannot hear you eitherCall::SetParticipantVolume- Adjusts the volume of a specific participant
Voice Activity Detection
Section titled “Voice Activity Detection”Use Call::SetVADThreshold to control voice activation detection sensitivity. This allows optional fine-tuning of
when the system considers someone to be speaking.
// Per-call controls (assuming you have a Call object)
uint64_t lobbyId = 123456789; // Your lobby ID
auto call = client->GetCall(lobbyId);
if (call) {
call.SetSelfMute(true); // Mute in this call only
call.SetSelfDeaf(false); // Unmute audio in this call
call.SetParticipantVolume(userId, 150.0f); // Increase participant volume
call.SetVADThreshold(false, -30.0f); // Set custom voice detection threshold
}
// Global controls
client->SetSelfMuteAll(true); // Mute across all calls
client->SetInputVolume(75.0f); // Set microphone to 75%
client->SetOutputVolume(120.0f); // Increase speaker volume to 120%Detecting No Audio Input
Section titled “Detecting No Audio Input”The SDK can notify you when no audio is reaching the microphone — for example, when a user's mic is broken, muted at the OS level, or the wrong input device is selected. This lets your game surface a "your mic appears silent" hint instead of leaving the user to wonder why nobody can hear them.
Client::SetNoAudioInputThreshold— dBFS threshold for what counts as "no input." Range[-100.0, 100.0], defaults to-100.0(detection disabled). Set to something like-60.0to enable.Client::SetNoAudioInputCallback— receives abool inputDetectedwhenever the mic crosses the threshold (silent → active or active → silent).
// Enable detection at -60 dBFS
client->SetNoAudioInputThreshold(-60.0f);
client->SetNoAudioInputCallback([](bool inputDetected) {
if (!inputDetected) {
// Show a UI hint: "Your mic appears silent — check your device settings."
} else {
// Mic is receiving audio again; clear the hint.
}
});Noise Suppression & Cancellation
Section titled “Noise Suppression & Cancellation”The SDK provides two tiers of microphone audio processing: a set of WebRTC-based defaults that are always on, and an optional Krisp-powered noise cancellation for higher-quality results.
Default Audio Processing (WebRTC)
Section titled “Default Audio Processing (WebRTC)”These three processors ship with every build and default to on. They use the WebRTC library's standard audio pipeline:
Client::SetNoiseSuppression— suppresses steady background noise (e.g. fans, keyboards, room tone). Defaults to on.Client::SetEchoCancellation— removes echo from speakers being picked up by the mic. Defaults to on.Client::SetAutomaticGainControl— automatically normalizes microphone volume for clarity and consistency. Defaults to on.
// Toggle individual WebRTC processors from a voice settings UI
client->SetNoiseSuppression(true);
client->SetEchoCancellation(true);
client->SetAutomaticGainControl(true);Advanced Noise Cancellation (Krisp)
Section titled “Advanced Noise Cancellation (Krisp)”Client::SetNoiseCancellation enables Krisp, a noise cancellation technology that removes a much wider range of
background sounds (e.g. typing, dogs barking, traffic) than the WebRTC suppression. It defaults to off.
// Enable Krisp noise cancellation
client->SetNoiseCancellation(true);Excluding Krisp to Reduce Installation Size
Section titled “Excluding Krisp to Reduce Installation Size”Krisp ships as additional libraries and model files alongside the core SDK, which adds to your installation size. If you're optimizing for size — for example on mobile — you can ship without Krisp and rely on the WebRTC noise suppression instead.
To exclude Krisp from your distribution, remove all .kef and .kw files along with any file or directory whose name
contains krisp (for example discord_krisp.dll, libdiscord_krisp.dylib, discord_partner_sdk_krisp.aar, and discord_partner_sdk_krisp.xcframework).
Advanced Audio Processing
Section titled “Advanced Audio Processing”Manipulating Voice Data with Callbacks
Section titled “Manipulating Voice Data with Callbacks”For advanced audio processing needs, use Client::StartCallWithAudioCallbacks to access raw audio data. This
enables real-time audio manipulation and integration with external audio processing systems.
In-Place Audio Modification
Section titled “In-Place Audio Modification”To directly modify incoming audio samples (e.g., volume dampening):
const auto call = client->StartCallWithAudioCallbacks(
lobbyId,
[](uint64_t userId, int16_t *data, const size_t samplesPerChannel,
int sampleRate, const size_t channels,
bool &outShouldMuteData) {
// Dampen volume of incoming audio by modifying data's samples
// in-place
for (int i = 0; i < samplesPerChannel * channels; i++) {
data[i] *= 0.5; // Reduce volume by 50%
}
},
[](int16_t *data, uint64_t samplesPerChannel, int32_t sampleRate,
uint64_t channels) {});
External Audio Pipeline Integration
Section titled “External Audio Pipeline Integration”To route audio to external processing systems such as FMOD or Wwise:
const auto call = client->StartCallWithAudioCallbacks(lobbyId,
[](uint64_t userId, int16_t* data, size_t samplesPerChannel,
int sampleRate, size_t channels, bool& outShouldMuteData) {
// Prevent Discord from playing the audio directly
outShouldMuteData = true;
const int totalNumSamples = samplesPerChannel * channels;
// Send audio data to your external audio system
SendAudioToExternalAudioSystem(data, totalNumSamples);
},
[](int16_t *data, uint64_t samplesPerChannel, int32_t sampleRate,
uint64_t channels) {});Key Audio Processing Points
Section titled “Key Audio Processing Points”- Direct Manipulation: The
dataparameter inClient::UserAudioReceivedCallbackcan be modified in-place to alter incoming audio samples - External Processing: Set
outShouldMuteData = trueto prevent Discord from playing audio directly, allowing you to handle it through your own audio pipeline - No Encoding Required: The SDK handles all voice encoding/decoding automatically - you work with raw audio samples
Ending Voice Calls
Section titled “Ending Voice Calls”When you need to terminate voice calls, you have two options:
End a Call For a Specific Lobby
Section titled “End a Call For a Specific Lobby”uint64_t lobbyId = 123456789; // Your lobby ID
client->EndCall(lobbyId, []() {
std::cout << "🔇 Call ended successfully" << std::endl;
});End All Calls
Section titled “End All Calls”client->EndCalls([]() {
std::cout << "🔇 All calls ended successfully" << std::endl;
});Checking Lobby Voice Call Status
Section titled “Checking Lobby Voice Call Status”You may want to check the voice call status for your lobby to display UI indicators, monitor participant activity, or provide information to players. The Discord Social SDK provides several ways to inspect active voice calls and participant states.
Checking if a Call is Active
Section titled “Checking if a Call is Active”Use LobbyHandle::GetCallInfoHandle() to determine if there's an active voice call in your lobby:
// Check if there's an active call in the lobby
const auto callInfoHandle = lobby->GetCallInfoHandle();
if (callInfoHandle) {
// There's an active call - you can join it or get participant
// info
const auto participants = callInfoHandle->GetParticipants();
std::cout << "Active call with " << participants.size()
<< " participants" << std::endl;
} else {
// No active call in this lobby
std::cout << "No active voice call in this lobby" << std::endl;
}
Checking Individual Participant Status
Section titled “Checking Individual Participant Status”For each participant in a voice call, you can check their voice state using VoiceStateHandle:
// Get voice state information for participants
const auto callInfo = lobby->GetCallInfoHandle();
if (callInfo) {
const auto participants = callInfo->GetParticipants();
for (const auto &participantId : participants) {
const auto voiceState = callInfo->GetVoiceStateHandle(participantId);
if (voiceState) {
const bool isMuted = voiceState->SelfMute();
const bool isDeafened = voiceState->SelfDeaf();
std::cout << "Participant " << participantId
<< " - Muted: " << (isMuted ? "Yes" : "No")
<< ", Deafened: " << (isDeafened ? "Yes" : "No")
<< std::endl;
}
}
}
Voice State Information Available
Section titled “Voice State Information Available”The VoiceStateHandle provides these key details about each participant:
VoiceStateHandle::SelfMute: Returnstrueif the user has muted themselves (others cannot hear them)VoiceStateHandle::SelfDeaf: Returnstrueif the user has deafened themselves (they cannot hear others and others cannot hear them)
This information is particularly useful for:
- Displaying voice indicators in your UI
- Implementing voice-related features or debugging audio issues
Reading Voice Settings from the Discord Client
Section titled “Reading Voice Settings from the Discord Client”The controls above let you set voice state through the SDK — but players often already have voice preferences configured directly in their Discord client (mute/deafen defaults, volumes, voice mode, and a push-to-talk key). Client::GetVoiceSettings lets you read that existing configuration, so your game can seed matching in-game defaults instead of asking players to set everything up twice.
Fetching the Current Settings
Section titled “Fetching the Current Settings”client->GetVoiceSettings([](discordpp::ClientResult result, discordpp::VoiceSettings settings) {
if (!result.Successful()) {
std::cerr << "❌ Failed to fetch voice settings: " << result.Error() << std::endl;
return;
}
std::cout << "Self mute: " << settings.SelfMute() << std::endl;
std::cout << "Self deaf: " << settings.SelfDeaf() << std::endl;
std::cout << "Input volume: " << settings.InputVolume() << std::endl; // 0-100
std::cout << "Output volume: " << settings.OutputVolume() << std::endl; // 0-200
// InputMode() is either VoiceInputModeType::VoiceActivity or
// VoiceInputModeType::PushToTalk
if (settings.InputMode() == discordpp::VoiceInputModeType::PushToTalk) {
// PttKey() is a display string, e.g. "SHIFT + F", empty if unbound
std::cout << "Push-to-talk key: " << settings.PttKey() << std::endl;
}
});Subscribing to Settings Changes
Section titled “Subscribing to Settings Changes”Use Client::SetVoiceSettingsUpdatedCallback to be notified whenever the player changes their voice settings in the Discord client:
client->SetVoiceSettingsUpdatedCallback([](discordpp::VoiceSettings settings) {
std::cout << "🔄 Voice settings updated - self mute: " << settings.SelfMute() << std::endl;
});Diagnosing Audio Issues
Section titled “Diagnosing Audio Issues”If users report echo, feedback, or other audio quality problems, the SDK offers dedicated tooling for capturing voice and audio diagnostics. See the following sections of the Debug & Log guide:
- Voice Logging — capture logs from the voice subsystem and underlying WebRTC layer.
- Audio Logging — record input/output waveforms to disk for offline analysis.
Next Steps
Section titled “Next Steps”Integrate Moderation
Integrating and managing content moderation for your game when using the Discord Social SDK.
Use with Discord APIs
Make requests to Discord's HTTP APIs from your game.
Voice Muting Based on Player Blocks
Mute players in lobby voice calls based on block relationships.
Need help? Join the Discord Developers Server and share questions in the #social-sdk-dev-help channel for support from the community.
If you encounter a bug while working with the Social SDK, please report it here: https://dis.gd/social-sdk-bug-report
Change Log
Section titled “Change Log”| Date | Changes |
|---|---|
| September 1, 2026 | Add section on reading voice settings from the Discord client |
| May 13, 2026 | Add noise suppression, cancellation, and no-audio-input detection |
| June 30, 2025 | Add communications scope warning |
| June 19, 2025 | released guide |
| March 17, 2025 | initial release |