# 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 `ZoomSDKTalkbackController` interface provides core functionality such as creating channels, inviting users, and sending audio. - The `ZoomSDKTalkbackControllerDelegate` 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, use the `ZoomSDKMeetingService` to get the `ZoomSDKTalkbackController`. ```swift guard let talkbackController = ZoomSDK.shared().getMeetingService()?.getTalkbackController() else { return } if talkbackController.isMeetingSupportTalkBack() { // Meeting supports talkback functionality } ``` ```objectivec ZoomSDKTalkbackController *talkbackController = [[[ZoomSDK sharedSDK] getMeetingService] getTalkbackController]; if (talkbackController.isMeetingSupportTalkBack) { // Meeting supports talkback functionality } ``` ## Set event callback If the meeting supports talkback functionality, register the `ZoomSDKTalkbackControllerDelegate` callback to receive talkback events. Create the custom listener class, define what happens when talkback events occur, register the listener, and enable event-driven behavior for talkback functionality. ```swift talkbackController.delegate = self extension ViewController: ZoomSDKTalkbackControllerDelegate { /* These four event notifications are for inviter */ func onCreateChannelResponse(_ channelID: String, error: ZoomSDKTalkbackError) { // Handle channel creation result } func onDestroyChannelResponse(_ channelID: String, error: ZoomSDKTalkbackError) { // Handle channel destruction result } func onChannelUserJoinResponse(_ channelID: String, userID: UInt32, error: ZoomSDKTalkbackError) { // Handle user join result } func onChannelUserLeaveResponse(_ channelID: String, userID: UInt32, error: ZoomSDKTalkbackError) { // Handle user leave result } /* These three event notifications are for the invitee */ func onJoinTalkbackChannel(_ inviterID: UInt32) { // Joined channel notification } func onLeaveTalkbackChannel(_ inviterID: UInt32) { // Left channel notification } func onInviterAudioLevel(_ inviterID: UInt32, audioLevel: UInt32) { // Callback event for inviter audio level, range 0-15 } } ``` ```objectivec // In your .h file @interface ViewController : NSWindowController { } // In your .m file ZoomSDKTalkbackController *talkbackController = [[[ZoomSDK sharedSDK] getMeetingService] getTalkbackController]; talkbackController.delegate = self; /* These four event notifications are for inviter */ - (void)onCreateChannelResponse:(NSString *)channelID error:(ZoomSDKTalkbackError)error { // Handle channel creation result } - (void)onDestroyChannelResponse:(NSString *)channelID error:(ZoomSDKTalkbackError)error { // Handle channel destruction result } - (void)onChannelUserJoinResponse:(NSString *)channelID userID:(unsigned int)userID error:(ZoomSDKTalkbackError)error { // Handle user join result } - (void)onChannelUserLeaveResponse:(NSString *)channelID userID:(unsigned int)userID error:(ZoomSDKTalkbackError)error { // Handle user leave result } /* These three event notifications are for the invitee */ - (void)onJoinTalkbackChannel:(unsigned int)inviterID { // Joined channel notification } - (void)onLeaveTalkbackChannel:(unsigned int)inviterID { // Left channel notification } - (void)onInviterAudioLevel:(unsigned int)inviterID audioLevel:(unsigned int)audioLevel { // Callback event for inviter audio level, range 0-15 } ``` ## 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. ```swift let error = talkbackController.createChannel(2) if error == ZoomSDKError_Success { // Wait for onCreateChannelResponse callback to confirm creation result } ``` ```objectivec ZoomSDKError error = [talkbackController createChannel:2]; if (error == ZoomSDKError_Success) { // Wait for onCreateChannelResponse callback to confirm creation result } ``` ## Batch invite users to the talkback channel To invite multiple users to a talkback channel, wait for the `onChannelUserJoinResponse` callback to confirm each user's join result. Each talkback channel supports up to 10 users. ```swift let inviteError = talkbackController.inviteUsers(toChannel: channelID, userIDList: [12345, 67890]) if inviteError == ZoomSDKError_Success { // Wait for onChannelUserJoinResponse callback to confirm each user's join result } ``` ```objectivec ZoomSDKError inviteError = [talkbackController inviteUsersToChannel:channelID userIDList:@[@12345, @67890]]; if (error == ZoomSDKError_Success) { // 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. ```swift let channelID: String // Channel ID from onCreateChannelResponse let audioData: UnsafeMutablePointer // PCM audio data let dataLength: UInt32 // Data length (must be a multiple of 2) let sampleRate: UInt32 // Sample rate let channel: ZoomSDKAudioChannel = ZoomSDKAudioChannel_Mono // Mono or Stereo talkbackController.sendAudioData(toChannel: channelID, audioData: audioData, dataLength: dataLength, sampleRate: sampleRate, channel: channel) ``` ```objectivec NSString *channelID; // Channel ID from onCreateChannelResponse char *audioData; // PCM audio data UInt32 dataLength; // Data length (must be a multiple of 2) UInt32 sampleRate; // Sample rate ZoomSDKAudioChannel channel = ZoomSDKAudioChannel_Mono; // Mono or Stereo [talkbackController sendAudioDataToChannel:channelID audioData:audioData dataLength:dataLength sampleRate:sampleRate channel: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. ```swift let backgroundVolume:Float = 0.3 talkbackController.setChannelBackgroundVolume("12345", backgroundVolume: backgroundVolume) ``` ```objectivec float backgroundVolume = 0.3f; [talkbackController setChannelBackgroundVolume:@"12345" backgroundVolume: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. You can also retrieve a list of all channel objects with `GetChannelList()`. ```swift // Get channel by ID if let channel = talkbackController.getChannelByID("12345") { // Get user list in channel let userList = channel.userIDList } // Get all channel list let channelList = talkbackController.getChannelList() ``` ```objectivec // Get channel by ID ZoomSDKTalkbackChannel *channel = [talkbackController getChannelByID:@"12345"]; if (channel) { // Get user list in channel NSArray *userList = channel.userIDList; } // Get all channel list NSArray *channelList = [talkbackController 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 be removed under the `userIDList` list. The `onChannelUserLeaveResponse` callback confirms the results of the batch removal. ```swift let error = talkbackController.removeUsers(fromChannel: channelID, userIDList: [12345, 67890]) if error == ZoomSDKError_Success { // Wait for onChannelUserLeaveResponse callback to confirm removal result } ``` ```objectivec ZoomSDKError error = [talkbackController removeUsersFromChannel:channelID userIDList:@[@12345, @67890]]; if (error == ZoomSDKError_Success) { // Wait for onChannelUserLeaveResponse callback to confirm removal result } ``` ## Batch destroy talkback channels To destroy multiple channels, pass the list of channel IDs under the `destroyChannels` method. The `onChannelUserLeaveResponse` callback confirms the results of the batch removal. ```swift let error = talkbackController.destroyChannels([String]) // [ChannelIDs] if error == ZoomSDKError_Success { // Wait for OnDestoryChannelResponse callback to confirm destruction result } ``` ```objectivec ZoomSDKError destroyError = [talkbackController destroyChannels:NSArray]; // Channel IDs if (destroyError == ZoomSDKError_Success) { // 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. ---