語音開發跨了通訊協定和音訊工程兩個領域,術語又多又硬。這篇文件簡要說明常見的網路協定與角色,方便建立共同認知。
# 傳輸層基礎
# TCP(Transmission Control Protocol)
- 可靠傳輸:保證封包順序、不丟失、自動重傳
- 有連線:需三次握手建立連線
- 延遲較高:因為要等確認回覆(ACK)
- 用途:信令(SIP over TCP/TLS)、HTTP API、gRPC、WebSocket
# UDP(User Datagram Protocol)
- 不可靠傳輸:不保證送達、不保證順序、不重傳
- 無連線:直接發送,不需握手
- 延遲極低:適合即時性要求高的場景
- 用途:語音/視訊媒體傳輸(RTP)、SIP 信令(預設 UDP)
為什麼語音用 UDP?
語音通話寧可丟幾個封包(聽起來只是短暫雜訊),也不要等重傳導致延遲(聽起來是卡頓)。人耳對延遲比對丟包更敏感。
# 信令層(控制通話)
# SIP(Session Initiation Protocol)
- 角色:通話的「遙控器」— 負責建立、修改、結束通話
- 不傳音訊:只處理「誰打給誰」「用什麼格式」「掛斷」等控制訊息
- 傳輸:通常 UDP:5060(明文)或 TCP/TLS:5061(加密)
- 類比:就像打電話時的撥號、響鈴、接聽、掛斷動作
來電者 Kamailio (SIP Proxy) FreeSWITCH
│── INVITE ──────────▶ │ │
│ │── INVITE ───────▶ │
│ │◀─ 100 Trying ────│
│◀─ 100 Trying ────────│ │
│ │◀─ 200 OK ────────│
│◀─ 200 OK ────────────│ │
│── ACK ───────────────▶ │── ACK ──────────▶ │
│ │ │
│ ══════ 語音通話中(RTP 直接傳) ══════ │
│ │ │
│── BYE ───────────────▶ │── BYE ──────────▶ │
│◀─ 200 OK ────────────│◀─ 200 OK ──────────│
# SDP(Session Description Protocol)
- 角色:描述媒體格式的「菜單」— 夾在 SIP 訊息裡
- 內容:我支援什麼編碼(PCMU/Opus)、我的 IP 和 port、取樣率等
- 類比:就像兩人約吃飯前先交換「我吃什麼」的清單,取交集
# 媒體層(傳輸音訊)
# RTP(Real-time Transport Protocol)
- 角色:實際搬運語音/視訊資料的「貨車」
- 基於 UDP:低延遲,容忍少量丟包
- 封包內容:時間戳、序號、音訊 payload
- 雙向:通話雙方各開一個 RTP port 互送
- 常見 port 範圍:10000–30000(動態分配)
┌─────────────────────────────────┐
│ RTP 封包結構 │
├────────┬────────┬───────────────┤
│ Header │ 時間戳 │ 音訊 Payload │
│ 12B │ 序號 │ (PCMU/Opus) │
└────────┴────────┴───────────────┘
# RTCP(RTP Control Protocol)
- 角色:RTP 的「品質報告」— 統計丟包率、延遲、抖動
- 用途:監控通話品質,動態調整編碼
# RTPEngine
- 角色:媒體代理(Media Proxy)
- 為什麼需要:解決 NAT 穿越、media fork(複製音訊流給 AI)、轉碼
- 在 FreeSWITCH 架構中:RTPEngine 將通話音訊 fork 一份給 AI Worker
來電者 ──RTP──▶ RTPEngine ──RTP──▶ FreeSWITCH
│
│── RTP fork(複製)
▼
AI Worker(ai-brain 的上游)
接收音訊 → STT → LLM → TTS → 回送音訊
# 音訊編碼(Codec)
| Codec | 取樣率 | 位元率 | 說明 |
|---|---|---|---|
| PCMU (G.711 μ-law) | 8 kHz | 64 kbps | 電話標準,無壓縮,相容性最高 |
| PCMA (G.711 A-law) | 8 kHz | 64 kbps | 歐洲電話標準 |
| G.729 | 8 kHz | 8 kbps | 壓縮編碼,省頻寬,需授權 |
| Opus | 8–48 kHz | 6–510 kbps | 現代全能編碼,WebRTC 預設 |
| PCM 16-bit | 16 kHz | 256 kbps | 原始未壓縮,AI 模型常用輸入格式 |
AI 相關注意:
- STT 輸入通常是 PCMU 8kHz(從 RTP 來)或 PCM 16kHz(轉碼後)
- TTS 輸出支援 PCM 16kHz(高品質)和 PCMU 8kHz(直接回 RTP)
# VAD(Voice Activity Detection)
- 角色:判斷「現在有人在說話嗎?」
- 為什麼需要:不能把整段音訊都丟給 STT,要切出「有語音」的片段
- 常見參數:
threshold:能量門檻(0–1),越高越嚴格min_silence_ms:靜音多久算說完min_speech_ms:最短語音長度(過濾雜音)speech_pad_ms:前後留白(避免切到字頭字尾)
音訊波形: ___/\/\/\/\___________/\/\/\____
VAD 判斷: [speech] [speech]
↑ ↑
送給 STT 送給 STT
# 完整架構:ai-brain 在哪裡?
信令層(SIP/TCP) 媒體層(RTP/UDP)
════════════════ ════════════════
外線 ──SIP──▶ Kamailio ──SIP──▶ FreeSWITCH
│
ESL (TCP)
▼
fs-client ──Redis Pub/Sub──▶ AI Worker
│
RTP 音訊接收
│
┌──────▼──────┐
│ VAD │
└──────┬──────┘
│ 語音片段
gRPC │
▼
┌──────────────┐
│ ai-brain │
│ │
│ STT → LLM │
│ ↓ │
│ TTS │
└──────┬───────┘
│ 音訊回送
▼
AI Worker → RTPEngine → 來電者
ai-brain 只處理 gRPC 層,不碰 SIP/RTP。音訊的收發由上游 AI Worker 負責。
# 常見縮寫速查
| 縮寫 | 全稱 | 一句話 |
|---|---|---|
| SIP | Session Initiation Protocol | 通話控制(撥號/掛斷) |
| SDP | Session Description Protocol | 媒體格式協商 |
| RTP | Real-time Transport Protocol | 即時音訊傳輸 |
| RTCP | RTP Control Protocol | 通話品質監控 |
| UDP | User Datagram Protocol | 快但不可靠的傳輸 |
| TCP | Transmission Control Protocol | 慢但可靠的傳輸 |
| VAD | Voice Activity Detection | 語音活動偵測 |
| ESL | Event Socket Layer | FreeSWITCH 事件介面 |
| NAT | Network Address Translation | 網路位址轉換(私有 IP 問題源頭) |
| PCMU | Pulse Code Modulation μ-law | 電話標準音訊編碼 |
| B2BUA | Back-to-Back User Agent | 雙向 SIP 代理(FreeSWITCH 角色) |