当前位置: 首页 > 工具软件 > wukong-robot > 使用案例 >

wukong-robot 唤醒词检测

赵超
2023-12-01

本文为我的 源代码阅读专栏 第一个工程的代码阅读——wukong-robot 一个优秀的开源智能音箱项目。本文解析的源代码文件为snowboy文件夹中的文件

snowboy介绍

Snowboy是一款基于神经网络的可定制的唤醒词检测引擎。Snowboy本身是用C++完成,通过swig封装,可在多种操作系统和多语言上使用。wukong-robot项目snowboy文件夹中的snowboydetect.py文件就是使用swig封装的python接口。本文主要研究Snowboy在wukong-robot项目中的使用。对Snowboy本身并不做太多研究,对Snowboy有兴趣的同学可以参考Snowboy官方网站github

snowboy文件夹

snowboy文件夹包含以下内容:

  • resources。资源文件夹
  • snowboydetect.py。swig封装的python接口
  • snowboydecoder.py。 对snowboy库进行封装的源码文件

下面主要针对snowboydecoder.py文件进行研究。
snowboydecoder.py 包含全局变量:

  • logger。日志记录
  • TOP_DIR
  • RESOURCE_FILE
  • DETECT_DING。定义声音文件
  • DETECT_DONG。定义声音文件
  • ERROR_HANDLER_FUNC。定义asound库出错后的回调接口
  • c_error_handler。asound库出错后的回调
    函数:
  • py_error_handler。asound库出错后实际执行的函数
  • no_alsa_error。asound库出错回调管理器
  • play_audio_file。播放声音文件
    类:
  • RingBuffer。环形缓冲区。实现多次部分写入,一次全部读出
  • ActiveListener。激活并开始循环热词监测。
  • HotwordDetector。检测麦克风是否有自定义的热词。

ActiveListener

ActiveListener是对snowboy库的封装,以更方便地使用热词唤醒功能

ActiveListener生成对象时,会将热词模型文件列表传入snowboy库。热词模型文件可通过调用snowboy.kitt.ai网络接口生成

ActiveListener对象生成后,就可以通过listen方法进行热词监听了。listen方法主要做了以下几件事情:

  • 打开录音设备,以持续地将录到的声音存储在前面定义的RingBuffer对象中
  • 在设定的循环次数recording_timeout和设定的安静次数silent_count_threshold内循环读取RingBuffer对象中的值,然后调用snowboy库的RunDetection接口进行热词唤醒检测。
  • 检测次数到或检测到热词后退出listen方法
  • 在退出listen方法之前,保存从ActiveListener对象创建到本次记录完成的声音到以时间命名的wav文件中

HotwordDetector

HotwordDetector是对snowboy库的封装。跟ActiveListener相比可设定的参数更多,如输入声音增益,每一个唤醒词的灵敏度等;可在检测到热词后马上调用回调函数,增加反应的实时性;在检测到唤醒词后经过一定延时才进行下一次热词检测

HotwordDetector生成对象时,会将热词模型文件列表、每一个唤醒词的灵敏度传入snowboy库。同时设置snowboy库的输入声音增益

HotwordDetector对象生成后,就可以通过start方法进行热词监听了。start方法主要做了以下几件事情:

  • 打开录音设备,以持续地将录到的声音存储在前面定义的RingBuffer对象中
  • 针对每一个唤醒词注册唤醒后的回调函数
  • 在内部不断的循环中进行热词检测
  • 检测到热词后调用本热词对应的回调函数
  • 检测到热词后在设定的循环次数recording_timeout和设定的安静次数silent_count_threshold达到再开始下一次检测
  • 在开始下一次检测之前,保存本次热词检测记录的声音到以时间命名的wav文件中

HotwordDetector对象还提供了terminate方法来强制停止start方法的循环过程

用到的技术点

  • collections。collections.deque是适合高效插入和删除的双向列表。
  • @contextmanager。上下文管理装饰器。用以管理资源。接受一个generator,用yield语句把with … as var把变量输出出去

参考

考虑到项目源代码可能会被作者更新,致使代码与我的总结文档不一致,下面列表中会提供原始代码链接和冻结代码链接。冻结代码链到我自己fork的工程中,大家如果需要找原始源码,可以点击原始代码链接

 类似资料: