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 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能. ...
随机推荐
- 使用mysql8.+版本,使用mybatis的代码生成工具:mybatis-generator连接数据库时Unknown initial character set index '255' received from server. Initial client character set can be forced via the 'characterEncoding' property.
Error connecting to database: (using class org.gjt.mm.mysql.Driver)Unknown initial character set ind ...
- 1级搭建类113-Oracle 11gR2 SI FS(OEL 6.10)
Oracle 11g 单实例文件系统搭建(EMDC) EMDC:Database Control 单实例主机.数据库等监控,这东西12c之后没有了 EMGC:Grid Control 单独安装GC软件 ...
- HTML文档快捷键
一.web浏览器 1.刷新网页 F5 二.VS Code 常用快捷键 1.快速生成HTML代码 首先,建立一个空文档,选择编程语言为HTML: 其次,按下!(英文状态下),再按下tab键,就可以了 ...
- eclipse中配置maven环境
一.配置setting.xml文件 1.首先将下载好的maven打开,打开文件夹,首先就需要对maven安装目录下有个config文件夹,在文件夹下有settings.xml文件.settings里面 ...
- Winform form窗体已弹出框的形式出现并回传值
From2(弹出框)回传数据到From1 Form1(数据接收form): public string Sstr; private void button1_Click(object sender, ...
- js集合
var list = {};//声明 List[0] = 52;//赋值 List[1] = 57;//赋值
- SCSS的基本操作
Sass是成熟.稳定.强大的CSS预处理器,而SCSS是Sass3版本当中引入的新语法特性,完全兼容CSS3的同时继承了Sass强大的动态功能. 特性概览 CSS书写代码规模较大的Web应用时,容易造 ...
- 自定义输入函数 - C语言编程
有返回功能的输入函数: #include <stdio.h> #include <conio.h> void input(char content[]); int main() ...
- 常用excel函数公式及操作示例
一.数字处理 1.取绝对值 =ABS(数字) 2.取整 =INT(数字) 3.四舍五入 =ROUND(数字,小数位数) 二.判断公式 1.把公式产生的错误值显示为空 公式:C2 =IFERROR(A2 ...
- 巨杉Talk | 拒绝数据碎片化,原生分布式数据库灵活应对数据管理需求
2019年7月19-20日,以“运筹帷幄,数揽未来”为主题的DAMS中国数据智能管理峰会在上海青浦区成功举办.在DAMS峰会上,巨杉数据库为大家带来了题为“云架构下的分布式数据库设计与实践”的主题分享 ...