C# 实现语音听写
本文系原创,禁止转载。
分享如何使用c#对接科大讯飞语音听写服务,简单高效地实现语音听写。
实现语音听写主要分为录音和语音识别两部分;录音是指获取设备声卡端口的音频数据并将之保存为音频文件,语音识别就是将刚才所述的音频文件通过调用讯飞的语音听写服务转换为文字。
相关的类库文件
1. 开源录音库 NAudio.dll
http://pan.baidu.com/s/1dFth2nv
2.语音听写库 msc.dll
去讯飞开放平台申请相关的SDK
录音部分可以使用开源的.net音频处理类库NAudio.dll,它是托管的类库,使用起来比较方便,当然你也可以自己去读声卡录音,微软有相关的系统API,这里不详述。
录音部分核心代码:
//初始化
String FilePath = AppDomain.CurrentDomain.BaseDirectory + "Temp.wav";
WaveIn m_waveSource = new WaveIn();
m_waveSource.WaveFormat = new NAudio.Wave.WaveFormat(, , );// 16bit,16KHz,Mono的录音格式
m_waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable);
m_waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped);
WaveFileWriter m_waveFile = new WaveFileWriter(m_fileName, m_waveSource.WaveFormat); //开始录音
m_waveSource.StartRecording(); //保存到截获到的声音
private void waveSource_DataAvailable(object sender, WaveInEventArgs e)
{
if (m_waveFile != null)
{
m_waveFile.Write(e.Buffer, , e.BytesRecorded);
m_waveFile.Flush();
}
} //停止录音
m_waveSource.StopRecording();
录音完成后就可以进行语音听写了,讯飞提供的语音听写服务SDK中的类库msc.dll是原生的类库,在c#中没有办法像托管类库那样使用,需要通过使用Import的方式来引用,也可以包装成托管的类库来使用,这里只介绍第一种方法。
上述类库是msc.dll使用C语言封装的,在声明接口的时候需注意C语言的变量类型的表达方式与C#有很多不同之处;比如,在SDK中有很多针对内存地址操作的,所以涉及到很多的指针类型变量,而C#中指针概念相对较弱。提供两个解决思路,一是在C#中声明UnSafe代码,这样就可以像C/C++一样使用指针,二是使用IntPtr、ref 变量的表达方式,来实现“兼容”。
相关接口声明:
[DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MSPLogin(string usr, string pwd, string @params);
[DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr QISRSessionBegin(string grammarList, string _params, ref int errorCode);
[DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int QISRGrammarActivate(string sessionID, string grammar, string type, int weight);
[DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int QISRAudioWrite(string sessionID, IntPtr waveData, uint waveLen, int audioStatus, ref int epStatus, ref int recogStatus);
[DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr QISRGetResult(string sessionID, ref int rsltStatus, int waitTime, ref int errorCode);
[DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int QISRSessionEnd(string sessionID, string hints);
[DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int QISRGetParam(string sessionID, string paramName, string paramValue, ref uint valueLen);
[DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int MSPLogout();
业务流程:
1.调用 MSPLogin(...)接口登入,可以只登入一次,但是必须保证在调用其他接口前先登入;
2.调用 QISRSessionBegin(...)开始一次语音听写;
3.调用 QISRAudioWrite(...) 分块写入音频数据
4.循环调用 QISRGetResult(...) 接口返回听写结果
5.调用 QISRSessionEnd(...) 主动结束本次听写
6.不再使用服务的时候 调用MSPLogout()登出,避免不必要的麻烦。
核心代码:
public string AudioToString(string inFile)
{
int ret = ;
string text = String.Empty;
FileStream fileStream = new FileStream(inFile, FileMode.OpenOrCreate);
byte[] array = new byte[this.BUFFER_NUM];
IntPtr intPtr = Marshal.AllocHGlobal(this.BUFFER_NUM);
int audioStatus = ;
int epStatus = -;
int recogStatus = -;
int rsltStatus = -;
while (fileStream.Position != fileStream.Length)
{
int waveLen = fileStream.Read(array, , this.BUFFER_NUM);
Marshal.Copy(array, , intPtr, array.Length);
ret = iFlyASR.QISRAudioWrite(this.m_sessionID, intPtr, (uint)waveLen, audioStatus, ref epStatus, ref recogStatus);
if (ret != )
{
fileStream.Close();
throw new Exception("QISRAudioWrite err,errCode=" + ret);
}
if (recogStatus == )
{
IntPtr intPtr2 = iFlyASR.QISRGetResult(this.m_sessionID, ref rsltStatus, , ref ret);
if (intPtr2 != IntPtr.Zero)
{
text += this.Ptr2Str(intPtr2);
}
}
Thread.Sleep();
}
fileStream.Close();
audioStatus = ;
ret = iFlyASR.QISRAudioWrite(this.m_sessionID, intPtr, 1u, audioStatus, ref epStatus, ref recogStatus);
if (ret != )
{
throw new Exception("QISRAudioWrite write last audio err,errCode=" + ret);
}
int timesCount = ;
while (true)
{
IntPtr intPtr2 = iFlyASR.QISRGetResult(this.m_sessionID, ref rsltStatus, , ref ret);
if (intPtr2 != IntPtr.Zero)
{
text += this.Ptr2Str(intPtr2);
}
if (ret != )
{
break;
}
Thread.Sleep();
if (rsltStatus == || timesCount++ >= )
{
break;
}
}
return text;
}
自己设计以下UI交互,或者和你的应用程序结合一下,就可以让你的应用程序长一双会听的耳朵了!
结果:

C# 实现语音听写的更多相关文章
- Android讯飞语音云语音听写学习
讯飞语音云语音听写学习 这几天两个舍友都买了iPhone 6S,玩起了"Hey, Siri",我依旧对我的Nexus 5喊着"OK,Google" ...
- UI进阶 科大讯飞(1) 语音听写(语音转换成文字)
一.科大讯飞开放平台: http://www.xfyun.cn/ 注册.登录之后创建新应用. 因为本项目只实现了语音听写,所以在SDK下载中心勾选语音听写单项SDK就可以了 开发平台选择iOS,应用选 ...
- Android集成科大讯飞SDK语音听写及语音合成功能实现
前言 现在软件设计越来越人性化.智能化.一些常见的输入都慢慢向语音听写方向发展,一些常见的消息提示都向语音播报发展.所以语音合成和语音听写是手机软件开发必不可少的功能.目前国内这方面做的比较好的应该是 ...
- 讯飞云 API 语音听写 python3 调用例程
#!/usr/bin/python3 # -*- coding: UTF-8 -*- import requests import time import gzip import urllib imp ...
- Android 讯飞语音听写SDK快速接入(附空指针解决和修改对话框文字方法)
1.账号准备工作 首先要有一个讯飞的账号啦,为后面申请APPID.APPKey等东西做准备.顺带一提:讯飞对不同认证类型用户开 放的SDK的使用次数是有不同的,详情如下图. 账号申请完成后,需要去你自 ...
- ros语音交互(四)移植科大讯飞语音识别到ros
将以前下载的的语音包的 samples/iat_record/的iat_record.c speech_recognizer.c speech_recognizer.c 拷贝到工程src中, linu ...
- iOS: 讯飞语音的使用
一.介绍: 讯飞语音做的相当不错,容错率达到90%多,如果需要做语音方面的功能,它绝对是一个不错的选择.讯飞语音的功能很多:语音听写.语音识别.语音合成等,但我们最常用的还是语音听写.讯飞语音中包含界 ...
- 3D语音天气球(源码分享)——在Unity中使用Android语音服务
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 这个项目准备分四部分介绍: 一:创建可旋转的"3D球":3 ...
- android讯飞语音开发常遇到的问题
场景:android项目中共使用了3个语音组件:在线语音听写.离线语音合成.离线语音识别 11208:遇到这个错误,授权应用失败,先检查装机量(3台测试权限),以及appid的申请时间(35天期限), ...
随机推荐
- python中defaultdict的用法
初识defaultdict 之前在使用字典的时候, 用的比较随意, 只是简单的使用dict. 然而这样在使用不存在的key的时候发生KeyError这样的一个报错, 这时候就该defaultdict登 ...
- wdcp php5.3添加pdo_mysql模块
先查看探针: pdo没有支持mysql.导致了PHpwind以及thinkphp框架的一些运用了pdo进行mysql操作的程序无法运行. php5.3默认是封装了pdo_mysq的.那么就没必要单独下 ...
- 禅道---Bug管理模块
禅道官网:http://www.cnezsoft.com/ 简介: 开源免费的项目管理软件.集产品管理.项目管理.测试管理一体以及事物管理组织管理的功能 使用原因: 开源 方便跟踪管理Bug 使用简单 ...
- 移动平台Unity3D 应用性能优化
WeTest 导读 做了大概半年多VR应用了,VR由于双眼double渲染的原因,对性能的优化要求比较高,在项目的进展过程中,总结了一些关于移动平台上Unity3D的性能优化经验,供分享. 一.移动平 ...
- centos文件权限详解
假设回显信息为 ①-②rws③r-x④r-x ⑤1 ⑥root ⑦root ⑧430540 ⑨Dec 20 18:27 ⑩/usr/sbin/passwd ,现在逐一分析其内容. ①. 首字符-,表 ...
- 如何在phpstorm中安装xdebug调试工具
用习惯了Visio Studio的调试工具,如果写个php用phpstorm没有调试工具,觉得还缺点什么.接下来就讲解一下如果安装xdebug,最好发现这个插件真好用! 1.下载xdebug.tar: ...
- .NET Core程序中使用User Secrets存储敏感数据
前言 在开发中经常会用到一些敏感数据,比如AppSecret或数据库连接字符串,无论是硬编码还是写在配置文件中,最终都要push到svn或git上.对于开源项目,这些敏感数据就无隐私可言了,对于私有项 ...
- Akka(10): 分布式运算:集群-Cluster
Akka-Cluster可以在一部物理机或一组网络连接的服务器上搭建部署.用Akka开发同一版本的分布式程序可以在任何硬件环境中运行,这样我们就可以确定以Akka分布式程序作为标准的编程方式了. 在上 ...
- Android 4.0以后正确的获取外部sd卡存储目录
刚解决这个棘手的问题 找了很久,随笔记下. 网上搜索 android 获取外部sd卡存储目录 普遍都是: 1) Environment.getExternalStorageDirectory() 这个 ...
- php Base64编码文件二进制流主要使用
<?php header( "Content-type: image/jpeg"); //$filename='1.jpg'; //$content=file_get_con ...