跳到主要内容
版本:V2.0.5.x

3.3.核心概念


1. ROS 2 中间件

tkvoice 是一个 ROS 2 项目,使用发布-订阅模式传递数据。

ROS 的类比:

  • 想象多个独立的程序,需要通过"话题(Topic)"进行通信
  • 一个程序"发布"数据,其他程序"订阅"数据
  • 就像报纸一样:报社发行(发布),读者订阅阅读

项目中的 ROS 话题:

话题名数据类型发布者订阅者含义
audio_framesAudioFrametk_audio_publisher内部单个音频帧
audio_sentence_framesAudioFrametk_audio_publishertk_asr_text_publisher整句音频
asr_sentenceStringtk_asr_text_publishertk_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