3D Audio Example

TEAMSPEAK. YOUR VOICE. YOUR WAY.

Introduction

This article will guide you through extending your Hello World application with 3D positioning.

Learn how to

  • Initialize the 3D audio engine
  • Position the listener and source
  • Adjust the roll off volume

Let’s code

Initialization

We initialize the 3D audio engine by calling unsigned int ts3client_systemset3DSettings(uint64 connection_id, float distance_factor, float rolloff_scale);. The setting is per connection ID, and we opt to do this once the connection has been established in our main function:

if (wait_for_connection())
    {
        ts3client_systemset3DSettings(connection_id, 1.0f, 1.0f);
    

Setting the listener position

For convenience, we’ll set a fixed listener position using unsigned int ts3client_systemset3DListenerAttributes(uint64 connection_id, const TS3_VECTOR* position, const TS3_VECTOR* forward, const TS3_VECTOR* up);.

We create a function to encapsulate this task:

void set_listener_position(uint64 connection_id)
    {
        TS3_VECTOR position;
        position.x = 0.0f;
        position.y = 1.0f;
        position.z = 0.0f;

        TS3_VECTOR forward;
        forward.x = 0.0f;
        forward.y = 1.0f;
        forward.z = 1.0f;

        TS3_VECTOR up;
        up.x = 0.0f;
        up.y = 1.5f;
        up.z = 0.0f;

        ts3client_systemset3DListenerAttributes(connection_id, &position, &forward, &up);
    }

Setting the source position

For setting the position of others, we’ll use unsigned int ts3client_channelset3DAttributes(uint64 connection_id, anyID client_id, const TS3_VECTOR* position);.

To set a random position when a user starts talking, we’ll need the onTalkStatusChange event. We create a function with the corresponding signature void onTalkStatusChangeEvent(uint64 connection_id, int status, int is_received_whisper, anyID client_id) and add it to our ‘funcs’ struct in the init_ts function: funcs.onTalkStatusChangeEvent = onTalkStatusChangeEvent;.

In the function we check if it is a STATUS_TALKING event and if it is someone else. If so, we get a random position from a helper function we created and set the position:

void onTalkStatusChangeEvent(uint64 connection_id, int status, int is_received_whisper, anyID client_id)
    {
        if (status == STATUS_TALKING)
        {
            anyID my_id;
            if (ts3client_getClientID(connection_id, &my_id) == ERROR_ok)
            {
                if (client_id != my_id)
                {
                    TS3_VECTOR position;
                    get_random_position_on_circle(&position);
                    ts3client_channelset3DAttributes(connection_id, client_id, &position);
                }
            }
        }
    }

Modifying the roll off volume

The client library calculates a physically correct volume attenuation over distance. This is not always desired, especially for voice communication. We may want to set limits to this to enhance the user experience when communicating.

To do this, we handle the onCustom3dRolloffCalculationClientEvent by creating a function with the corresponding signature and adding it to our funcs struct.

In this example, we’ll arbitrarily set the maximum distance for anything to be heard to 100 units, and cap the volume reduction at a factor of 0.5:


        void onCustom3dRolloffCalculationClientEvent(uint64 connection_id, anyID client_id, float distance, float* volume){
            if (distance > 100) *volume = 0.0f;
            else if (*volume < 0.5f) *volume = 0.5f;
        }
    

Congratulations!

You have extended your Hello World application with 3D sound.