之前有个项目需求是要在客户内网实现一个连续大词汇语音识别功能,由于客户的内网是独立的,不能访问互联网,所以我只能到开源社区去找找碰碰运气了。后来在网上找到了cmusphinx(地址:http://cmusphinx.sourceforge.net/),项目是c#语言的,pocketsphinx这个语音识别引擎是cpp写的,Sphinx4这是java的版本,为了很好的集成到项目中去,我选择了pocketsphinx,因为它在移动端和PC端都能运行。本人C++语言很差,东拼西凑总算把调用识别引擎的方法写好了,编译成Dll以后,在C#里面用DllImport来调用。从github上下载项目源码后,写一个下面的类,代码如下:

  1. #include <pocketsphinx.h>
  2. #include <fstream>
  3. #include <iostream>
  4. #include <string>
  5. #include <Windows.h>
  6. #define EXPORT_DLL extern "C" __declspec(dllexport)//向c#开放此文件的cpp方法
  7. using namespace std;
  8.  
  9. //#define MODELDIR "model"
  10.  
  11. //获取运行环境路径
  12. EXPORT_DLL string GetProgramDir()
  13. {
  14. char buf[];
  15. GetCurrentDirectory(,buf);
  16. string path(buf);
  17. return path;
  18. }
  19.  
  20. //保存识别结果
  21. static void write_results(char *rec_result)
  22. {
  23. ofstream fResult("D:/run_path.txt",ios::app);
  24. fResult<<rec_result;
  25. fResult.close();
  26. }
  27.  
  28. //获取配置文件(1:英文识别,2:中文识别)
  29. static cmd_ln_t* get_config(char *modelDir,int language_type)
  30. {
  31. string configPath(modelDir);
  32. if(modelDir==NULL)
  33. {
  34. string configPath=GetProgramDir();
  35. }
  36. //write_results((char*)configPath.c_str());
  37. cmd_ln_t *config;
  38. string hmm,lm,dict;
  39. if(language_type==)
  40. {
  41. hmm=configPath+"/model/en-us/en-us";
  42. lm=configPath+"/model/en-us/en-us.lm.dmp";
  43. dict=configPath+"/model/en-us/cmudict-en-us.dict";
  44. config = cmd_ln_init(NULL, ps_args(), TRUE,
  45. "-hmm", hmm.c_str(),
  46. "-lm", lm.c_str(),
  47. "-dict",dict.c_str(),
  48. NULL);
  49. }else
  50. {
  51. hmm=configPath+"/model/zh/zh";
  52. lm=configPath+"/model/zh/zh_broadcastnews_64000_utf8.dmp";
  53. dict=configPath+"/model/zh/zh_broadcastnews_utf8.dic";
  54. config = cmd_ln_init(NULL, ps_args(), TRUE,
  55. "-hmm", hmm.c_str(),
  56. "-lm", lm.c_str(),
  57. "-dict", dict.c_str(),
  58. NULL);
  59. }
  60. /*if (config == NULL)
  61. return config;*/
  62. return config;
  63. }
  64.  
  65. //字符编码转换
  66. char * UnicodeToANSI(const wchar_t* str)
  67. {
  68. char* result;
  69. int textlen;
  70. textlen=WideCharToMultiByte(CP_ACP,,str,-,NULL,,NULL,NULL);
  71. result=(char *)malloc((textlen+)*sizeof(char));
  72. memset(result,,sizeof(char)*(textlen+));
  73. WideCharToMultiByte(CP_ACP,,str,-,result,textlen,NULL,NULL);
  74. return result;
  75. }
  76.  
  77. wchar_t * UTF8ToNunicode(const char* str)
  78. {
  79. int textlen;
  80. wchar_t * result;
  81. textlen=MultiByteToWideChar(CP_UTF8,,str,-,NULL,);
  82. result=(wchar_t *)malloc((textlen+)*sizeof(wchar_t));
  83. memset(result,,(textlen+)*sizeof(wchar_t));
  84. MultiByteToWideChar(CP_UTF8,,str,-,(LPWSTR)result,textlen);
  85. return result;
  86. }
  87.  
  88. char* UTF8ToANSI(const char* str)
  89. {
  90. return UnicodeToANSI(UTF8ToNunicode(str));
  91. }
  92.  
  93. char strResult[];//保存语音识别返回结果
  94. /*语言识别方法一
  95. *languageType:(1:英文识别,2:中文识别,)
  96. *file_name: (wav音频文件路径)
  97. */
  98. EXPORT_DLL char* wavfile_speech_rec(int languageType,char *modelDir,char *file_name)
  99. {
  100. ps_decoder_t *ps;
  101. int rv;
  102. int16 buf[];
  103. int32 score;
  104. FILE *fh;
  105. char const *hyp, *uttid;
  106. cmd_ln_t *config=get_config(modelDir,languageType);
  107. if(config==NULL)
  108. {
  109. strcpy(strResult,"语音模型配置文件读取失败!");
  110. return strResult;
  111. }
  112. ps=ps_init(config);
  113. if (ps == NULL)
  114. {
  115. strcpy(strResult,"解码器初始化失败!");
  116. return strResult;
  117. }
  118. fh = fopen(file_name, "rb");
  119. if (fh == NULL)
  120. {
  121. strcpy(strResult,"不是有效的wav文件!");
  122. return strResult;
  123. }
  124. rv = ps_start_utt(ps);
  125. if (rv < )
  126. {
  127. strcpy(strResult,"解码失败!");
  128. return strResult;
  129. }
  130. while (!feof(fh)) {
  131. size_t nsamp;
  132. nsamp = fread(buf, , , fh);
  133. rv = ps_process_raw(ps, buf, nsamp, FALSE, FALSE);
  134. }
  135. rv = ps_end_utt(ps);
  136. if (rv < )
  137. {
  138. strcpy(strResult,"解码失败!");
  139. return strResult;
  140. }
  141. hyp = ps_get_hyp(ps, &score);
  142. if (hyp == NULL)
  143. {
  144. strcpy(strResult,"");
  145. return strResult;
  146. }else
  147. {
  148. strcpy(strResult,hyp);
  149. }
  150. fclose(fh);
  151. fh=NULL;
  152. ps_free(ps);
  153. cmd_ln_free_r(config);
  154. return UTF8ToANSI(strResult);
  155. }

c#中调用的代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6.  
  7. namespace SpeechRec
  8. {
  9. /// <summary>
  10. /// 语音识别工具类
  11. /// </summary>
  12. public class SpeechRecTool
  13. {
  14. public SpeechRecTool()
  15. {
  16.  
  17. }
  18. [DllImport("pocketsphinx_speech_rec.dll", EntryPoint = "GetProgramDir", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  19. public static extern IntPtr GetProgramDir();
  20. /// <summary>
  21. /// wav文件识别
  22. /// </summary> CharSet = CharSet.Ansi, EntryPoint = "wavfile_speech_rec")
  23. /// <returns></returns>
  24. [DllImport("pocketsphinx_speech_rec.dll", EntryPoint = "wavfile_speech_rec", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
  25. private static extern IntPtr wavfile_speech_rec(int lang, string modelPath, string fileName);
  26. /// <summary>
  27. /// wav文件识别
  28. /// </summary>
  29. /// <param name="language"></param>
  30. /// <param name="fileName"></param>
  31. public string WavFileSpeechRec(LanguageType language, string fileName)
  32. {
  33. string strResult = "";
  34. if (System.IO.File.Exists(fileName))
  35. {
  36. WavTools wTool = new WavTools();
  37. if (!new WavTools().IsStandardWavFile(fileName))
  38. {
  39. fileName = wTool.FormateWavFile(fileName);
  40. }
  41. IntPtr intPtrResult = wavfile_speech_rec((int)language, @"E:\SoftWare\语音识别\狮身人面像\pocketsphinx\bin\Release\Win32", fileName);
  42. strResult = Marshal.PtrToStringAnsi(intPtrResult);
  43. System.IO.File.WriteAllText("D:\\aa.txt", strResult, System.Text.Encoding.GetEncoding("GB2312"));
  44. Console.WriteLine("执行结果:" + strResult);
  45. }
  46. else
  47. {
  48. Console.WriteLine("不是有效的音频文件");
  49. }
  50. return strResult;
  51. }
  52. }
  53. /// <summary>
  54. /// 语言类型
  55. /// </summary>
  56. public enum LanguageType
  57. {
  58. /// <summary>
  59. /// 中文
  60. /// </summary>
  61. En = ,
  62. /// <summary>
  63. /// 英文
  64. /// </summary>
  65. Zh =
  66. }
  67. }

注意事项:音频要是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. git Auto packing the repository in background for optimum performance

    遇到问题: git本地仓库,如果长时间不进行清理,几个月以后的某一天,可能拉取代码的时候突然提示你 git Auto packing the repository in background for ...

  2. 视频格式转换mp4

    第一步:https://ffmpeg.zeranoe.com/builds/下载ffmpeg 或者:百度云下载: 链接:https://pan.baidu.com/s/1x_QogbV8xFjkYTe ...

  3. 前端页面中:jsp和HTML的区别之处

    JSP和HTML的区别 HTML页面是静态页面,也就是事先由用户写好放在服务器上,固定内容,不会变,由web服务器向客户端发送,平时上网看的网页都是大部分都是基于html语言的. JSP页面是有JSP ...

  4. 深入浅出Mybatis系列六-objectFactory、plugins、mappers简介与配置

    注:本文转载自南轲梦 注:博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 上篇文章<深入浅出Mybatis系列(五)---TypeHandler简介及配 ...

  5. C#中怎样获取System.Drawing.Color的所有颜色对象并存到数组中

    场景 需要在生成一组多条曲线时,随机从一颜色数组中取颜色,至少一百种颜色以上. 而System.Drawing.Color自带140多种颜色 那么怎样将其自带的颜色对象取出并存在数组中. 注: 博客主 ...

  6. jQuery---下拉菜单案例

    下拉菜单案例 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UT ...

  7. Mac 多版本 JDK 管理

    Mac 多版本 JDK 管理 1. 准备 ZSH Homebrew Oracle JDK 1.8 安装包(Homebrew 官方源和第三方源不再提供老版本的 Oracle JDK) 2. 安装 JDK ...

  8. RYU安装教程

    一.使用pip的形式安装RYU 1.首先检查ubuntu中是否存在pip,命令为 sudo pip3 --version 2.如果存在则使用默认版本8.1.1就行不必跟新,否则自己下载一个pip 3. ...

  9. 关于在Ubuntu中无法使用tree命令的原因

    初学linux系统的时候使用的是Ubuntu的操作系统,边看视频边学习,却发现很多命令行在自己使用的时候没有效果,只会盲目的百度,后面回过头来仔细一看才发现,原来终端早就给你答案了,只是自己一看到英语 ...

  10. 关于List比较好玩的操作

    作为Java大家庭中的集合类框架,List应该是平时开发中最常用的,可能有这种需求,当集合中的某些元素符合一定条件时,想要删除这个元素.如: public class ListTest { publi ...