语音识别——使用Vosk进行语音识别

在这里插入图片描述


前言

如何编译Vosk请参照之前的文章,ubuntu编译kaldi和vosk

Vosk是语音识别开源框架,支持二十+种语言 - 中文,英语,印度英语,德语,法语,西班牙语,葡萄牙语,俄语,土耳其语,越南语,意大利语,荷兰人,加泰罗尼亚语,阿拉伯, 希腊语, 波斯语, 菲律宾语,乌克兰语, 哈萨克语, 瑞典语, 日语, 世界语, 印地语, 捷克语, 波兰语, 乌兹别克语, 韩国语, 塔吉克语。

Vosk还支持设备上离线语音识别 ,包括Raspberry Pi,Android,iOS等,API接口简单,并且有多种语言支持,同时会识别语义,最终输出合理的语句。


|版本声明:山河君,未经博主允许,禁止转载

一、Vosk模型

1.准备好所需要的语音包

在开始使用Vosk之前,需要拥有语音识别的模型,如图中拥有很多语音模型,中文、英文、西班牙、印度等等,Vosk模型库,需要外网才可以下载
在这里插入图片描述

2.下载使用

下载并进行解压后如下图所示,例如这里有简单英文、轻量级中文、和用于服务器处理的大型通用中文模型等,根据需要进行下载
在这里插入图片描述

解压后放在对应目录下,值得注意的是,是整个解压后的文件夹,而不是某一固定文件,一定要放在对应位置,不然使用时会直接崩溃,连报错都没有。
在这里插入图片描述

二、使用示例

1.文件读取示例

首先语音文件和模型需要准备好,示例中的语音文件是自己录下来的,模型vosk-model-cn-0.22是中文模型

#include <vosk_api.h>
#include <stdio.h>

int main() {
    FILE *wavin;
    char buf[3200];
    int nread, final;

    VoskModel *model = vosk_model_new("vosk-model-cn-0.22");
    VoskRecognizer *recognizer = vosk_recognizer_new(model, 16000.0);

    wavin = fopen("test.wav", "rb");
    fseek(wavin, 44, SEEK_SET);
    while (!feof(wavin)) {
        nread = fread(buf, 1, sizeof(buf), wavin);
        final = vosk_recognizer_accept_waveform(recognizer, buf, nread);
        if (final) {
            printf("%s\n", vosk_recognizer_result(recognizer));
        } else {
            printf("%s\n", vosk_recognizer_partial_result(recognizer));
        }
    }
    printf("%s\n", vosk_recognizer_final_result(recognizer));

    vosk_recognizer_free(recognizer);
    vosk_model_free(model);
    fclose(wavin);
    return 0;
}

输出结果如下,partial是短时输出,text是识别语义后的输出:
在这里插入图片描述

  • vosk_model_new:加载模型
  • vosk_recognizer_new:创建语音识别实例
  • vosk_recognizer_accept_waveform:塞入语音数据(pcm格式)
  • vosk_recognizer_result:获取识别器的完整识别结果
  • vosk_recognizer_partial_result:返回当下识别结果,如果没有识别到,返回空

2.结合麦克风演示

#include <stdio.h>
#include <stdlib.h>
#include <alsa/asoundlib.h>
#include <vosk_api.h>
#include <iostream>
#include <cstdio>
#include <memory>
#include <array>

#define SAMPLE_RATE 44100
#define BUFFER_SIZE 44100 * 2 * 2



int main() {
    // 初始化 Vosk 模型
    VoskModel *model = vosk_model_new("vosk-model-cn-0.22");
    VoskRecognizer *recognizer = vosk_recognizer_new(model, SAMPLE_RATE);

    // 打开 ALSA 设备
    snd_pcm_t *pcm_handle;
    int ret = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_CAPTURE, 0);
    ret = snd_pcm_set_params(pcm_handle, SND_PCM_FORMAT_S16_LE, SND_PCM_ACCESS_RW_INTERLEAVED, 1, SAMPLE_RATE, 1, 1000000); // 1秒

    char buffer[BUFFER_SIZE];
    int final_result;

    while (1) {
        // 从麦克风读取音频数据
        int nread = snd_pcm_readi(pcm_handle, buffer, BUFFER_SIZE / 2);
        if (nread < 0) {
            snd_pcm_recover(pcm_handle, nread, 0);
            continue;
        }

        // 将音频数据传递给 Vosk
        final_result = vosk_recognizer_accept_waveform(recognizer, buffer, nread * 2);
        if (final_result) {
            printf("%s\n", vosk_recognizer_result(recognizer));
        } else {
            std::string strTest = vosk_recognizer_partial_result(recognizer);
            printf("%s\n", strTest.c_str());
        }
    }

    printf("%s\n", vosk_recognizer_final_result(recognizer));

    // 清理
    snd_pcm_close(pcm_handle);
    vosk_recognizer_free(recognizer);
    vosk_model_free(model);
    return 0;
}

识别到并且最终组成的语句如下:
在这里插入图片描述


总结

轻量级、资源消耗小的嵌入式设备进行语音识别使用Vosk是一个不错的选择,但是如果只是用于语音唤醒之类的,实际上应该有更好的选择。

如果对您有所帮助,请帮忙点个赞吧!

### C++ 和 Vosk 库实现语音识别的方法 Vosk 是一个强大的开源离线语音识别工具包,支持多语言和多种应用场景。结合 C++ 使用时,可以通过调用 Vosk 提供的 API 来实现高效的语音转文字功能[^1]。 以下是使用 C++ 和 Vosk 进行语音识别的具体方法以及示例代码: #### 依赖安装 在开始之前,需要确保已正确安装 Vosk 的 C++ 绑定库及其模型文件。可以从官方仓库获取预编译的二进制文件或自行构建。此外,还需要配置好开发环境以便链接必要的动态库或静态库。 #### 初始化与设置 为了启动语音识别过程,需先加载对应的声学模型,并初始化 `Recognizer` 对象。此对象负责解析输入音频流并生成相应的文本输出。 ```cpp #include <iostream> #include <vosk_api.h> int main() { // 加载指定路径下的声学模型 std::string model_path = "path/to/model"; vosk::Model model(model_path); // 创建 Recognizer 实例,默认采样率为 16kHz vosk::Recognizer recognizer(&model, 16000); return 0; } ``` 上述代码片段展示了如何加载本地存储的语言模型以及创建用于后续操作的核心组件实例。 #### 音频数据处理 接下来要读取待转换成文本形式的音频信号。通常情况下,这些原始 PCM 数据会被分割为固定大小的小块逐一送入到 `AcceptWaveform()` 方法中进行逐帧解码。 ```cpp // 假设我们已经获得一段长度为 N 的 float 类型数组表示的声音样本 float* audio_data; size_t num_samples; if (recognizer.AcceptWaveform(audio_data, num_samples)) { auto result_json = recognizer.Result(); std::cout << "Final Result: " << result_json << "\n"; } else { auto partial_result_json = recognizer.PartialResult(); std::cout << "Partial Result: " << partial_result_json << "\n"; } ``` 这里需要注意的是,在每次调用结束后都会返回 JSON 字符串格式的结果;如果是最终版本,则包含完整的句子结构信息;而中间状态仅给出可能匹配的部分单词列表。 #### 完整示例程序 下面给出了一个更接近实际应用场合的例子——从麦克风实时捕获声音并通过网络传输给服务器端完成整个流程演示: ```cpp #include <iostream> #include <fstream> #include <vector> #include <thread> #include <chrono> #include <vosk_api.h> void record_audio(std::vector<float>& buffer){ /* 此处省略具体录音逻辑 */ } std::string recognize_speech(const std::vector<float>& samples, const vosk::Model& model){ vosk::Recognizer recog(&model, 16000); if(recog.AcceptWaveform(samples.data(),samples.size())){ return recog.FinalResult(); }else{ return recog.PartialResult(); } } int main(){ try{ // Step1: Load acoustic model. std::string model_dir="en-us-model/"; vosk::Model model(model_dir); // Step2: Start recording thread. std::vector<float> recorded_buffer(8000/*sample rate*/ * 3 /*seconds per chunk*/,0.f); std::thread recorder(record_audio,std::ref(recorded_buffer)); while(true){ // Wait until enough data collected... std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Perform recognition on buffered frames. std::string res=recognize_speech(recorded_buffer,model); std::cout<<res<<"\r\n"; // Clear old content before next round starts. memset((void*)recorded_buffer.data(),'\0',sizeof(float)*recorded_buffer.capacity()); } recorder.join(); }catch(...){ std::cerr<<"Error occurred during execution.\n"; } return EXIT_SUCCESS; } ``` 该脚本模拟了一个持续监听外部世界变化并将听到的内容即时反馈出来的简单对话系统原型设计思路。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值