How to implement Push-To-Talk?

Push-To-Talk should be implemented by toggling the client variable CLIENT_INPUT_DEACTIVATED using the function ts3client_setClientSelfVariableAsInt. The variable can be set to the following values (see the enum InputDeactivationStatus in public_definitions.h):



For Push-To-Talk toggle between INPUT_ACTIVE (talking) and INPUT_DEACTIVATED (not talking).

Example code:

unsigned int error;
bool shouldTalk;

shouldTalk = isPushToTalkButtonPressed();  // Your key detection implementation
if((error = ts3client_setClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_DEACTIVATED,
                                                 shouldTalk ? INPUT_ACTIVE : INPUT_DEACTIVATED))
    != ERROR_ok) {
    char* errorMsg;
    if(ts3client_getErrorMessage(error, &errorMsg) != ERROR_ok) {
        printf("Error toggling push-to-talk: %s\n", errorMsg);

if(ts3client_flushClientSelfUpdates(scHandlerID, NULL) != ERROR_ok) {
    char* errorMsg;
    if(ts3client_getErrorMessage(error, &errorMsg) != ERROR_ok) {
        printf("Error flushing after toggling push-to-talk: %s\n", errorMsg);

It is not necessary to close and reopen the capture device to implement Push-To-Talk.

Basically it would be possible to toggle CLIENT_INPUT_MUTED as well, but the advantage of CLIENT_INPUT_DEACTIVATED is that the change is not propagated to the server and other connected clients, thus saving network traffic. CLIENT_INPUT_MUTED should instead be used for manually muting the microphone when using Voice Activity Detection instead of Push-To-Talk.

If you need to query the current muted state, use ts3client_getClientSelfVariableAsInt:

int hardwareStatus, deactivated, muted;

if(ts3client_getClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_HARDWARE,
                                        &hardwareStatus) != ERROR_ok) {
    /* Handle error */
if(ts3client_getClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_DEACTIVATED,
                                        &deactivated) != ERROR_ok) {
    /* Handle error */
if(ts3client_getClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_MUTED,
                                        &muted) != ERROR_ok) {
    /* Handle error */

if(hardwareStatus == HARDWAREINPUT_DISABLED) {
    /* No capture device available */
if(deactivated == INPUT_DEACTIVATED) {
    /* Input was deactivated for Push-To-Talk (not propagated to server) */
if(muted == MUTEINPUT_MUTED) {
    /* Input was muted (propagated to server) */

When using Push-To-Talk, you should deactivate Voice Activity Detection in the preprocessor or keep the VAD level very low. To deactivate VAD, use:

ts3client_setPreProcessorConfigValue(serverConnectionHandlerID, "vad", "false");

How to adjust the volume?

Output volume

The global voice output volume can be adjusted by changing the “volume_modifierplayback option using the function ts3client_setPlaybackConfigValue. The value is in decibel, so 0 is no modification, negative values make the signal quieter and positive values louder.

Example to increase the output volume by 10 decibel:

ts3client_setPlaybackConfigValue(scHandlerID, "volume_modifier", 10);

In addition to modifying the global output volue, the volume of individual clients can be changed with ts3client_setClientVolumeModifier.

Input volume

Automatic Gain Control (AGC) takes care of the input volume during preprocessing automatically. Instead of modifying the input volume directly, you modify the AGC preprocessor settings with setProProcessorConfigValue.

How to talk across channels?

Generally clients can only talk to other clients in the same channel. However, for specific scenarios this can be overruled using whisper lists.. This feature allows specific clients to temporarily talk to other clients or channels outside of their own channel. While whispering, talking to the own channel is disabled.

An example for a scenario where whisper may be useful would be a team consisting of a number of squads. Each squad is assigned to one channel, so squad members can only talk to other members of the same squad. In addition, there is a team leader and squad leaders, who want to communicate accross the squad channels. This can be implemented with whispering, so the team leader could broadcast to all squad leaders, or a squad leader could briefly report to the team leader temporarily sending his voice data to him instead of the squad leaders channel.

This mechanism is powerful and flexible allowing the SDK developer to handle more complex scenarios overruling the standard behaviour where clients can only talk to other clients within the same channel.