Accessing the voice buffer

## Accessing the voice buffer

The TeamSpeak Client Lib allows users to access the raw playback and capture voice data and even modify it, for example to add effects to the voice. These callbacks are also used by the TeamSpeak client for the voice recording feature.

Using these low-level callbacks is not required and should be reserved for specific needs. Most SDK applications won't need to implement these callbacks.

The following event is called when a voice packet from a client (not own client) is decoded and about to be played over your sound device, but before it is 3D positioned and mixed with other sounds. You can use this function to alter the voice data (for example when you want to do effects on it) or to simply get voice data. The TeamSpeak client uses this function to record sessions.

`void onEditPlaybackVoiceDataEvent(` | serverConnectionHandlerID, |
| clientID, |
| samples, |
| sampleCount, |
| channels`)`; |

`uint64 serverConnectionHandlerID`;
`anyID clientID`;
`short* samples`;
`int sampleCount`;
`int channels`;

Parameters

- `serverConnectionHandlerID`

  ID of the server connection handler from which the voice data was sent.

- `clientID`

  ID of the client whose voice data is received.

- `samples`

  Pointer to the voice data (signed 16 bit @ 48KHz).

- `sampleCount`

  Number of samples the "samples" variable points to.

- `channels`

  Number of channels in the sound data.

The following event is called when a voice packet from a client (not own client) is decoded and 3D positioned and about to be played over your sound device, but before it is mixed with other sounds. You can use this function to alter/get the voice data after 3D positioning.

`void onEditPostProcessVoiceDataEvent(` | serverConnectionHandlerID, |
| clientID, |
| samples, |
| sampleCount, |
| channels, |
| channelSpeakerArray, |
| channelFillMask`)`; |

`uint64 serverConnectionHandlerID`;
`anyID clientID`;
`short* samples`;
`int sampleCount`;
`int channels`;
`const unsigned int* channelSpeakerArray`;
`unsigned int* channelFillMask`;

Parameters

- `serverConnectionHandlerID`

  ID of the server connection handler from which the voice data was sent.

- `clientID`

  ID of the client whose voice data is received.

- `samples`

  Pointer to the voice data (signed 16 bit @ 48KHz).

- `sampleCount`

  Number of samples the "samples" variable points to.

- `channels`

  Number of channels in the sound data.

- `channelSpeakerArray`

  An array with `channels` entries, defining the speaker each channels represents. The speaker values can be found in the SPEAKER_* defines within `public_definitions.h`.

  For example for stereo (`channels` = 2), the array might look liks this:

      channelSpeakerArray[0] = SPEAKER_FRONT_LEFT
      channelSpeakerArray[1] = SPEAKER_FRONT_RIGHT

- `channelFillMask`

  A pointer to a bit-mask defining which channels are filled. For efficiency reasons, not all channels need to have actual sound data in it. So before this data is used, use this bit-mask to check if the channel is actually filled. If you decide to add data to a channel that is empty, set the bit for this channel in this mask.

For example, this callback reports:

channels = 6
channelSpeakerArray[0] = SPEAKER_FRONT_CENTER
channelSpeakerArray[1] = SPEAKER_LOW_FREQUENCY
channelSpeakerArray[2] = SPEAKER_BACK_LEFT
channelSpeakerArray[3] = SPEAKER_BACK_RIGHT
channelSpeakerArray[4] = SPEAKER_SIDE_LEFT
channelSpeakerArray[5] = SPEAKER_SIDE_RIGHT // Quite unusual setup
*channelFillMask = 1

This means "samples" points to 6 channel data, but only the SPEAKER_FRONT_CENTER channel has data, the other channels are undefined (not necessarily 0, but undefined).

So for the first sample, samples[0] has data and samples[1], samples[2], samples[3], samples[4] and samples[5] are undefined.

If you want to add SPEAKER_BACK_RIGHT channel data you would do something like:

    *channelFillMask |= 1<<3;  // SPEAKER_BACK_RIGHT is the 4th channel (is index 3) according to *channelSpeakerArray.
    for(int i=0; i<sampleCount; ++i){
        samples[3 + (i*channels) ] = getChannelSoundData(SPEAKER_BACK_RIGHT, i);
    }

The following event is called when all sounds that are about to be played back for this server connection are mixed. This is the last chance to alter/get sound.

You can use this function to alter/get the sound data before playback.

`void onEditMixedPlaybackVoiceDataEvent(` | serverConnectionHandlerID, |
| samples, |
| sampleCount, |
| channels, |
| channelSpeakerArray, |
| channelFillMask`)`; |

`uint64 serverConnectionHandlerID`;
`short* samples`;
`int sampleCount`;
`int channels`;
`const unsigned int* channelSpeakerArray`;
`unsigned int* channelFillMask`;

Parameters

- `serverConnectionHandlerID`

  ID of the server connection handler from which the voice data was sent.

- `samples`

  Pointer to the voice data (signed 16 bit @ 48KHz).

- `sampleCount`

  Number of samples the "samples" variable points to.

- `channels`

  Number of channels in the sound data.

- `channelSpeakerArray`

  An array with `channels` entries, defining the speaker each channels represents. The speaker values can be found in the SPEAKER_* defines within `public_definitions.h`.

  For example for stereo (`channels` = 2), the array might look liks this:

      channelSpeakerArray[0] = SPEAKER_FRONT_LEFT
      channelSpeakerArray[1] = SPEAKER_FRONT_RIGHT

- `channelFillMask`

  A pointer to a bit-mask of which channels are filled. For efficiency reasons, not all channels need to have actual sound data in it. So before this data is used, use this bit-mask to check if the channel is actually filled. If you decide to add data to a channel that is empty, set the bit for this channel in this mask.

The following event is called after sound is recorded from the sound device and is preprocessed. This event can be used to get/alter recorded sound. Also it can be determined if this sound will be send, or muted. This is used by the TeamSpeak client to record sessions.

If the sound data will be send, (*edited | 2) is true. If the sound data is changed, set bit 1 (*edited |=1). If the sound should not be send, clear bit 2. (*edited &= ~2)

`void onEditCapturedVoiceDataEvent(` | serverConnectionHandlerID, |
| samples, |
| sampleCount, |
| channels, |
| edited`)`; |

`uint64 serverConnectionHandlerID`;
`short* samples`;
`int sampleCount`;
`int channels`;
`int* edited`;

Parameters

- `serverConnectionHandlerID`

  ID of the server connection handler from which the voice data was sent.

- `samples`

  Pointer to the voice data (signed 16 bit @ 48KHz).

- `sampleCount`

  Number of samples the "samples" variable points to.

- `channels`

  Number of channels in the sound data.

- `edited`

  When called, bit 2 indicates if the sound is about to be sent to the server.

  On return, set bit 1 if the sound data was changed.

### Voice recording

When using the above callbacks to record voice, you should notify the server when recording starts or stops with the following functions:

`unsigned int ts3client_startVoiceRecording(` | serverConnectionHandlerID`)`; |

`uint64 serverConnectionHandlerID`;

`unsigned int ts3client_stopVoiceRecording(` | serverConnectionHandlerID`)`; |

`uint64 serverConnectionHandlerID`;

Parameters

- `serverConnectionHandlerID`

  ID of the server connection handler on which voice recording should be started or stopped.

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

Playback options |  | Playing wave files