文章使用AI助手生成,实在不想敲字了

前言

在日常生活中,我一直在寻找一种更适合自己的信息备忘方式。传统的文字输入对于需要快速记录的场景来说效率偏低,而现有的语音备忘工具往往依赖复杂的触控操作或视觉效果,这对于追求简洁高效的我来说并不理想。

同时,作为一名关注无障碍技术的开发者,我也深知视障人群在处理日常信息时面临的挑战——传统的键盘输入和屏幕交互对他们的负担较重。如果能有一款工具,让用户只需通过简单的物理按键和语音交互,就能完成信息的记录和检索,那将会大大提升使用体验。

带着这样的想法,同时受Redis启发,我开始探索在树莓派5上打造一个完全离线、可语音交互的键值对备忘录系统——「助记宝」。

项目背景与目标

痛点分析

在寻找合适的信息备忘方式过程中,我遇到了以下问题:

  • 效率瓶颈:传统的文字输入速度有限,特别是中英文混合内容
  • 交互负担:触控操作需要视觉注意力,在忙碌或双手不便时尤为不便
  • 隐私顾虑:云端服务存在数据安全风险,本地存储更放心
  • 无障碍需求:视障用户在操作传统应用时面临诸多障碍

设计目标

  1. 语音优先:用语音录制代替文字输入,解放双手和双眼
  2. 极简交互:三个物理按键完成所有操作,无需复杂手势
  3. 离线运行:所有AI模型本地部署,保护隐私,响应快速
  4. 即开即用:配置为开机自启服务,接通电源即可使用
  5. 无障碍友好:全程语音反馈,无需依赖视觉界面

技术架构

硬件配置

按键 GPIO编号 功能
录制键 GPIO 17 长按录制关键词(K)和内容(V)
播放键 GPIO 3 播放已录制笔记
停止键 GPIO 4 停止当前操作

整个系统运行在树莓派5上,利用其GPIO接口连接物理按键,通过USB免驱麦克风录制音频,通过USB免驱音响输出语音反馈。

软件架构

助记宝 (KV Notes)
├── GPIO 控制层 (lgpio)
├── 音频处理层 (recorder.py)
│   ├── 录音功能
│   └── 播放功能
├── AI 模型层
│   ├── ASR 语音识别 (Sherpa-ONNX)
│   └── TTS 语音合成 (VITS)
├── 数据存储层 (SQLite)
└── 业务逻辑层 (状态机)

核心模块

模块 职责
kv_notes.py 主程序,状态机控制
asr_recognizer.py 调用Sherpa-ONNX进行语音识别
tts_synthesizer.py 调用VITS模型进行语音合成
recorder.py 音频录制和播放
database.py SQLite数据库操作
config.py 配置文件

核心功能实现

1. 按键交互流程

用户操作                    系统响应
───────────────────────────────────────
长按录制键 → 录制关键词 → 释放录制键 → 语音识别关键词
    ↓
匹配到已有记录?
    ├── 是 → 语音提示选项:覆盖/播放/退出
    └── 否 → 短按录制键 → 录制内容 → 自动保存

2. 关键词匹配机制

当用户录制关键词后,系统会查找数据库中是否存在相同的关键词记录:

record = self.db.find_by_k_text(self.current_k_text)

if record:
    # 找到已有记录,提示用户选择
    self.speak("找到已有录音,短按录音键覆盖,或按播放键收听,或按停止键退出")
    self.state = self.STATE_MATCH_FOUND
else:
    # 新增记录
    self.speak("请短按录音键录制长录音")
    self.state = self.STATE_WAITING_V

3. 覆盖录音功能

用户选择覆盖已有录音时,系统会更新数据库中的V音频路径:

def stop_record_v(self):
    # ... 录制处理 ...

    if self.overwrite_mode and self.current_record:
        # 覆盖模式:更新现有记录
        record_id = self.current_record[0]
        self.db.update_v_audio(record_id, v_audio_path)
        self.speak("录音已覆盖保存")
    else:
        # 新增模式:插入新记录
        self.save_recording(self.current_k_text, v_audio_path)
        self.speak("录音已保存")

4. 守护服务配置

使用 systemd 实现开机自启:

