AI Interpretation (TSAIInterpreterInterface)
Simultaneous interpretation creates a long-running ASR → translation → optional TTS pipeline from the device microphone. The contract is one-way; implement two-way conversation by stopping and restarting with swapped languages.
Prerequisites
TSAIContext *context = [TSAIKit sharedInstance].activeContext;
if (![context supportsAIFeatures:TSAIFeatureInterpretation]) {
return;
}
id<TSAIInterpreterInterface> interpreter = context.interpreter;
The device must be connected and microphone permission must be granted.
TSAIInterpreterConfig
| Property | Type | Description |
|---|---|---|
audioRouteConfiguration | TSAIAudioRouteConfiguration * | Complete route for this session; an explicit route overrides legacy playback fields |
sourceLanguage | TSAILanguage | Source language; Auto is supported |
targetLanguage | TSAILanguage | Concrete target language |
enableVoiceOutput | BOOL | Produce translated TTS audio |
autoPlayVoice | BOOL | Let the SDK play translated audio |
preferSpeakerOutput | BOOL | Prefer the phone speaker for SDK playback |
speakerId | NSString * | TTS voice identifier |
defaultConfig enables voice output, automatic playback, and speaker preference. Set both language fields before starting.
Content, events, and report
| Model | Main properties | Description |
|---|---|---|
TSAIInterpreterContent | contentType, utteranceIndex, language | Streaming kind and utterance identity |
TSAIInterpreterContent | text, isTextFinal | Cumulative source or translated text |
TSAIInterpreterContent | audioChunk, audioFormat, isAudioFinal | Delta TTS audio |
TSAIInterpreterEvent | eventType, timestamp, detectedLanguage | VAD, playback, detection, or error event |
TSAIInterpreterUtterance | index, startTime, originalText, translatedText, sourceLanguage, targetLanguage | One stable utterance |
TSAIInterpreterReport | echoed config, startTime, endTime, duration, endReason, rawAudioFilePath, utterances | Persistable session archive |
TSAIInterpreterContentType
| Value | Semantics |
|---|---|
OriginalText | Cumulative ASR source text |
TranslatedText | Cumulative translated text |
AudioChunk | Delta translated TTS audio |
Items with the same utteranceIndex belong to one spoken sentence.
Events, states, and end reasons
TSAIInterpreterEventType | Raw value | Meaning |
|---|---|---|
Unknown | -1 | Unknown event |
SessionStarted | 1 | Session started |
UtteranceStarted / UtteranceEnded | 2 / 3 | Utterance started/ended |
LanguageDetected | 4 | Source language detected |
TranslationPlaybackStarted / TranslationPlaybackEnded | 5 / 6 | Translated playback started/ended |
NetworkError | 7 | Network error |
BleDisconnected | 8 | BLE device disconnected |
| Enum | Values and raw values |
|---|---|
TSAIInterpreterState | Idle = 0, Started = 1, Processing = 2, Ended = 3, Failure = 255 |
TSAIInterpreterEndReason | Unknown = -1, UserStop = 1, Interrupted = 2, Error = 3 |
Add the corresponding enum prefix to shortened values, for example TSAIInterpreterEventTypeSessionStarted.
Start a session
- (NSString *)startInterpretationWithConfig:(TSAIInterpreterConfig *)config
onContent:(nullable TSAIInterpreterContentBlock)onContent
onEvent:(nullable TSAIInterpreterEventBlock)onEvent
completion:(nullable TSAIInterpreterCompletionBlock)completion;
TSAIInterpreterConfig *config = [TSAIInterpreterConfig defaultConfig];
config.sourceLanguage = TSAILanguageChineseSimplified;
config.targetLanguage = TSAILanguageEnglishUS;
config.enableVoiceOutput = YES;
config.autoPlayVoice = YES;
NSString *taskId = [interpreter startInterpretationWithConfig:config
onContent:^(TSAIInterpreterContent *content) {
switch (content.contentType) {
case TSAIInterpreterContentTypeOriginalText:
TSLog(@"Source: %@", content.text);
break;
case TSAIInterpreterContentTypeTranslatedText:
TSLog(@"Translation: %@", content.text);
break;
default:
break;
}
}
onEvent:^(TSAIInterpreterEvent *event) {
TSLog(@"Interpreter event: %ld", (long)event.eventType);
}
completion:^(TSAIInterpreterReport *report, NSError *error) {
if (error) {
TSLog(@"Interpretation failed: %@", error.localizedDescription);
return;
}
TSLog(@"Utterances: %lu", (unsigned long)report.utterances.count);
}];
When autoPlayVoice is YES, the SDK already owns playback; do not play AudioChunk again. When it is NO, the app buffers and plays the delta chunks.
Stop and observe state
- (void)stopInterpretationWithTaskId:(NSString *)taskId;
- (void)registerAIInterpreterStateDidChanged:(nullable TSAIInterpreterStateBlock)stateBlock;
[interpreter registerAIInterpreterStateDidChanged:^(TSAIInterpreterState state) {
TSLog(@"Interpreter state: %ld", (long)state);
}];
[interpreter stopInterpretationWithTaskId:taskId];
Interpretation deliberately exposes graceful stop rather than cancellation. Stop flushes the last buffered utterance and returns the final report. Device PCM playback waits for the DeviceBridge terminal result and fails with a timeout if the bridge never responds. A valid report may accompany a playback-finalization error and remains safe to persist.
Device-initiated voice translation
TSAIDeviceVoiceTranslationConfig *config =
[TSAIDeviceVoiceTranslationConfig defaultConfig];
config.audioRouteConfiguration = [TSAIAudioRouteConfiguration defaultConfiguration];
config.fallbackSourceLanguage = TSAILanguageChineseSimplified;
config.fallbackTargetLanguage = TSAILanguageEnglishUS;
NSString *taskId = [interpreter startDeviceVoiceTranslationWithConfig:config
completion:^(BOOL success, NSError *error) {
if (!success) {
TSLog(@"Failed to arm device translation: %@", error.localizedDescription);
}
}];
// [interpreter stopDeviceVoiceTranslationWithTaskId:taskId];
Fallback languages are used only when device voice packets omit a language. Unknown disables the corresponding fallback.
Important notes
- Languages cannot change during a session; stop and create a new configuration.
- Source may be Auto; target must be concrete.
- The final report contains all stable utterances and can be persisted directly.
- Unregister state callbacks and stop active sessions when leaving the feature.
- Acoustic echo cancellation (AEC) is not guaranteed when the app owns translated-audio playback.