Custom FMOD objects

Using custom FMOD system objects

Instead of using the standard Client Lib functions ts3client_openPlaybackDevice, ts3client_openCaptureDevice and ts3client_activateCaptureDevice it is possible to supply a FMOD::System object of your own that is then used by the TeamSpeak 3 SDK. This allows you to integrate your existing FMOD solution for your application with the FMOD solution used by TeamSpeak 3, or even if you don't use FMOD in your application you can use this functionality if you want more control over the way the FMOD::System objects are used.

By managing the FMOD::System objects yourself and by using the later described onFMODChannelCreatedEvent callback you will be able to use advanced FMOD functionality that the TeamSpeak 3 client SDK does not use and does not expose to be used through the clientlib.h API, for example custom DSP effects or modelling the 3D world.

[Note]Note

Using custom FMOD objects is entirely optional.

The function to open a playback device using a custom FMOD::System object is an alternative to ts3client_openPlaybackDevice:

unsigned int ts3client_openCustomPlaybackDevice(serverConnectionHandlerID,  
 fmodSystem); 
anyID serverConnectionHandlerID;
void* fmodSystem;
 

The function to open a capture device using a custom FMOD::System object is an alternative to ts3client_openCaptureDevice:

unsigned int ts3client_openCustomCaptureDevice(serverConnectionHandlerID,  
 fmodSystem,  
 fmodDriverID); 
anyID serverConnectionHandlerID;
void* fmodSystem;
int fmodDriverID;
 

The function to activate the capture device using a custom FMOD::System object is an alternative to ts3client_activateCaptureDevice:

unsigned int ts3client_activateCustomCaptureDevice(serverConnectionHandlerID,  
 fmodSystem,  
 fmodDriverID); 
anyID serverConnectionHandlerID;
void* fmodSystem;
int fmodDriverID;
 

Parameters

  • serverConnectionHandlerID

    Connection handler of the server on which you want to initialize or activate the device.

  • fmodSystem

    A FMOD::System object created and customized by your code, as shown in the following examples.

    If you use the FMOD C API, you can pass a FMOD_SYSTEM* object instead of FMOD::System*, as the two are interchangable.

  • fmodDriverID

    Enumerated FMOD driver ID, see the FMOD documentation for details.

All functions return ERROR_ok on success, otherwise an error code as defined in public_errors.h.

[Note]Note

The TeamSpeak 3 SDK uses void* pointers to avoid the dependency on FMOD, as custom FMOD objects is an optional feature.


Simple example how to create a FMOD::System object for opening a capture device:

FMOD::System* pFMODSystem = NULL;
FMOD_RESULT result;

result = FMOD::System_Create(&pFMODSystem);
if(result != FMOD_OK) {
    cout << "System_Create: " << FMOD_ErrorString(result) << endl;
    return;
}

result= pFMODSystem->setOutput(static_cast<FMOD_OUTPUTTYPE>(modeID));
if(result != FMOD_OK) {
    cout << "setOutput failed (modeID: " << modeID << "): " << FMOD_ErrorString(result) << endl;
    return;
}

result = pFMODSystem->init(32, FMOD_INIT_NORMAL, NULL);
if(result != FMOD_OK) {
    cout << "init: " << FMOD_ErrorString(result) << endl;
    return;
}

Simple example how to create a FMOD::System object for opening a playback device:

FMOD::System* system = NULL;
FMOD_RESULT result;

result = FMOD::System_Create(&system);
if(result != FMOD_OK) {
    cout << "System_Create: " << FMOD_ErrorString(result) << endl;
    return false;
}

result= system->setOutput(static_cast<FMOD_OUTPUTTYPE>(modeID));
if(result != FMOD_OK) {
    cout << "setOutput failed (modeID: " << modeID << "): " << FMOD_ErrorString(result) << endl;
    return false;
}

result= system->setDriver(driverID);
if(result != FMOD_OK) {
    cout << "setDriver: " << FMOD_ErrorString(result) << endl;
    return false;
}

