ubuntu下使用pocketsphinx进行语音识别

文章目录

  • 前言
  • 一、pocketsphinx的介绍
  • 二、ubuntu下编译
  • 三、使用示例
    • 1.模型选择
    • 2.代码示例
    • 3.自定义字典
  • 四、交叉编译
  • 总结


前言

由于工作需要语音识别的功能,环境是在linux arm版上,所以想先在ubuntu上跑起来看一看,就找了一下语音识别的开源框架,选中了很多框架可以看编译vosk那篇文章,现在一一试验一下。

网上对于pocketsphinx的介绍都比较老了,本篇博客将会在ubuntu上进行pocketsphinx编译使用,并且进行交叉编译。

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


一、pocketsphinx的介绍

PocketSphinx是一款卡内基梅隆大学的开源大型词汇、独立于说话人的连续语音识别引擎。

对于接下来的编译使用,你需要知道:

  1. 它是一个离线语音识别系统
  2. 不再依赖SphinxBase ,所以对于网上文章出现调用cmd_ln_init这种接口的都是比较老的文章,某一天可能这篇博客也会变老
  3. pocketsphinx当前只有社区维护了,如果对于开源项目更新速度有要求的,不建议再使用它了。
  4. 有几个关键网址需要知道: pocketsphinx源码下载地址,通用模型下载地址,自定义模型库工具地址
  5. pocketsphinx支持自定义词典,针对关键词进行识别
  6. pocketsphinx依赖的模型库非常重要的文件:HMM:描述音频信号的模型,基于音素的发音特征;
  7. pocketsphinx依赖的模型库非常重要的文件: Dict:将单词映射到其音素发音的字典文件
  8. pocketsphinx依赖的模型库非常重要的文件: LM:描述单词序列概率的语言模型,帮助识别上下文关系

二、ubuntu下编译

sudo apt-get install build-essential cmake bison flex libpulse-dev python3-dev
git clone https://github.com/cmusphinx/pocketsphinx.git
cd pocketsphinx
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install
make
make install

在安装路径下出现表示成功
在这里插入图片描述

  • bin:示例程序
  • build:中间文件,不用管
  • include:头文件
  • lib:静态库
  • share:里面包含一个英文的通用模型

三、使用示例

1.模型选择

可以选择使用自带的也就是上文中share文件夹包含的通用模型
在这里插入图片描述

如果想使用中文模型需要在通用模型下载地址下载,选择中文模型
在这里插入图片描述
模型解压后
在这里插入图片描述

2.代码示例

代码如下,我使用了麦克风的声音,所以会用到sox插件,这个读者可以自行更改:


#include <pocketsphinx.h>
#include <signal.h>

static int global_done = 0;
static void
catch_sig(int signum)
{
    (void)signum;
    global_done = 1;
}

#ifdef WIN32
#define popen _popen
#define pclose _pclose
#endif

static FILE *
popen_sox(int sample_rate)
{
    char *soxcmd;
    int len;
    FILE *sox;
#define SOXCMD "sox -q -r %d -c 1 -b 16 -e signed-integer -d -t raw -"
    len = snprintf(NULL, 0, SOXCMD, sample_rate);
    if ((soxcmd = (char*)malloc(len + 1)) == NULL)
        E_FATAL_SYSTEM("Failed to allocate string");
    if (snprintf(soxcmd, len + 1, SOXCMD, sample_rate) != len)
        E_FATAL_SYSTEM("snprintf() failed");
    if ((sox = popen(soxcmd, "r")) == NULL)
        E_FATAL_SYSTEM("Failed to popen(%s)", soxcmd);
    free(soxcmd);

    return sox;
}

int
main(int argc, char *argv[])
{
    ps_decoder_t *decoder;
    ps_config_t *config;
    ps_endpointer_t *ep;
    FILE *sox;
    short *frame;
    size_t frame_size;

    (void)argc; (void)argv;
    config = ps_config_init(NULL);
    ps_default_search_args(config);

    //en
    // ps_config_set_str(config, "dict", "/home/aaron/workplace/audioread/pocketsphinx/build/share/pocketsphinx/model/en-us/cmudict-en-us.dict");
    // ps_config_set_str(config, "lm", "/home/aaron/workplace/audioread/pocketsphinx/build/share/pocketsphinx/model/en-us/en-us.lm.bin");


    //china
    ps_config_set_str(config, "hmm", "/home/aaron/workplace/audioread/ceshi/pocketsphinx/pocketsphinxtest/third/cmusphinx/zh_cn.cd_cont_5000");
    ps_config_set_str(config, "dict", "/home/aaron/workplace/audioread/ceshi/pocketsphinx/pocketsphinxtest/third/cmusphinx/zh_cn.dic");
    ps_config_set_str(config, "lm", "/home/aaron/workplace/audioread/ceshi/pocketsphinx/pocketsphinxtest/third/cmusphinx/zh_cn.lm.bin");

    if ((decoder = ps_init(config)) == NULL)
        E_FATAL("PocketSphinx decoder init failed\n");

    if ((ep = ps_endpointer_init(0, 0.0, (ps_vad_mode_t)0, 0, 0)) == NULL)
        E_FATAL("PocketSphinx endpointer init failed\n");
    sox = popen_sox(ps_endpointer_sample_rate(ep));
    frame_size = ps_endpointer_frame_size(ep);
    if ((frame = (short int *)malloc(frame_size * sizeof(frame[0]))) == NULL)
        E_FATAL_SYSTEM("Failed to allocate frame");
    if (signal(SIGINT, catch_sig) == SIG_ERR)
        E_FATAL_SYSTEM("Failed to set SIGINT handler");
    while (!global_done) {
        const int16 *speech;
        int prev_in_speech = ps_endpointer_in_speech(ep);
        size_t len, end_samples;
        if ((len = fread(frame, sizeof(frame[0]),
                         frame_size, sox)) != frame_size) {
            if (len > 0) {
                speech = ps_endpointer_end_stream(ep, frame,
                                                  frame_size,
                                                  &end_samples);
            }
            else
                break;
        } else {
            speech = ps_endpointer_process(ep, frame);
        }
        if (speech != NULL) {
            const char *hyp;
            if (!prev_in_speech) {
                fprintf(stderr, "Speech start at %.2f\n",
                        ps_endpointer_speech_start(ep));
                ps_start_utt(decoder);
            }
            if (ps_process_raw(decoder, speech, frame_size, FALSE, FALSE) < 0)
                E_FATAL("ps_process_raw() failed\n");
            if ((hyp = ps_get_hyp(decoder, NULL)) != NULL)
                fprintf(stderr, "PARTIAL RESULT: %s\n", hyp);
            if (!ps_endpointer_in_speech(ep)) {
                fprintf(stderr, "Speech end at %.2f\n",
                        ps_endpointer_speech_end(ep));
                ps_end_utt(decoder);
                if ((hyp = ps_get_hyp(decoder, NULL)) != NULL)
                    printf("%s\n", hyp);
            }
        }
    }
    free(frame);
    if (pclose(sox) < 0)
        E_ERROR_SYSTEM("Failed to pclose(sox)");
    ps_endpointer_free(ep);
    ps_free(decoder);
    ps_config_free(config);

    return 0;
}

结果如下:
在这里插入图片描述

3.自定义字典

  • 打开一个txt,输入想指定的词典,尽量多几行,单行不识别
    在这里插入图片描述
  • 通过自定义模型库工具地址网址进行上传,选择文件后点击comple knowledge base按钮
    在这里插入图片描述
  • 点击comple knowledge base按钮后,下载对应的包解压
    在这里插入图片描述
  • 解压后,可以看到存在dic字典,再把后缀为.lm文件重命名为.lm.bin
    在这里插入图片描述
  • 打开0047.dic和之前的通用模型zh_cn.dic,对照zh_cn.dic0047.dic中添加英译,如果不存在就搜单个字音译,这个规律很好找,数字代表的声调

在这里插入图片描述

  • 替换到模型里,指定当前的词典,那么只会针对词典里的词进行识别了

四、交叉编译

交叉工具选择aarch64

# aarch64_toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_ASM_COMPILER aarch64-linux-gnu-as)
set(CMAKE_LINKER aarch64-linux-gnu-ld)
set(CMAKE_STRIP aarch64-linux-gnu-strip)
set(CMAKE_OBJCOPY aarch64-linux-gnu-objcopy)
set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu)
set(CMAKE_OBJDUMP aarch64-linux-gnu-objdump)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu)这一行比较重要,我在交叉编译时发现找不到对应的libm库,加了这一行才找到

cmake .. -DCMAKE_TOOLCHAIN_FILE=/toolchain.cmake -DCMAKE_INSTALL_PREFIX=./ -DCMAKE_EXE_LINKER_FLAGS="-lm"
make
make install

结果:
在这里插入图片描述


总结

本来想把其他几个开源语音识别引擎也初步记录一下的,看以后有没有时间吧,使用pocketsphinx是为了满足低资源消耗,等实际测试后再重新记录到这篇博客里面吧

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/908805.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis的持久化以及性能管理

目录 一、Redis持久化概述 1.什么是Redis持久化 2.持久化方式 3.RDB持久化 3.1概念 3.2触发条件 3.3执行流程 3.4启动时加载 4. AOF持久化 4.1概念 4.2启动AOF 4.3执行流程 4.4启动时加载 5.RDB和AOF的优缺点 二、Redis性能管理 1.查看Redis内存使用 2…

科研绘图系列:R语言组合连线图和箱线图(linechart+boxplot)

文章目录 介绍加载R包数据数据预处理画图1画图2系统信息介绍 连线图(Line Chart)是一种常用的数据可视化图表,它通过将一系列数据点用直线段连接起来来展示数据随时间或有序类别变化的趋势。以下是连线图可以表示的一些内容: 时间序列数据:展示数据随时间变化的趋势,例如…

Webserver(3.1)线程

目录 创建线程终止线程连接已终止的进程二级指针 线程分离线程取消线程属性线程同步多线程卖票 创建线程 编译时需要加-pthread gcc pthread_create.c -o create -pthread#include<pthread.h> #include<stdio.h> #include<string.h> #include<unistd.h&…

WPS实现手机电脑同步文件

复制链接&#xff0c;发送微信&#xff0c;即可在手机端打开同步编辑文档。 当手机编辑文档后&#xff0c;会有如下提示: 根据提示&#xff0c;可选择文件更新版本。

ES海量数据插入如何优化性能?

2024年10月NJSD技术盛典暨第十届NJSD软件开发者大会、第八届IAS互联网架构大会在南京召开。百度文心快码总经理臧志分享了《AI原生研发新范式的实践与思考》&#xff0c;探讨了大模型赋能下的研发变革及如何在公司和行业中落地&#xff0c;AI原生研发新范式的内涵和推动经验。 …

【linux】HTTPS 协议原理

1. 了解 HTTPS 协议原理 &#xff08;一&#xff09;认识 HTTPS HTTPS 也是一种应用层协议&#xff0c;是在 HTTP 协议的基础上引入了一个加密层 因为 HTTP协议的内容都是按照文本的方式进行传输的&#xff0c;这个过程中&#xff0c;可能会出现一些篡改的情况 &#xff08;…

labview学习总结

labview学习总结 安装labview的特点一、图形化编程范式二、并行执行机制三、硬件集成能力四、应用领域优势五、开发效率六、系统集成能力**labview基本组成示意图****常用程序结构图解**结语 基础知识介绍界面前后面板的概念平铺式和层叠式 帧的概念结构类型顺序结构for循环whi…

PostgreSQL技术内幕17:PG分区表

文章目录 0.简介1.概念介绍2.分区表技术产生的背景3.分区类型及使用方式4.实现原理4.1 分区表创建4.2 分区表查询4.3 分区表写入4.4 分区表删除 0.简介 本文主要介绍PG中分区表的概念&#xff0c;产生分区表技术的原因&#xff0c;使用方式和其内部实现原理&#xff0c;旨在能…

RHCSA课后练习3(网络与磁盘)

1、配置网络&#xff1a;为网卡添加一个本网段IPV4地址&#xff0c;x.x.x.123 涉及的知识点 配置网络&#xff1a; ens160&#xff1a;en---表示以太网 wl---表示无线局域网 ww---表示无线广域网 注意&#xff1a;一个网络接口&#xff0c;可以有多个网络连接&#xff0c;但…

开发人员需要知道的 20个Git命令行技巧

前言 大多数开发人员每天都会使用 Git&#xff0c;但许多人只是对其功能略知一二。 学习一些 git 命令行技巧可以改变游戏规则&#xff0c;让你更高效、更有成效&#xff0c;对版本控制更有信心。 那么&#xff0c;让我们深入了解每个开发人员工具包中都应该有的 20 个 Git …

