Using custom devices
| Using playback and capture modes and devices |

### 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, |
| deviceDisplayName, |
| capFrequency, |
| capChannels, |
| playFrequency, |
| playChannels`)`; |

`const char* deviceID`;
`const char* deviceDisplayName`;
`int capFrequency`;
`int capChannels`;
`int playFrequency`;
`int playChannels`;

Parameters

- `deviceID`

  ID string of the custom device, under which the device can be later accessed.

- `deviceDisplayName`

  Displayed name of the custom device. Freely choose a name which identifies your device.

- `capFrequency`

  Frequency of the capture device.

- `capChannels`

  Number of channels of the capture device.

- `playFrequency`

  Frequency of the playback device.

- `playChannels`

  Number of channels of the playback device.

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`;

Parameters

- `deviceID`

  ID string of the custom device to unregister. This is the ID under which the device was registered with `ts3client_registerCustomDevice`.

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, |
| buffer, |
| samples`)`; |

`const char* deviceID`;
`const short* buffer`;
`int samples`;

Parameters

- `deviceID`

  ID string of the custom device. This is the ID under which the device was registered with `ts3client_registerCustomDevice`.

- `buffer`

  Capture data buffer containing the data captured by the custom device.

- `samples`

  Size of the capture data buffer.

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, |
| buffer, |
| samples`)`; |

`const char* deviceID`;
`const short* buffer`;
`int samples`;

Parameters

- `deviceID`

  ID string of the custom device. This is the ID under which the device was registered with `ts3client_registerCustomDevice`.

- `buffer`

  Buffer containing the playback data retrieved from the Client Lib.

- `samples`

  Size of the playback data buffer.

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");
    }

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

Closing devices |  | Activating the capture device