result = system->init(1000, FMOD_INIT_NORMAL, NULL);
if(result != FMOD_OK) {
    cout << "init: " << FMOD_ErrorString(result) << endl;
    return false;
}

See FMOD Ex Frequently Asked Questions for the recommended way to initialize the output device and the FMOD API documentation for further details.


When the TeamSpeak 3 SDK is using a passed-in FMOD::System object, it will not call close() or release() on the FMOD::System object when finished with it, but rather notify the SDK user via a callback that the SDK has finished using the object. You can either call release() on the FMOD::System object or - if you are still using it in your own application - do nothing.

When closing a capture device, which has been previously opened using ts3client_openCustomCaptureDevice, the following callback allows to clean-up the custom FMOD::System object if desired:

void onCustomCaptureDeviceCloseEvent(serverConnectionHandlerID,  
 fmodSystem); 
anyID serverConnectionHandlerID;
void* fmodSystem;
 

When closing a playback device, which has been previously opened using ts3client_openCustomPlaybackDevice, the following callback allows to clean-up the custom FMOD::System object if desired:

void onCustomPlaybackDeviceCloseEvent(serverConnectionHandlerID,  
 fmodSystem); 
anyID serverConnectionHandlerID;
void* fmodSystem;
 

[Note]Note

Note that you still use the standard ts3client_closePlaybackDevice and ts3client_closeCaptureDevice function to close devices opened using ts3client_openCustomCaptureDevice and ts3client_openCustomPlaybackDevice.

Customizing FMOD channel objects

FMOD channels are created by the Client Lib whenever a user starts talking. By implementing the following callback, additional settings can be applied to the FMOD::Channel object.

[Note]Note

The onFMODChannelCreatedEvent callback is always called, no matter if devices were opened with the standard or custom functions. This allows to apply additional settings to FMOD Channels even if the custom FMOD System objects mechanism is not used.

If you do not need this callback, just set the function pointer to NULL in the ClientUIFunctions parameter for ts3client_initClientLib.

The order of operations when a client starts talking is:

  • FMOD channel is created in a paused state.

  • Client Lib sets standard options on the FMOD::Channel object, like 3D sound settings as set with ts3client_fmod_Channelset3DAttributes.

  • onFMODChannelCreatedEvent is called and allows you to apply additional settings on the FMOD::Channel object, or to even overwrite the default settings that were made in the previous step.

  • The FMOD channel is unpaused and the client starts talking.

void onFMODChannelCreatedEvent(serverConnectionHandlerID,  
 clientID,  
 fmodChannel); 
anyID serverConnectionHandlerID;
anyID clientID;
void* fmodChannel;
 

Parameters

  • serverConnectionHandlerID

    Connection handler of the server on which the FMOD channel is created.

  • clientID

    ID of the client who starts talking.

  • fmodChannel

    A FMOD::Channel object on which additional settings can be applied.

    If you use the FMOD C API, cast the void* fmodChannel object to FMOD_CHANNEL* instead of FMOD::Channel*, as the two are interchangable.

The callback should return quickly to avoid delaying unpausing the FMOD channel.

Querying the current FMOD System objects

The currently used FMOD System playback and capture objects - may it be a standard or custom object - can be queried from the clientlib if you want to use them for own FMOD operations like for example playing wave files.

Request the current playback device with:

unsigned int ts3client_getCurrentPlaybackDevice(serverConnectionHandlerID,  
 fmodSystemResult); 
anyID serverConnectionHandlerID;
void** fmodSystemResult;
 

Request the current capture device with:

unsigned int ts3client_getCurrentCaptureDevice(serverConnectionHandlerID,  
 fmodSystemResult); 
anyID serverConnectionHandlerID;
void** fmodSystemResult;
 

Parameters

  • serverConnectionHandlerID

    ID of the server connection handler on which the FMOD system devices should be queried.

  • serverConnectionHandlerID

    Address of a variable that receives the requested FMOD System object.

Returns ERROR_ok on success, otherwise an error code as defined in public_errors.h. If the function fails, fmodSystemResult is undefined.