Using custom devices

Instead of opening existing sound devices that TeamSpeak has detected, you can also use our custom capture and playback mechanism to allow you to override the way in which TeamSpeak does capture and playback. When you have opened a custom capture and playback device you must regularly supply new "captured" sound data via the ts3client_processCustomCaptureData function and retrieve data that should be "played back" via ts3client_acquireCustomPlaybackData. Where exactly this captured sound data comes from and where the playback data goes to is up to you, which allows a lot of cool things to be done with this mechanism.

Implementing own custom devices is for special use cases and entirely optional.

Registering a custom device announces the device ID and name to the Client Lib. Once a custom device has been registered under a device ID, the device can be opened like any standard device with ts3client_openCaptureDevice and ts3client_openPlaybackDevice.

void ts3client_registerCustomDevice(deviceID,  
const char* deviceID;
const char* deviceDisplayName;
int capFrequency;
int capChannels;
int playFrequency;
int playChannels;

Returns ERROR_ok on success, otherwise an error code as defined in public_errors.h.

Unregistering a custom device will automatically close the device:

void ts3client_unregisterCustomDevice(deviceID); 
const char* deviceID;

Returns ERROR_ok on success, otherwise an error code as defined in public_errors.h.

To send the captured data from your device to the Client Lib:

void ts3client_processCustomCaptureData(deviceID,  
const char* deviceID;
const short* buffer;
int samples;

Returns ERROR_ok on success, otherwise an error code as defined in public_errors.h.

Retrieve playback data from the Client Lib:

void ts3client_acquireCustomPlaybackData(deviceID,  
const char* deviceID;
const short* buffer;
int samples;

Returns ERROR_ok if playback data is available or ERROR_sound_no_data if the Client Lib currently has no playback data.

The return value ERROR_sound_no_data can be used for performance optimisation, it means there is currently only silence (nobody is talking, no wave files being played etc.) and instead of returning a buffer full of zeroes it just notifies the user there is currently no data, which allows you to not playback any sound data for that moment, if your API supports that (potentially saving some CPU), or to just fill the sound buffer with zeroes and playback this if your sound API demands you to fill it with something for every given time.

Overview on registering and opening a custom device:

/* Register a new custom sound device with specified frequency and number of channels */
if(ts3client_registerCustomDevice("customWaveDeviceId", "Nice displayable wave device name", captureFrequency, captureChannels, playbackFrequncy, playbackChannels) != ERROR_ok) {
    printf("Failed to register custom device\n");

/* Open capture device we created earlier */
if(ts3client_openCaptureDevice(scHandlerID, "custom", "customWaveDeviceId") != ERROR_ok) {
    printf("Error opening capture device\n");

/* Open playback device we created earlier */
if(ts3client_openPlaybackDevice(scHandlerID, "custom", "customWaveDeviceId") != ERROR_ok) {
    printf("Error opening playback device\n");

/* Main loop */
while(!abort) {
    /* Fill captureBuffer from your custom device */

    /* Stream your capture data to the client lib */
	if(ts3client_processCustomCaptureData("customWaveDeviceId", captureBuffer, captureBufferSize) != ERROR_ok) {
        printf("Failed to process capture data\n");

    /* Get playback data from the client lib */
    error = ts3client_acquireCustomPlaybackData("customWaveDeviceId", playbackBuffer, playbackBufferSize);
    if(error == ERROR_ok) {
        /* Playback data available, send playbackBuffer to your custom device */
    } else if(error == ERROR_sound_no_data) {
        /* Not an error. The client lib has no playback data available. Depending on your custom sound API, either
           pause playback for performance optimisation or send a buffer of zeros. */
    } else {
        printf("Failed to get playback data\n");  /* Error occured */

/* Unregister the custom device. This automatically close the device. */
if(ts3client_unregisterCustomDevice("customaveDeviceId") != ERROR_ok) {
    printf("Failed to unregister custom device\n");

Further sample code on how to use a custom device can be found in the “client_customdevice” example included in the SDK.