Skip to main content
Documentation - Discord Docs

Search documentation

Type to search this documentation.

On this pageOverview

Managing Voice Chat

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

Before you can start a voice call, you must complete these essential steps:

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

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.


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:

C++
// 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;
    }
});

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.

The Discord Social SDK provides comprehensive voice control options at both the individual call level and globally across all calls.

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

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

Use Call::SetVADThreshold to control voice activation detection sensitivity. This allows optional fine-tuning of when the system considers someone to be speaking.

C++
// 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%

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.0 to enable.
  • Client::SetNoAudioInputCallback — receives a bool inputDetected whenever the mic crosses the threshold (silent → active or active → silent).
C++
// 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.
    }
});

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.

These three processors ship with every build and default to on. They use the WebRTC library's standard audio pipeline:

C++
// Toggle individual WebRTC processors from a voice settings UI
client->SetNoiseSuppression(true);
client->SetEchoCancellation(true);
client->SetAutomaticGainControl(true);

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.

C++
// Enable Krisp noise cancellation
client->SetNoiseCancellation(true);

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).

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.

To directly modify incoming audio samples (e.g., volume dampening):

C++
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) {});

To route audio to external processing systems such as FMOD or Wwise:

C++
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) {});
  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

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

C++
uint64_t lobbyId = 123456789;  // Your lobby ID
client->EndCall(lobbyId, []() {
    std::cout << "🔇 Call ended successfully" << std::endl;
});
C++
client->EndCalls([]() {
    std::cout << "🔇 All calls ended successfully" << std::endl;
});

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.

Use LobbyHandle::GetCallInfoHandle() to determine if there's an active voice call in your lobby:

C++
// 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;
}

For each participant in a voice call, you can check their voice state using VoiceStateHandle:

C++
// 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;
    }
  }
}

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

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.

C++
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;
    }
});

Use Client::SetVoiceSettingsUpdatedCallback to be notified whenever the player changes their voice settings in the Discord client:

C++
client->SetVoiceSettingsUpdatedCallback([](discordpp::VoiceSettings settings) {
    std::cout << "🔄 Voice settings updated - self mute: " << settings.SelfMute() << std::endl;
});

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.

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


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
Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu