標籤:平台 his oba app 商務程序 類庫 錄音 ref tor
本文系原創,禁止轉載。
分享如何使用c#對接科大訊飛聽寫服務,簡單高效地實現聽寫。
實現聽寫主要分為錄音和語音辨識兩部分;錄音是指擷取裝置音效卡連接埠的音頻資料並將之儲存為音頻檔案,語音辨識就是將剛才所述的音頻檔案通過調用訊飛的聽寫服務轉換為文字。
相關的類庫檔案
1. 開源錄音庫 NAudio.dll
http://pan.baidu.com/s/1dFth2nv
2.聽寫庫 msc.dll
去訊飛開放平台申請相關的SDK
錄音部分可以使用開源的.net音頻處理類庫NAudio.dll,它是託管的類庫,使用起來比較方便,當然你也可以自己去讀音效卡錄音,微軟有相關的系統API,這裡不詳述。
錄音部分核心代碼:
1 //初始化 2 String FilePath = AppDomain.CurrentDomain.BaseDirectory + "Temp.wav"; 3 WaveIn m_waveSource = new WaveIn(); 4 m_waveSource.WaveFormat = new NAudio.Wave.WaveFormat(16000, 16, 1);// 16bit,16KHz,Mono的錄音格式 5 m_waveSource.DataAvailable += new EventHandler<WaveInEventArgs>(waveSource_DataAvailable); 6 m_waveSource.RecordingStopped += new EventHandler<StoppedEventArgs>(waveSource_RecordingStopped); 7 WaveFileWriter m_waveFile = new WaveFileWriter(m_fileName, m_waveSource.WaveFormat); 8 9 //開始錄音10 m_waveSource.StartRecording();11 12 //儲存到截獲到的聲音13 private void waveSource_DataAvailable(object sender, WaveInEventArgs e)14 {15 if (m_waveFile != null)16 {17 m_waveFile.Write(e.Buffer, 0, e.BytesRecorded);18 m_waveFile.Flush();19 }20 }21 22 //停止錄音23 m_waveSource.StopRecording();
錄音完成後就可以進行聽寫了,訊飛提供的聽寫服務SDK中的類庫msc.dll是原生的類庫,在c#中沒有辦法像託管類庫那樣使用,需要通過使用Import的方式來引用,也可以封裝成託管的類庫來使用,這裡只介紹第一種方法。
上述類庫是msc.dll使用C語言封裝的,在聲明介面的時候需注意C語言的變數類型的表達方式與C#有很多不同之處;比如,在SDK中有很多針對記憶體位址操作的,所以涉及到很多的指標類型變數,而C#中指標概念相對較弱。提供兩個解決思路,一是在C#中聲明UnSafe代碼,這樣就可以像C/C++一樣使用指標,二是使用IntPtr、ref 變數的表達方式,來實現“相容”。
相關介面聲明:
1 [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] 2 public static extern int MSPLogin(string usr, string pwd, string @params); 3 4 [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] 5 public static extern IntPtr QISRSessionBegin(string grammarList, string _params, ref int errorCode); 6 7 [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] 8 public static extern int QISRGrammarActivate(string sessionID, string grammar, string type, int weight); 9 10 [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]11 public static extern int QISRAudioWrite(string sessionID, IntPtr waveData, uint waveLen, int audioStatus, ref int epStatus, ref int recogStatus);12 13 [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]14 public static extern IntPtr QISRGetResult(string sessionID, ref int rsltStatus, int waitTime, ref int errorCode);15 16 [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]17 public static extern int QISRSessionEnd(string sessionID, string hints);18 19 [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]20 public static extern int QISRGetParam(string sessionID, string paramName, string paramValue, ref uint valueLen);21 22 [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)]23 public static extern int MSPLogout();
商務程序:
1.調用 MSPLogin(...)介面登入,可以只登入一次,但是必須保證在調用其他介面前先登入;
2.調用 QISRSessionBegin(...)開始一次聽寫;
3.調用 QISRAudioWrite(...) 分塊寫入音頻資料
4.迴圈調用 QISRGetResult(...) 介面返回聽寫結果
5.調用 QISRSessionEnd(...) 主動結束本次聽寫
6.不再使用服務的時候 調用MSPLogout()登出,避免不必要的麻煩。
核心代碼:
public string AudioToString(string inFile) { int ret = 0; 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 = 2; int epStatus = -1; int recogStatus = -1; int rsltStatus = -1; while (fileStream.Position != fileStream.Length) { int waveLen = fileStream.Read(array, 0, this.BUFFER_NUM); Marshal.Copy(array, 0, intPtr, array.Length); ret = iFlyASR.QISRAudioWrite(this.m_sessionID, 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 = iFlyASR.QISRGetResult(this.m_sessionID, ref rsltStatus, 0, ref ret); if (intPtr2 != IntPtr.Zero) { text += this.Ptr2Str(intPtr2); } } Thread.Sleep(500); } fileStream.Close(); audioStatus = 4; ret = iFlyASR.QISRAudioWrite(this.m_sessionID, 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 = iFlyASR.QISRGetResult(this.m_sessionID, ref rsltStatus, 0, ref ret); if (intPtr2 != IntPtr.Zero) { text += this.Ptr2Str(intPtr2); } if (ret != 0) { break; } Thread.Sleep(200); if (rsltStatus == 5 || timesCount++ >= 50) { break; } } return text; }
自己設計以下UI互動,或者和你的應用程式結合一下,就可以讓你的應用程式長一雙會聽的耳朵了!
結果:
C# 實現聽寫