Skip to main content
This feature is currently available with rate limits. To remove the rate limits for your game, please follow Communication Features: Applying for Rate Limit Removal.

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

Before you can start a voice call, you must complete these essential steps:
To utilize this communication feature, you must enable Client::GetDefaultCommunicationScopes in your OAuth Scope configuration. See the OAuth Scopes Core Concepts Guide for more details.

1. Lobby Management

Voice calls require an active lobby with participants. You must:
  1. Create or join a lobby using the Discord Social SDK
  2. Add players to the lobby - voice calls only work with lobby members
Essential Reading: For detailed instructions on creating lobbies, joining lobbies, and managing lobby members, see the complete Managing Lobbies Guide.

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

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

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

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.
You donโ€™t need to check if a lobby exists or if a call is already ongoing. The SDK handles both scenarios seamlessly, making your code simpler and more reliable.

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

These methods control voice settings across all active calls using the Client object:

Per-Call Voice Controls

These methods control voice settings for a specific call using the Call object:

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% 

Advanced Audio Processing

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

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

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

  1. Direct Manipulation: The data parameter in Client::UserAudioReceivedCallback can be modified in-place to alter incoming audio samples
  2. External Processing: Set outShouldMuteData = true to prevent Discord from playing audio directly, allowing you to handle it through your own audio pipeline
  3. No Encoding Required: The SDK handles all voice encoding/decoding automatically - you work with raw audio samples

Ending Voice Calls

When you need to terminate voice calls, you have two options:

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

client->EndCalls([]() {  std::cout << "๐Ÿ”‡ All calls ended successfully" << std::endl; }); 

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

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

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

The VoiceStateHandle provides these key details about each participant: This information is particularly useful for:
  • Displaying voice indicators in your UI
  • Implementing voice-related features or debugging audio issues

Next Steps

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

DateChanges
June 30, 2025Add communications scope warning
June 19, 2025released guide
March 17, 2025initial release