[Unit]
Description=Speech Recognition Service
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/lvge/sherpa
ExecStart=/bin/bash /home/lvge/sherpa/scripts/start.sh
Restart=on-failure
RestartSec=5
StartLimitBurst=3
StartLimitIntervalSec=30

[Install]
WantedBy=multi-user.target

技术挑战与解决方案

挑战一:RPi.GPIO 与树莓派5兼容性问题

问题描述

RuntimeError: Cannot determine SOC peripheral base address

RPi.GPIO 库在树莓派5上无法正常访问GPIO,而代码优先使用 lgpio 但该库未安装。

解决方案

# 安装 lgpio 编译依赖
sudo apt install swig liblgpio-dev

# 安装 Python 包
pip install lgpio

代码中的导入逻辑:

try:
    import lgpio as GPIO
    USE_LGPIO = True
except ImportError:
    try:
        import RPi.GPIO as GPIO
        USE_LGPIO = False
    except ImportError:
        USE_LGPIO = False
        GPIO = None

挑战二:systemd 服务循环重启

问题描述
服务启动后不断循环重启,无法正常运行。

解决方案

  • 添加详细的日志输出:StandardOutput=journal
  • 修改重启策略:Restart=on-failure(仅异常退出时重启)
  • 添加重启限制:防止频繁重启
Restart=on-failure
RestartSec=5
StartLimitBurst=3
StartLimitIntervalSec=30

挑战三:虚拟环境激活方式

问题描述
使用 source venv/bin/activate 在某些执行环境下无法正常工作。

解决方案
直接使用虚拟环境中的Python解释器绝对路径:

# 修改前
source sherpa_env/bin/activate
python3 kv_notes.py

# 修改后
/home/lvge/sherpa/sherpa_env/bin/python3 /home/lvge/sherpa/src/kv_notes.py

性能与优化

离线模型选择

模型 用途 优势
sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20 语音识别 支持流式识别,中英文双语,离线运行
vits-zh-aishell3 语音合成 音质自然,支持中文

状态机设计

系统采用状态机模式管理复杂的交互逻辑:

STATE_IDLE
    ↓ (长按录制键)
STATE_WAITING_K (等待关键词识别)
    ↓ (识别完成)
STATE_WAITING_V (等待录制内容) ←→ STATE_MATCH_FOUND (找到已有记录)
    ↓ (短按录制键)                 ↓ (用户选择)
STATE_RECORDING_V ←───────────────┘
    ↓ (短按录制键)
STATE_IDLE

使用效果

典型使用场景

场景一:记录新笔记

  1. 长按录制键,说出关键词(如"会议记录")
  2. 系统识别后,提示"请短按录音键录制长录音"
  3. 短按录制键开始录音,录制完成后再次短按录音键或达到最大时限(10分钟)自动保存

场景二:查看已有笔记

  1. 长按录制键,说出关键词
  2. 系统找到已有录音,提示"找到已有录音…"
  3. 短按播放键收听现有录音

场景三:覆盖更新笔记

  1. 长按录制键,说出关键词
  2. 系统找到已有录音,提示"找到已有录音…"
  3. 短按录制键开始录制新内容
  4. 录制完成后自动覆盖原有录音

项目结构

.
├── src/                    # 源代码
│   ├── kv_notes.py         # 主应用程序
│   ├── config.py           # 配置文件
│   ├── database.py         # SQLite数据库模块
│   ├── recorder.py         # 音频录制与播放
│   ├── asr_recognizer.py   # 语音识别模块
│   ├── tts_synthesizer.py  # 语音合成模块
│   └── similarity.py       # 文本相似度计算
├── scripts/                # 脚本
│   ├── start.sh            # 启动脚本
│   └── install.sh          # 安装脚本
├── service/                 # 服务配置
│   └── sherpa.service       # systemd守护服务
├── tests/                   # 测试文件
└── README.md

未来改进方向

  1. 语音命令扩展:支持"下一个"、"上一个"等导航命令
  2. 相似笔记检索:基于语义相似度而非精确匹配
  3. 录音管理:增加删除、导出功能
  4. 多语言支持:扩展支持更多语言,尤其方言,增强ASR鲁棒性
  5. 低功耗模式:增加省电机制

如果你也在寻找更适合自己的信息备忘方式,或者对无障碍技术感兴趣,欢迎交流讨论。

参考资源

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