public static extern int QISRAudioWrite(string sessionID, byte[] waveData, uint waveLen, AudioStatus audioStatus, ref EpStatus epStatus, ref RsltStatus rsltStatus);
public static extern IntPtr QISRGetResult(string sessionID, ref RsltStatus rsltStatus, int waitTime, ref int errorCode);
public void RunIat(string audioFile, string param) { string sessionID = null; EpStatus epStatus = EpStatus.MSP_EP_LOOKING_FOR_SPEECH; RsltStatus rsltStatus = RsltStatus.MSP_REC_STATUS_SUCCESS; long count = 0; //计次? uint totalLen = 0; //获取音频文件 using (FileStream fs = new FileStream(audioFile, FileMode.Open, FileAccess.Read)) { fs.Seek(0, SeekOrigin.End); var size = fs.Length; fs.Seek(0, SeekOrigin.Begin); var data = new byte[size]; if (data == null) { if (onErrorEvent != null) { onErrorEvent.Invoke("内存不足."); } return; } var readSize = fs.Read(data, 1, (int)size); if (readSize != size) { onErrorEvent.Invoke("读" + audioFile + "出错"); return; } int errcode = 0; //开始语音听写 sessionID = Marshal.PtrToStringAuto(MSCDLL.QISRSessionBegin(null, param, ref errcode)); if (errcode != (int)ErrorCode.MSP_SUCCESS) { if (onErrorEvent != null) { onErrorEvent.Invoke("Iat开启出错" + errcode); } return; } while (true) { uint len = 10 * 640; int ret = 0; if (size < 2 * len) { len = (uint)size; } if (len <= 0) { break; } var audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_CONTINUE; if (count == 0) { audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_FIRST; } ret = MSCDLL.QISRAudioWrite(sessionID, data, len, audioStatus, ref epStatus, ref rsltStatus); if (ret != (int)ErrorCode.MSP_SUCCESS) { if (onErrorEvent != null) { onErrorEvent.Invoke("写入本次识别的音频失败." + ret); } return; } count += len; size -= len; //已经有部分听写结果 if (rsltStatus == RsltStatus.MSP_REC_STATUS_SUCCESS) { var result = Marshal.PtrToStringAuto(MSCDLL.QISRGetResult(sessionID, ref rsltStatus, 0, ref ret)); if (ret != 0) { if (onErrorEvent != null) { onErrorEvent.Invoke("获取识别结果失败." + ret); } return; } if (result != null) { uint resultLen = (uint)result.Length; totalLen += resultLen; if (totalLen >= 4096) { if (onErrorEvent != null) { onErrorEvent.Invoke("对于临时资源没有足够的缓存空间。"); } return; } } } if (epStatus == EpStatus.MSP_EP_AFTER_SPEECH) { break; } Thread.Sleep(200); } errcode = MSCDLL.QISRAudioWrite(sessionID, null, 0, AudioStatus.MSP_AUDIO_SAMPLE_LAST, ref epStatus, ref rsltStatus); if (errcode != 0) { if (onErrorEvent != null) { onErrorEvent.Invoke("音频写入失败。" + errcode); } return; } } }
string filename = $"Call.wav"; //合成的语音文件 #endregion #region 事件处理 /// <summary> /// 本地语音识别 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnLocalVoice_Click(object sender, EventArgs e) { //业务流程: //1.调用 MSPLogin(...)接口登入,可以只登入一次,但是必须保证在调用其他接口前先登入; //2.调用 QISRSessionBegin(...)开始一次语音听写; //3.循环调用 QISRAudioWrite(...) 分块写入音频数据 //4.循环调用 QISRGetResult(...) 接口返回听写结果 //5.调用 QISRSessionEnd(...) 主动结束本次听写 //6.不再使用服务的时候 调用MSPLogout()登出,避免不必要的麻烦。 try { //识别结果 string text = String.Empty; //登录参数,自己注册后获取的appid string login_configs = "appid=5983daf6"; //语音路径 var voicePath = AppDomain.CurrentDomain.BaseDirectory + filename; //检测文件是否存在 if (!File.Exists(voicePath)) { MessageBox.Show("文件" + voicePath + "不存在!"); } //读取音频文件 using (FileStream fileStream = new FileStream(voicePath, FileMode.OpenOrCreate)) { IntPtr intPtr = Marshal.AllocHGlobal(BUFFER_NUM); byte[] array = new byte[BUFFER_NUM]; LoadingHelper.ShowLoading("加载中", this, o => { AudioStatus audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_CONTINUE; EpStatus epStatus = EpStatus.MSP_EP_LOOKING_FOR_READY; RsltStatus recogStatus = RsltStatus.MSP_REC_STATUS_FOR_READY; //MSPLogin(...)接口登入 this.BeginInvoke(updateStatus, "登录接口"); ret = IFYDll.MSPLogin("*****@*****.**", "jkljlk123", login_configs); if (ret != (int)ErrorCode.MSP_SUCCESS) { return; } //QISRSessionBegin 开始一次语音识别 this.BeginInvoke(updateStatus, "开始一次语音识别"); string _params = $"domain=iat,sub=iat,aue=speex-wb;7,sample_rate=16000,result_type=plain"; session_ID = IFYDll.QISRSessionBegin(null, _params, ref ret); if (ret != (int)ErrorCode.MSP_SUCCESS) { return; } //QISRAudioWrite 写入本次识别的音频。 this.BeginInvoke(updateStatus, "分块写入识别的音频"); while (fileStream.Position != fileStream.Length) { int waveLen = fileStream.Read(array, 0, BUFFER_NUM); Marshal.Copy(array, 0, intPtr, array.Length); ret = IFYDll.QISRAudioWrite(Ptr2Str(session_ID), intPtr, (uint)waveLen, audioStatus, ref epStatus, ref recogStatus); if (ret != 0) { fileStream.Close(); throw new Exception("QISRAudioWrite err,errCode=" + ret); } Thread.Sleep(500); } this.BeginInvoke(updateStatus, "写入最后一块音频"); audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_LAST; ret = IFYDll.QISRAudioWrite(Ptr2Str(session_ID), intPtr, 1u, audioStatus, ref epStatus, ref recogStatus); if (ret != 0) { throw new Exception("QISRAudioWrite write last audio err,errCode=" + ret); } //QISRGetResult 读取识别结果 this.BeginInvoke(updateStatus, "读取识别结果"); while (true) { IntPtr intPtr2 = IFYDll.QISRGetResult(Ptr2Str(session_ID), ref recogStatus, waitTime, ref ret); if (intPtr2 != IntPtr.Zero) { text += Ptr2Str(intPtr2); } if (ret != 0) { break; } Thread.Sleep(500); if (recogStatus == RsltStatus.MSP_REC_STATUS_COMPLETE) { break; } } }); txtLocalVoiceRecognitionResult.Text = text; } } catch (Exception ex) { txtLocalVoiceRecognitionResult.Text = ex.Message; } finally { //主动结束本次语音识别 this.BeginInvoke(updateStatus, "结束本次识别结果"); ret = IFYDll.QISRSessionEnd(Ptr2Str(session_ID), ""); //退出登录 this.BeginInvoke(updateStatus, "退出登录"); ret = IFYDll.MSPLogout(); } Thread.Sleep(3000); this.BeginInvoke(updateStatus, "就绪"); }
/// <summary> /// 进行语音识别 /// </summary> /// <param name="inFile"></param> /// <returns></returns> public string AudioToString(string inFile) { int ret = 0; string text = String.Empty; FileStream fileStream = new FileStream(inFile, FileMode.OpenOrCreate); byte[] array = new byte[BUFFER_NUM]; IntPtr intPtr = Marshal.AllocHGlobal(BUFFER_NUM); AudioStatus audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_CONTINUE; EpStatus epStatus = EpStatus.MSP_EP_LOOKING_FOR_READY; RsltStatus recogStatus = RsltStatus.MSP_REC_STATUS_FOR_READY; RsltStatus rsltStatus = RsltStatus.MSP_REC_STATUS_FOR_READY; while (fileStream.Position != fileStream.Length) { int waveLen = fileStream.Read(array, 0, BUFFER_NUM); Marshal.Copy(array, 0, intPtr, array.Length); ret = IFYDll.QISRAudioWrite(Ptr2Str(session_ID), intPtr, (uint)waveLen, audioStatus, ref epStatus, ref recogStatus); if (ret != 0) { fileStream.Close(); throw new Exception("QISRAudioWrite err,errCode=" + ret); } if (recogStatus == 0) { IntPtr intPtr2 = IFYDll.QISRGetResult(Ptr2Str(session_ID), ref rsltStatus, 0, ref ret); if (intPtr2 != IntPtr.Zero) { text += Ptr2Str(intPtr2); } } Thread.Sleep(500); } fileStream.Close(); audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_LAST; ret = IFYDll.QISRAudioWrite(Ptr2Str(session_ID), intPtr, 1u, audioStatus, ref epStatus, ref recogStatus); if (ret != 0) { throw new Exception("QISRAudioWrite write last audio err,errCode=" + ret); } int timesCount = 0; while (true) { IntPtr intPtr2 = IFYDll.QISRGetResult(Ptr2Str(session_ID), ref rsltStatus, 0, ref ret); if (intPtr2 != IntPtr.Zero) { text += Ptr2Str(intPtr2); } if (ret != 0) { break; } Thread.Sleep(200); if (rsltStatus == RsltStatus.MSP_REC_STATUS_COMPLETE || timesCount++ >= 50) { break; } } return(text); }
public static extern IntPtr QISEGetResult(string sessionID, ref uint rsltLen, ref RsltStatus rsltStatus, ref int errorCode);
private void ThreadStart() { ErrorCode errorCode = ErrorCode.MSP_SUCCESS; AudioStatus audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_FIRST; EpStatus epStatus = EpStatus.MSP_EP_IN_SPEECH; RsltStatus rsltStatus = RsltStatus.MSP_REC_STATUS_SUCCESS; // 开始 IntPtr ptr = Msc.QISRSessionBegin(null, @params, out errorCode); if (errorCode != ErrorCode.MSP_SUCCESS) { Console.WriteLine("开始识别出错:(错误码)" + (int)errorCode); Account.Logout(); return; } int maxLength = 20480; int tims = m_Datas.Length / maxLength; if ((m_Datas.Length % maxLength) != 0) { tims++; } for (int i = 0; i < tims; i++) { if (i == 0) { audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_FIRST; } else if (i == tims - 1) { audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_LAST; } else { audioStatus = AudioStatus.MSP_AUDIO_SAMPLE_CONTINUE; } byte[] by = null; if ((m_Datas.Length - maxLength * i) >= maxLength) { by = new byte[maxLength]; } else { by = new byte[(m_Datas.Length - maxLength * i)]; } by = m_Datas.Skip(i * maxLength).Take(by.Length).ToArray(); ErrorCode errorCode1 = Msc.QISRAudioWrite(ptr, by, (uint)by.Length, audioStatus, out epStatus, out rsltStatus); if (errorCode1 != ErrorCode.MSP_SUCCESS) { Console.WriteLine("音频数据写入失败:(错误码)" + (int)errorCode1); Account.Logout(); return; } } RsltStatus status = RsltStatus.MSP_REC_STATUS_INCOMPLETE; ErrorCode errorCode2 = ErrorCode.MSP_SUCCESS; StringBuilder msg = new StringBuilder(); while (status != RsltStatus.MSP_REC_STATUS_COMPLETE) { IntPtr data = Msc.QISRGetResult(ptr, out status, 5000, out errorCode2); if (errorCode2 != ErrorCode.MSP_SUCCESS) { Console.WriteLine("获取失败:(错误码)" + (int)errorCode2); Account.Logout(); return; } if (data != null) { msg.Append(Marshal.PtrToStringAnsi(data)); } Thread.Sleep(200); } ErrorCode errorCode3 = Msc.QISRSessionEnd(ptr, "识别结束"); if (errorCode3 != ErrorCode.MSP_SUCCESS) { Console.WriteLine("结束失败:(错误码)" + (int)errorCode3); } Data = msg.ToString(); isDown = true; }