第十一章 综合案例--“精品课程网站“开发

1.网站的开发流程 网站开发流程通常分为几个关键阶段&#xff0c;每个阶段都有其特定的任务和目标。以下是一个典型的网站开发流程&#xff1a; 1. 需求分析 目标设定&#xff1a;明确网站的目标和目的。 受众研究&#xff1a;确定目标用户&#xff0c;了解他们的需求和偏好。…

VSCode 1.82之后的vscode server离线安装

概述 因为今天在公司开发项目的时候&#xff0c;需要离线配置vscode远程开发环境&#xff0c; 根据参考链接1配置了一遍&#xff0c;不管怎么重启&#xff0c;VSCODE都还是提示下载vscode server&#xff0c;后面在官方issue上找到了解决方案 解决方案 修改Remote SSH的配置…

Linux和,FreeRTOS 任务调度原理,r0-r15寄存器,以及移植freertos(一)

目录、 1、r0-r15寄存器&#xff0c;保护现场&#xff0c;任务切换的原理 2、freertos移植 3、freertos的任务管理。 一、前言 写这篇文章的目的&#xff0c;是之前面试官&#xff0c;刚好问到我&#xff0c;移植FreeRTOS 到mcu&#xff0c;需要做哪些步骤&#xff0c;当时回…

「Mac畅玩鸿蒙与硬件28」UI互动应用篇5 - 滑动选择器实现

本篇将带你实现一个滑动选择器应用&#xff0c;用户可以通过滑动条选择不同的数值&#xff0c;并实时查看选定的值和提示。这是一个学习如何使用 Slider 组件、状态管理和动态文本更新的良好实践。 关键词 UI互动应用Slider 组件状态管理动态数值更新用户交互 一、功能说明 在…

云服务器防火墙设置方法

云服务器防火墙设置方法通常包括&#xff1a;第一步&#xff1a;登录控制台&#xff0c;第二步&#xff1a;配置安全组规则&#xff0c;第三步&#xff1a;添加和编辑规则&#xff0c;第四步&#xff1a;启用或停用规则&#xff0c;第五步&#xff1a;保存并应用配置。云服务器…

数据中台一键大解析!

自从互联玩企业掀起了数据中台风&#xff0c;数据中台这个点马上就火起来了&#xff0c;短短几年数据中台就得到了极高的热度&#xff0c;一大堆企业也在跟风做数据中台&#xff0c;都把数据中台作为企业数字化转型的救命稻草&#xff0c;可是如果我告诉你数据中台并不是万能钥…

【第一个qt项目的实现和介绍以及程序分析】【正点原子】嵌入式Qt5 C++开发视频

qt项目的实现和介绍 1.第一个qt项目  &#xff08;1).创建qt工程    [1].创建一个存放qt的目录    [2].新建一个qt工程    [3].编译第一个工程    发生错误时的解决方式 二.QT文件介绍  (1).工程中文件简单介绍  (2).项目文件代码流程介绍    [1].添…

计算机网络:网络层 —— 网络地址转换 NAT

文章目录 网络地址转换 NAT 概述最基本的 NAT 方法NAT 转换表的作用 网络地址与端口号转换 NAPTNAT 和 NAPT 的缺陷 网络地址转换 NAT 概述 尽管因特网采用了无分类编址方法来减缓 IPv4 地址空间耗尽的速度&#xff0c;但由于因特网用户数量的急剧增长&#xff0c;特别是大量小…

【算法】【优选算法】双指针(下)

目录 一、611.有效三⻆形的个数1.1 左右指针解法1.2 暴力解法 二、LCR 179.查找总价格为目标值的两个商品2.1 左右指针解法2.2 暴力解法 三、15.三数之和3.1 左右指针解法3.2 暴力解法 四、18.四数之和4.1 左右指针解法4.2 暴力解法 一、611.有效三⻆形的个数 题目链接&#x…

面试题分享11月1日

1、过滤器和拦截器的区别 过滤器是基于spring的 拦截器是基于Java Web的 2、session 和 cookie 的区别、关系 cookie session 存储位置 保存在浏览器 &#xff08;客户端&#xff09; 保存在服务器 存储数据大小 限制大小&#xff0c;存储数据约为4KB 不限制大小&…