如何在orangepi5上使用sherpa与snowboy结合

分享 2024-06-25

前情提要

我们在上一篇文档中已经成功部署了snowboy并实现了自定义的唤醒词,并且创建了一个自定义的函数,在关键词触发后执行,那么我们可不可以在触发后继续监听麦克风,然后根据说出的关键词,进行更多好玩的操作呢,答案当然是可以,我们可以使用sherpa-ncnn来实现STT并处理

开始实验

1、安装sherpa-ncnn 包

官方已经发布python包,直接安装sherpa-ncnn 的包,就可以使用python调用了

pip install sherpa-ncnn

检查是否安装成功

python3 -c "import sherpa_ncnn; print(sherpa_ncnn.__file__)"
python3 -c "import _sherpa_ncnn; print(_sherpa_ncnn.__file__)"

如果正常输出说明安装没有问题。

2、下载模型

https://k2-fsa.github.io/sherpa/ncnn/pretrained_models/index.html
到上面的地址,去寻找你需要的模型
本文档使用的模型为:sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13

下载好以后上传到服务器,解压后记住路径

与snowboy集成

1、整理项目需要的代码和资源

创建你自己的目录用于整合
mkdir snowboy-test

将之前clone的snowboy项目中的代码移动到自己的目录(我省略了pmdl文件的迁移,请注意)

cp  snowboy/examples/Python3/demo.py snowboy-test
cp  snowboy/swig/Python3/snowboydetect.py snowboy-test
cp  snowboy/swig/Python3/_snowboydetect.so snowboy-test
cp  -ar snowboy/resource  snowboy-test

修改代码

修改demo.py中的代码。(可直接复制后覆盖原demo.py文件后修改)
我将代码改成了唤醒后,监听麦克风三秒,听到“开机”关键字时,回去使用wake on lan 通过网络发送魔术包的方式开启指定mac的电脑
注意点

  • 代码中create_recognizer 函数中的模型路径需要你自己替换成你下载模型的位置
  • action 函数中你可以继续写其他的操作,根据你的喜好
  • while total_sp<3sample_rate 可以控制识别语音的时间 3是3秒,自行修改,长时间的没有测试过
import snowboydecoder
import sys
import signal
import sherpa_ncnn
import sounddevice as sd
from wakeonlan import send_magic_packet

interrupted = False


# 调用sherpa_ncnn
def create_recognizer():
    # Please replace the model files if needed.
    # See https://k2-fsa.github.io/sherpa/ncnn/pretrained_models/index.html
    # for download links.
    recognizer = sherpa_ncnn.Recognizer(
        tokens="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/tokens.txt",
        encoder_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.param",
        encoder_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/encoder_jit_trace-pnnx.ncnn.bin",
        decoder_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.param",
        decoder_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/decoder_jit_trace-pnnx.ncnn.bin",
        joiner_param="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.param",
        joiner_bin="./sherpa-ncnn-streaming-zipformer-bilingual-zh-en-2023-02-13/joiner_jit_trace-pnnx.ncnn.bin",
        num_threads=4,
        hotwords_file="",
        hotwords_score=1.5,
    )
    return recognizer

def action(res):
    if "开机" in res:
      print("字符串包含“开机”。")
      mac="A8-5E-45-54-6A-85"
      send_magic_packet(mac)

def sherpa_callback():
    recognizer = create_recognizer()
    devices = sd.query_devices()
    print(devices)
    default_input_device_idx = sd.default.device[0]
    print(f'Use default device: {devices[default_input_device_idx]["name"]}')
    sample_rate = recognizer.sample_rate
    samples_per_read = int(0.1 * sample_rate)
    last_result = None
    with sd.InputStream(channels=1, dtype="float32", samplerate=sample_rate) as s:
        total_sp=0
        while total_sp<3*sample_rate:
        #while True:
            samples, _ = s.read(samples_per_read)  # a blocking read
            samples = samples.reshape(-1)
            recognizer.accept_waveform(sample_rate, samples)
            result = recognizer.text
            if last_result != result:
                last_result = result
                print("\r{}".format(result), end="", flush=True)
            total_sp+=len(samples)    
    action(result)
    print("Started! Please speak")
    
    
    
def signal_handler(signal, frame):
    global interrupted
    interrupted = True


def interrupt_callback():
    global interrupted
    return interrupted

if len(sys.argv) == 1:
    print("Error: need to specify model name")
    print("Usage: python demo.py your.model")
    sys.exit(-1)
def p():
    print("我在")
    
    
    
if __name__=="__main__":
    #sherpaSetting
 #   recognizer = create_recognizer()

    #snowBoy
    model = sys.argv[1]

    # capture SIGINT signal, e.g., Ctrl+C
    signal.signal(signal.SIGINT, signal_handler)

    detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
    print('Listening... Press Ctrl+C to exit')

    # main loop
    detector.start(detected_callback=sherpa_callback,
                   interrupt_check=interrupt_callback,
                   sleep_time=0.03)
    #detector.terminate()

运行

python demo.py xxx.pmdl

更多

如果你需要了解更多sherpa相关的信息
你可以访问 https://k2-fsa.github.io/sherpa

-


本文由 nobinobita 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

还不快抢沙发

添加新评论