3.3.核心概念
1. ROS 2 中间件
tkvoice 是一个 ROS 2 项目,使用发布-订阅模式传递数据。
ROS 的类比:
- 想象多个独立的程序,需要通过"话题(Topic)"进行通信
- 一个程序"发布"数据,其他程序"订阅"数据
- 就像报纸一样:报社发行(发布),读者订阅阅读
项目中的 ROS 话题:
| 话题名 | 数据类型 | 发布者 | 订阅者 | 含义 |
|---|---|---|---|---|
audio_frames | AudioFrame | tk_audio_publisher | 内部 | 单个音频帧 |
audio_sentence_frames | AudioFrame | tk_audio_publisher | tk_asr_text_publisher | 整句音频 |
asr_sentence | String | tk_asr_text_publisher | tk_audio_process | 识别文本 |
2. 线程与异步编程
TKVoice 大量使用多线程处理并发任务:
import threading
# 创建一个在后台运行的线程
thread = threading.Thread(target=some_function, daemon=True)
thread.start()
# 线程会与主线程并行执行
为什么需要多线程?
在语音交互中,需要同时做多件事:
- 接收音频数据(I/O 密集)
- 发送数据到 ASR 服务(网络 I/O 密集)
- 处理 LLM 回答(计算密集)
- 播放语音(I/O 密集)
如果只用单线程,会造成阻塞:音频接收时无法处理回答。
3. 队列(Queue)数据结构
from queue import Queue
q = Queue(maxsize=1) # 最多保存1个元素
# 放入数据
q.put(data)
# 取出数据
data = q.get(timeout=2) # 等待2秒,如果没有数据会超时
队列的作用:
- 在线程间安全地传递数据
- 实现生产者-消费者模式
- 自动处理线程同步
4. WebSocket 实时通信
WebSocket 是一种双向实时通信协议:
普通 HTTP (请求-响应): WebSocket (持久连接):
客户端 → 服务器 客户端 ↔ 服务器
↓ ↓
获取响应 → 关闭连接 保持连接,随时收发数据
↓ ↓
重复 流式处理
TKVoice 中的应用:
- 与 Funasr 通信时,使用 WebSocket 发送音频块
- Funasr 边识别边返回结果(流式)
5. 音频处理基础
采样率(Sample Rate): 16000 Hz = 每秒 16000 个样本点 位深(Bit Depth): 16 bit = 每个样本 2 字节 通道(Channels): 1 = 单声道
计算:1 秒音频大小 = 16000 × 2 = 32000 字节 ≈ 31 KB