127 lines
3.7 KiB
Markdown
127 lines
3.7 KiB
Markdown
# Audio Processes 改进总结
|
||
|
||
## 问题背景
|
||
- 原始问题:TTS音频只播放3个字符就停止,出现ALSA underrun错误
|
||
- 根本原因:音频缓冲区管理不当,播放策略过于保守
|
||
|
||
## 改进内容
|
||
|
||
### 1. 音频播放优化 (_play_audio 方法)
|
||
- **改进前**:保守的播放策略,需要缓冲区有足够数据才开始播放
|
||
- **改进后**:
|
||
- 借鉴 recorder.py 的播放策略:只要有数据就播放
|
||
- 添加错误恢复机制,自动检测和恢复 ALSA underrun
|
||
- 优化缓冲区管理,减少延迟
|
||
|
||
### 2. TTS 工作线程模式
|
||
- **参考**: recorder.py 的 TTS 工作线程实现
|
||
- **实现功能**:
|
||
- 独立的 TTS 工作线程处理音频生成
|
||
- 任务队列管理,避免阻塞主线程
|
||
- 统一的 TTS 请求接口 `process_tts_request()`
|
||
- 支持流式音频处理
|
||
|
||
### 3. 统一的音频播放队列
|
||
- **InputProcess 和 OutputProcess 都支持**:
|
||
- TTS 工作线程
|
||
- 音频生成和播放队列
|
||
- 统一的错误处理和日志记录
|
||
|
||
### 4. 关键改进点
|
||
|
||
#### 音频播放策略
|
||
```python
|
||
# 改进前:保守策略
|
||
if len(self.playback_buffer) > 2: # 需要缓冲区有足够数据
|
||
# 开始播放
|
||
|
||
# 改进后:积极策略 + 错误恢复
|
||
audio_chunk = self.playback_buffer.pop(0)
|
||
if audio_chunk and len(audio_chunk) > 0:
|
||
try:
|
||
self.output_stream.write(audio_chunk)
|
||
# 统计信息
|
||
except Exception as e:
|
||
# ALSA underrun 错误恢复
|
||
if "underrun" in str(e).lower():
|
||
# 自动恢复音频流
|
||
```
|
||
|
||
#### TTS 工作线程
|
||
```python
|
||
def _tts_worker(self):
|
||
"""TTS工作线程 - 处理TTS任务队列"""
|
||
while self.tts_worker_running:
|
||
try:
|
||
task = self.tts_task_queue.get(timeout=1.0)
|
||
if task is None:
|
||
break
|
||
|
||
task_type, content = task
|
||
if task_type == "tts_sentence":
|
||
self._generate_tts_audio(content)
|
||
|
||
self.tts_task_queue.task_done()
|
||
|
||
except queue.Empty:
|
||
continue
|
||
except Exception as e:
|
||
self.logger.error(f"TTS工作线程错误: {e}")
|
||
```
|
||
|
||
#### 错误恢复机制
|
||
```python
|
||
# ALSA underrun 检测和恢复
|
||
if "underrun" in str(e).lower() or "alsa" in str(e).lower():
|
||
self.logger.info("检测到ALSA underrun,尝试恢复音频流")
|
||
try:
|
||
if self.output_stream:
|
||
self.output_stream.stop_stream()
|
||
time.sleep(0.1)
|
||
self.output_stream.start_stream()
|
||
self.logger.info("音频流已恢复")
|
||
except Exception as recovery_e:
|
||
self.logger.error(f"恢复音频流失败: {recovery_e}")
|
||
self.playback_buffer.clear()
|
||
```
|
||
|
||
### 5. 性能优化
|
||
- 减少日志输出频率,提高性能
|
||
- 优化队列处理策略,使用适当的超时设置
|
||
- 动态调整休眠时间,根据播放状态优化CPU使用
|
||
|
||
### 6. 测试和验证
|
||
- 创建了测试脚本 `test_audio_processes.py`
|
||
- 验证了语法正确性
|
||
- 可以测试 TTS 功能的完整性
|
||
|
||
## 使用方法
|
||
|
||
### 在控制系统中使用
|
||
```python
|
||
from audio_processes import InputProcess, OutputProcess
|
||
|
||
# 创建输入和输出进程
|
||
input_process = InputProcess(command_queue, event_queue)
|
||
output_process = OutputProcess(audio_queue)
|
||
|
||
# 处理TTS请求
|
||
output_process.process_tts_request("你好,这是测试语音")
|
||
```
|
||
|
||
### 独立测试
|
||
```bash
|
||
python test_audio_processes.py
|
||
```
|
||
|
||
## 预期效果
|
||
- 解决 ALSA underrun 错误
|
||
- 提高音频播放的流畅性
|
||
- 减少 TTS 处理的延迟
|
||
- 提供更稳定的音频处理能力
|
||
|
||
## 注意事项
|
||
1. 确保系统安装了必要的依赖:`requests`, `pyaudio`
|
||
2. 检查音频设备是否正常工作
|
||
3. 网络连接正常(用于TTS服务)
|
||
4. 适当调整音频参数以适应不同环境 |