# Implement talkback functionality > The code on this page works with either the **default UI** or the **custom UI**. Talkback functionality lets users create independent audio channels in Zoom meetings for private communication between specific users. These audio channels might be used to coordinate simultaneous interpretation between interpreters and hosts; during live production, for directors to communicate with camera operators; for real-time remote guidance between experts and on-site technicians; or internal staff-member coordination during large events. - The `IMeetingTalkbackController` interface provides core functionality such as creating channels, inviting users, and sending audio. - The `IMeetingTalkbackCtrlEvent` interface for receiving result notifications of asynchronous operations. - The `IMeetingTalkbackChannel` interface provides channel ID and user list query functionality. Call SetEvent() to register the callback handlers before using other functionalities. ## See if the meeting supports talkback To check whether the meeting supports talkback functionality, have `GetMeetingTalkbackController()` get a pointer to the `MeetingTalkbackController`. ```cpp IMeetingTalkbackController* pTalkbackCtrl = GetMeetingTalkbackController(); if (pTalkbackCtrl && pTalkbackCtrl->IsMeetingSupportTalkBack()) { // Meeting supports talkback functionality } ``` ## Set event callback If the meeting supports talkback functionality, implement the `IMeetingTalkbackCtrlEvent` interface and register the callback. Create the custom listener class, define what happens when talkback events occur, register the listener, and enable event-driven behavior for talkback functionality. ```cpp class MyTalkbackEventHandler : public IMeetingTalkbackCtrlEvent { public: //The following four event notifications are for inviter void onCreateChannelResponse(const zchar_t* channelID, TalkbackError error) override { // Handle channel creation result } void onDestroyChannelResponse(const zchar_t* channelID, TalkbackError error) override { // Handle channel destruction result } void onChannelUserJoinResponse(const zchar_t* channelID, unsigned int userID, TalkbackError error) override { // Handle user join result } void onChannelUserLeaveResponse(const zchar_t* channelID, unsigned int userID, TalkbackError error) override { // Handle user leave result } //The following three event notifications are for the invitee void onJoinTalkbackChannel(unsigned int inviterID) override { //joined channel notification } void onLeaveTalkbackChannel(unsigned int inviterID) override { //left channel notification } void onInviterAudioLevel(unsigned int inviterID, unsigned int audioLevel) override { //Callback event for inviter audio level, range 0-15 } }; MyTalkbackEventHandler* handler = new MyTalkbackEventHandler(); pTalkbackCtrl->SetEvent(handler); ``` ## Create channels To create channels, call the` CreateChannel` function on the talkback controller. The callback `onCreateChannelResponse` indicates whether the channel is created. Creating channels is an asynchronous operation, supporting up to 16 channels. ```cpp // Create 2 channels SDKError err = pTalkbackCtrl->CreateChannel(2); if (err == SDKErr_Success) { // Wait for onCreateChannelResponse callback to confirm creation result } ``` ## Batch invite users to the talkback channel To invite multiple users to a talkback channel, then wait for the `onChannelUserJoinResponse` callback to confirm each user's join result. Each talkback channel supports up to 10 users. Batch operation flow must follow the **Begin > Add/Remove > Execute** sequence. ```cpp // Begin batch invite pTalkbackCtrl->BeginBatchInviteUsers(channelID); // Add users to invite list pTalkbackCtrl->AddUserToInvite(12345); pTalkbackCtrl->AddUserToInvite(67890); // Execute batch invite pTalkbackCtrl->ExecuteBatchInviteUsers(); // Wait for onChannelUserJoinResponse callback to confirm each user's join result ``` ## Send audio data to the talkback channel To send audio data to the talkback channel, send the audio data, the data length, the sample rate, and whether the data should be mono or stereo. Sending data is usually done on a worker thread. Supports PCM format, 16-bit, mono or stereo, with recommended sample rates of 32kHz or 48kHz or other common sampling rates. ```cpp const char* audioData = ...; // PCM audio data unsigned int dataLength = ...; // Data length (must be a multiple of 2) unsigned int sampleRate = 48000; // Sample rate ZoomSDKAudioChannel channel = ZoomSDKAudioChannel_Mono; // Mono SDKError err = pTalkbackCtrl->SendAudioDataToChannel( channelID, audioData, dataLength, sampleRate, channel ); ``` ## Set the background volume Adjust the main meeting audio volume heard by users in the talkback channel, with a range of 0.0 - 2.0. The background volume is usually lowered to make the private audio chat clearer. ```cpp // Lower background volume to make channel audio clearer float backgroundVolume = 0.3f; pTalkbackCtrl->SetChannelBackgroundVolume(channelID, backgroundVolume); ``` ## Get talkback channel information To get information about a specific talkback channel, look it up via its channel ID. If that channel exists, the controller returns a list of all users in that channel. Retrieve a list of all channel objects with `GetChannelList()`. ```cpp // Get channel by ID IMeetingTalkbackChannel* pChannel = pTalkbackCtrl->GetChannelByID(channelID); if (pChannel) { // Get user list in channel IList* userList = pChannel->GetUserIDList(); } // Get all channel list IList* channelList = pTalkbackCtrl->GetChannelList(); ``` ## Batch remove users from a specific talkback channel To remove multiple users from a channel, first pass the channel ID. Then, add all of the users to remove. The `onChannelUserLeaveResponse` callback confirms the results of the batch removal. Batch operation flow must follow the **Begin > Add/Remove > Execute** sequence. ```cpp // Begin batch remove pTalkbackCtrl->BeginBatchRemoveUsers(channelID); // Add users to remove pTalkbackCtrl->AddUserToRemove(12345); pTalkbackCtrl->AddUserToRemove(67890); // Execute batch remove pTalkbackCtrl->ExecuteBatchRemoveUsers(); // Wait for onChannelUserLeaveResponse callback to confirm removal result ``` ## Batch destroy talkback channels Batch operation flow must follow the **Begin > Add/Remove > Execute** sequence. ```cpp // Begin batch destroy pTalkbackCtrl->BeginBatchDestroyChannels(); // Add channels to destroy pTalkbackCtrl->AddChannelToDestroy(L"channel_001"); pTalkbackCtrl->AddChannelToDestroy(L"channel_002"); // Execute batch destroy pTalkbackCtrl->ExecuteBatchDestroyChannels(); // Wait for OnDestoryChannelResponse callback to confirm destruction result ``` If you destroy a talkback channel when users are still in it, those users will automatically leave the talkback channel. ---