Skip to content

interpretation — end-to-end simultaneous interpretation ​

An end-to-end real-time SI engine: it consumes 16 kHz PCM audio frames directly and, inside one long-lived session, emits the source text (interim/final), the translation (interim/final) and optional synthesized speech as it goes.

Plugins taking this route bypass the host's ASR → MT → TTS cascade (typical example: iFlytek real-time interpretation).


Declaration ​

json
{
  "id": "community.cloud.xunfei_si",
  "name": "科大讯飞实时同传",
  "version": "1.0.0",
  "target_app_version": "0.2",
  "type": "interpretation",
  "entrypoint": "xunfei_si.py:XunfeiInterpretationProvider",
  "tags": ["cloud", "streaming", "low-latency"],
  "requires_hf": false,
  "supported_langs": ["en", "zh"],
  "ui_extensions": { "settings_view": "SettingsView.qml" },
  "config_schema": [
    { "key": "appid", "label": "AppID", "type": "string", "default": "" },
    { "key": "api_key", "label": "API Key", "type": "string", "default": "" }
  ]
}

After enabling it, select it as the active SI engine on the settings page; when the user switches into SI mode the host starts streaming.


Base class contract ​

Must implement (abstract methods):

python
def start_session(self, session_id="peer", source_lang="zh", target_lang="en",
                  voice=None, tts_enabled=False) -> bool
    """Open an SI session (establish the long-lived connection and get ready to stream)."""

def feed_audio(self, session_id: str, pcm_chunk: np.ndarray) -> None
    """Feed 16 kHz mono PCM frames (float32 or int16)."""

def stop_session(self, session_id: str = "peer") -> None
    """Send the end frame and close the session gracefully."""

def is_active(self, session_id: str = "peer") -> bool
    """Whether the session is connected and streaming."""

Emitting results upwards (already implemented in the base class, call them directly):

python
self.emit_transcript(text, is_final=False, session_id="peer")        # source text
self.emit_translation(src, dst, is_final=False, session_id="peer")   # translation
self.emit_tts_audio(pcm_bytes, sample_rate=16000, session_id="peer") # synthesized audio
self.emit_status(status, session_id="peer")   # 'idle'|'connecting'|'streaming'|'error'
self.emit_error(message, session_id="peer")

is_final=False goes through the typewriter interim path (the host displays it as it arrives); True means final.

Compatibility aliases: dispatch_transcript / dispatch_translation / dispatch_tts_audio / dispatch_status / dispatch_error are equivalent to emit_*.


Dual-track sessions session_id ​

ValueMeaning
"peer"Upper track: the other party / system sound (inbound SI)
"self"Lower track: my microphone (outbound SI)

The host may open two sessions at the same time. If your underlying protocol does not support multiple sessions, reuse the connection inside a single session, or establish separate connections per session_id.


Voices ​

python
def list_voices(self) -> list[dict]: ...        # SI speaker list

def voice_config_key(self, target_lang: str) -> str
    """Return the speaker config key for the target language: Chinese → 'voice_zh', everything else → 'voice_en'."""

def get_voice_for(self, target_lang: str) -> str
    """Get the speaker id configured for the current language direction (empty string when unconfigured)."""

Speakers are split by language (don't use a Chinese voice on an English translation, it produces weird audio); the config keys are the two shown above.


Notes ​

  • Streaming is a real-time hot path: feed_audio must return fast; do not do blocking IO / heavy computation inside it.
  • stop_session must really close the connection and release threads; the host calls it when SI is stopped, the engine is switched, or the app exits.
  • Report session state truthfully through emit_status; the user interface uses it to show "connecting / interpreting / error".

Reference implementation ​

extensions/community_cloud_xunfei_si/ (includes a custom SettingsView.qml).


TransBox — empowering borderless cross-language communication for everyone