之前有个项目需求是要在客户内网实现一个连续大词汇语音识别功能,由于客户的内网是独立的,不能访问互联网,所以我只能到开源社区去找找碰碰运气了。后来在网上找到了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实现连续大词汇量语音识别的更多相关文章

  1. MySQL随机获取数据的方法,支持大数据量

    最近做项目,需要做一个从mysql数据库中随机取几条数据出来. 总所周知,order by rand 会死人的..因为本人对大数据量方面的只是了解的很少,无解,去找百度老师..搜索结果千篇一律.特发到 ...

  2. MySQL大数据量快速分页实现(转载)

    在mysql中如果是小数据量分页我们直接使用limit x,y即可,但是如果千万数据使用这样你无法正常使用分页功能了,那么大数据量要如何构造sql查询分页呢?     般刚开始学SQL语句的时候,会这 ...

  3. 大数据量查询优化——数据库设计、SQL语句、JAVA编码

    数据库设计方面: 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将 ...

  4. sql大数据量查询的优化技巧

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  5. 提高MYSQL大数据量查询的速度

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  6. Mysql千万级大数据量查询优化

    来源于:https://blog.csdn.net/A350204530/article/details/79040277 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 ord ...

  7. 大数据量下的SQL Server数据库自身优化

    原文: http://www.d1net.com/bigdata/news/284983.html 1.1:增加次数据文件 从SQL SERVER 2005开始,数据库不默认生成NDF数据文件,一般情 ...

  8. DB开发之大数据量高并发的数据库优化

    一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. ...

  9. 大数据量高并发的数据库优化详解(MSSQL)

    转载自:http://www.jb51.net/article/71041.htm 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能. ...

随机推荐

  1. Centos7 同时运行PHP5.2和PHP7.1配置

    工作环境一直都是lnmp,其中PHP已经升级到7.1版本了.突然有份代码需要运行在PHP5.2上.但是之前的环境还是需要的,所以需要在centos中再安装PHP5.2. 0.之前的php7安装在/us ...

  2. FLUSH+RELOAD技术

    FLUSH+RELOAD技术是PRIME+PROBE技术的变体,攻击间谍进程和目标进程的共享页.在共享页中,间谍进程可以确保一个特定的内存的映射从整个cache的层级中剔除.间谍进程就是使用这一点去监 ...

  3. 51nod1326 遥远的旅途(spfa+dp)

    题意: 给出一个无向图,问从1到n是否存在一条长度为L的路径. n,m<=50,1<=路径长度<=10000,L<=10^18 思路: 改变一下思路,我们发现,假设从起点1走到 ...

  4. vue实现网页简单计算器实例代码

    效果: 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  5. nginx 简单理解和配置

    1.概念 Nginx是一个高性能的HTTP和反向代理的web服务器,同时也提供了IMAP/POP3/SMTP服务,Nginx是由伊戈尔·塞索耶夫为俄罗斯访问量第二的Rambler.ru站点开发的,第一 ...

  6. SpringBoot学习- 10、设计用户角色权限表

    SpringBoot学习足迹 前几节已经基本了解了SpringBoot框架常用的技术,其他的消息队列,定时器等技术暂时用不到,真正项目中如果基于微信系,阿里系开发的话,还要了解平台专用的技术知识,学习 ...

  7. Django学习笔记3

    From the last two parts, we know, by using the HttpResponse we can return text to the web page, and ...

  8. 关于vue 里:class 的几种使用方式

    最近一直在做vue项目 从网上搜索到的资料不太多.关于:class的使用 结合自己的实现 整理如下.接下来一篇写:style .其实从:class 这里可以想到:style的使用 也是类似的 一 cl ...

  9. ECMAScript基本语法——②注释

    单行注释://注释内容多行注释:/*注释内容*/

  10. gap间隙锁

    1.什么式gap锁 (1)在索引记录之间,或者在索引之前,或者索引之后的区间上加锁,就是gap锁.比如: SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR ...