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 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能. ...
随机推荐
- js面向对象怎么理解
js面向对象怎么理解 <一>. 认识对象.首先要认识对象:在编程中,对象(object)是具体的某一个实例,唯一的某一个个体.如:电脑就是一个统称,而你面前的这一台电脑就是对象.而电脑的统 ...
- [CF1303D] Fill The Bag - 贪心
Solution 考虑从低位往高位贪心,设当前在处理第 \(i\) 位,更低位剩余的部分一共可以拼出 \(cnt\) 个 \(2^i\) 如果 \(n\) 的这一位是 \(1\) ,那么这一位就需要处 ...
- AI 所需的数学基础
一.[微积分] 基础概念(极限.可微与可导.全导数与偏导数):只要学微积分,就必须要明白的概念,否则后面什么都无法继续学习. 函数求导:求导是梯度的基础,而梯度是 AI 算法的基础,因此求导非常重要! ...
- H5_0016:js获取网络中配置文件中的参数
//获取网络配置文件中的参数 $.get("https://cdn.com/share.json", function(e) { //console ...
- 使用U盘装Windows10系统
一.装备工作 使用U盘装系统需要准备以下工具: 8G左右的U盘一个.由于制作启动盘会删除U盘的所有数据,所以重要资料请提前备份. 系统的镜像文件.这里我推荐MSDN, 我告诉你.这里下载的镜像和官方的 ...
- tomcat常见状态码
- Server2012多用户远程桌面及问题解决记录
1.开启远程桌面 转载自 https://jingyan.baidu.com/article/c275f6ba9321fda33c756712.html 2.添加用户 转载自 https://jin ...
- 如何架构一个 React 项目?
编程有点像搞园艺.比起竭力去对付BUG(虫子),我们更愿意把一切弄得整洁有序,以免最后落得个身在荒野丛林中.低劣的架构会拖我们的后腿,也会使得BUG更容易钻进系统里去. 想要对你的项目进行架构,方法有 ...
- LightOJ-1370 Bi-shoe and Phi-shoe (欧拉函数+二分)
Problem Description Bamboo Pole-vault is a massively popular sport in Xzhiland. And Master Phi-shoe ...
- Python2安装MySQLdb
在http://www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python下载对应的包版本,如果是win7 64位2.7版本的python,就下载 MySQL_p ...