pocketsphinx实现连续大词汇量语音识别
之前有个项目需求是要在客户内网实现一个连续大词汇语音识别功能,由于客户的内网是独立的,不能访问互联网,所以我只能到开源社区去找找碰碰运气了。后来在网上找到了cmusphinx(地址:http://cmusphinx.sourceforge.net/),项目是c#语言的,pocketsphinx这个语音识别引擎是cpp写的,Sphinx4这是java的版本,为了很好的集成到项目中去,我选择了pocketsphinx,因为它在移动端和PC端都能运行。本人C++语言很差,东拼西凑总算把调用识别引擎的方法写好了,编译成Dll以后,在C#里面用DllImport来调用。从github上下载项目源码后,写一个下面的类,代码如下:
#include <pocketsphinx.h>
#include <fstream>
#include <iostream>
#include <string>
#include <Windows.h>
#define EXPORT_DLL extern "C" __declspec(dllexport)//向c#开放此文件的cpp方法
using namespace std; //#define MODELDIR "model" //获取运行环境路径
EXPORT_DLL string GetProgramDir()
{
char buf[];
GetCurrentDirectory(,buf);
string path(buf);
return path;
} //保存识别结果
static void write_results(char *rec_result)
{
ofstream fResult("D:/run_path.txt",ios::app);
fResult<<rec_result;
fResult.close();
} //获取配置文件(1:英文识别,2:中文识别)
static cmd_ln_t* get_config(char *modelDir,int language_type)
{
string configPath(modelDir);
if(modelDir==NULL)
{
string configPath=GetProgramDir();
}
//write_results((char*)configPath.c_str());
cmd_ln_t *config;
string hmm,lm,dict;
if(language_type==)
{
hmm=configPath+"/model/en-us/en-us";
lm=configPath+"/model/en-us/en-us.lm.dmp";
dict=configPath+"/model/en-us/cmudict-en-us.dict";
config = cmd_ln_init(NULL, ps_args(), TRUE,
"-hmm", hmm.c_str(),
"-lm", lm.c_str(),
"-dict",dict.c_str(),
NULL);
}else
{
hmm=configPath+"/model/zh/zh";
lm=configPath+"/model/zh/zh_broadcastnews_64000_utf8.dmp";
dict=configPath+"/model/zh/zh_broadcastnews_utf8.dic";
config = cmd_ln_init(NULL, ps_args(), TRUE,
"-hmm", hmm.c_str(),
"-lm", lm.c_str(),
"-dict", dict.c_str(),
NULL);
}
/*if (config == NULL)
return config;*/
return config;
} //字符编码转换
char * UnicodeToANSI(const wchar_t* str)
{
char* result;
int textlen;
textlen=WideCharToMultiByte(CP_ACP,,str,-,NULL,,NULL,NULL);
result=(char *)malloc((textlen+)*sizeof(char));
memset(result,,sizeof(char)*(textlen+));
WideCharToMultiByte(CP_ACP,,str,-,result,textlen,NULL,NULL);
return result;
} wchar_t * UTF8ToNunicode(const char* str)
{
int textlen;
wchar_t * result;
textlen=MultiByteToWideChar(CP_UTF8,,str,-,NULL,);
result=(wchar_t *)malloc((textlen+)*sizeof(wchar_t));
memset(result,,(textlen+)*sizeof(wchar_t));
MultiByteToWideChar(CP_UTF8,,str,-,(LPWSTR)result,textlen);
return result;
} char* UTF8ToANSI(const char* str)
{
return UnicodeToANSI(UTF8ToNunicode(str));
} char strResult[];//保存语音识别返回结果
/*语言识别方法一
*languageType:(1:英文识别,2:中文识别,)
*file_name: (wav音频文件路径)
*/
EXPORT_DLL char* wavfile_speech_rec(int languageType,char *modelDir,char *file_name)
{
ps_decoder_t *ps;
int rv;
int16 buf[];
int32 score;
FILE *fh;
char const *hyp, *uttid;
cmd_ln_t *config=get_config(modelDir,languageType);
if(config==NULL)
{
strcpy(strResult,"语音模型配置文件读取失败!");
return strResult;
}
ps=ps_init(config);
if (ps == NULL)
{
strcpy(strResult,"解码器初始化失败!");
return strResult;
}
fh = fopen(file_name, "rb");
if (fh == NULL)
{
strcpy(strResult,"不是有效的wav文件!");
return strResult;
}
rv = ps_start_utt(ps);
if (rv < )
{
strcpy(strResult,"解码失败!");
return strResult;
}
while (!feof(fh)) {
size_t nsamp;
nsamp = fread(buf, , , fh);
rv = ps_process_raw(ps, buf, nsamp, FALSE, FALSE);
}
rv = ps_end_utt(ps);
if (rv < )
{
strcpy(strResult,"解码失败!");
return strResult;
}
hyp = ps_get_hyp(ps, &score);
if (hyp == NULL)
{
strcpy(strResult,"");
return strResult;
}else
{
strcpy(strResult,hyp);
}
fclose(fh);
fh=NULL;
ps_free(ps);
cmd_ln_free_r(config);
return UTF8ToANSI(strResult);
}
c#中调用的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text; namespace SpeechRec
{
/// <summary>
/// 语音识别工具类
/// </summary>
public class SpeechRecTool
{
public SpeechRecTool()
{ }
[DllImport("pocketsphinx_speech_rec.dll", EntryPoint = "GetProgramDir", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr GetProgramDir();
/// <summary>
/// wav文件识别
/// </summary> CharSet = CharSet.Ansi, EntryPoint = "wavfile_speech_rec")
/// <returns></returns>
[DllImport("pocketsphinx_speech_rec.dll", EntryPoint = "wavfile_speech_rec", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr wavfile_speech_rec(int lang, string modelPath, string fileName);
/// <summary>
/// wav文件识别
/// </summary>
/// <param name="language"></param>
/// <param name="fileName"></param>
public string WavFileSpeechRec(LanguageType language, string fileName)
{
string strResult = "";
if (System.IO.File.Exists(fileName))
{
WavTools wTool = new WavTools();
if (!new WavTools().IsStandardWavFile(fileName))
{
fileName = wTool.FormateWavFile(fileName);
}
IntPtr intPtrResult = wavfile_speech_rec((int)language, @"E:\SoftWare\语音识别\狮身人面像\pocketsphinx\bin\Release\Win32", fileName);
strResult = Marshal.PtrToStringAnsi(intPtrResult);
System.IO.File.WriteAllText("D:\\aa.txt", strResult, System.Text.Encoding.GetEncoding("GB2312"));
Console.WriteLine("执行结果:" + strResult);
}
else
{
Console.WriteLine("不是有效的音频文件");
}
return strResult;
}
}
/// <summary>
/// 语言类型
/// </summary>
public enum LanguageType
{
/// <summary>
/// 中文
/// </summary>
En = ,
/// <summary>
/// 英文
/// </summary>
Zh =
}
}
注意事项:音频要是wav,而且格式要和它demo里面的一致,我用了Naudio开源组件来实现wav音频格式的转换,如果音频比特率和采样率和它demo里面的不一样的话,会导致识别率降低
pocketsphinx实现连续大词汇量语音识别的更多相关文章
- MySQL随机获取数据的方法,支持大数据量
最近做项目,需要做一个从mysql数据库中随机取几条数据出来. 总所周知,order by rand 会死人的..因为本人对大数据量方面的只是了解的很少,无解,去找百度老师..搜索结果千篇一律.特发到 ...
- MySQL大数据量快速分页实现(转载)
在mysql中如果是小数据量分页我们直接使用limit x,y即可,但是如果千万数据使用这样你无法正常使用分页功能了,那么大数据量要如何构造sql查询分页呢? 般刚开始学SQL语句的时候,会这 ...
- 大数据量查询优化——数据库设计、SQL语句、JAVA编码
数据库设计方面: 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将 ...
- sql大数据量查询的优化技巧
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 提高MYSQL大数据量查询的速度
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- Mysql千万级大数据量查询优化
来源于:https://blog.csdn.net/A350204530/article/details/79040277 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ord ...
- 大数据量下的SQL Server数据库自身优化
原文: http://www.d1net.com/bigdata/news/284983.html 1.1:增加次数据文件 从SQL SERVER 2005开始,数据库不默认生成NDF数据文件,一般情 ...
- DB开发之大数据量高并发的数据库优化
一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. ...
- 大数据量高并发的数据库优化详解(MSSQL)
转载自:http://www.jb51.net/article/71041.htm 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能. ...
随机推荐
- Bell数
事实上,\[e^{(e^t-1)x}=\sum_{k=0}^{\infty}\frac{B_k(x)}{k!}.\]\[B_n(x)=x\sum_{k=1}^{n}\binom{n-1}{k-1}B_ ...
- Codeforces Round #622 (Div. 2) C2 - Skyscrapers (hard version) 单调栈
从左往右扫,找到比第i个小的第一个数字,l[i] = l[last] + (i - last) * m[i],用单调栈O(n)维护这个过程,再从右往左扫,同理可以算出r数组,注意一下long long ...
- How to Install Oracle Java 11 on Ubuntu 18.04 LTS (Bionic) Written by Rahul, Updated on April 3, 20
本文系转载备份 请阅读点击下面链接阅读原文以获取更佳地阅读体验.谢谢. How to Install Oracle Java 11 on Ubuntu 18.04 LTS (Bionic) Writt ...
- vue常用插件之视频播放(rtmp m3u8)
vue-video-player(5.0.2) 最近我的项目做了一个监控视屏的显示,后台提供的视屏格式是rtmp 后来又改为m3u8,没成功,原因是占用内存过大,所以取消了这种方式 一.安装 npm ...
- Vuejs+elementUI项目,在进行打包时,要注意的问题
注意:打包之前,需要注意修改一些地方 (1)若是前后端分离开发的,前端开发过程中可能会在api.js中设置访问路径为服务器所在电脑的ip:端口,打包前,最好将它改回localhost:8080 (2) ...
- PP: Toeplitz Inverse Covariance-Based Clustering of Multivariate Time Series Data
From: Stanford University; Jure Leskovec, citation 6w+; Problem: subsequence clustering. Challenging ...
- Python标准库之shelve模块(序列化与反序列化)
shelve模块是一个简单的key,value将内存数据通过文件持久化的模块,可以持久化任何picklel可支持的Python数据格式. 序列化 序列化源代码: import shelve impor ...
- Windows系统对拍程序
Windows系统对拍程序,其中包含c++11用法,请使用c++11标准编译.此对拍程序会在发现错误时显示错误行号以及对应内容,方便比对. 此对拍程序自动使用g++对源代码进行编译.如果出现找不到g+ ...
- Jmeter-几种脚本录制方式
一.使用代理服务器进行录制 1.创建线程组 2.创建http代理服务器 分组解释 不对样本分组:所有请求全部罗列 在组件添加分隔:加入一个虚拟的以分割线命名的动作 每个组放入一个新的控制器:执行时按控 ...
- 测试准确率计算方法说明 pre.eq(target).float().sum().item()
测试准确率计算方法说明 pre.eq(target).float().sum().item() 待办 pred = logits.argmax(dim=1) correct += pred.eq(ta ...