前奏,渾渾噩噩已經工做一年多,這一年多收穫仍是挺多的。逛園子應該有兩年多了,工做後基本上是每天都會來園子逛逛,園子 裏仍是有不少牛人寫了一些不錯的博客,幫我解決不少問題。可是一直沒寫過博客,歸根到底一個字「懶」,還有就是不知道該寫 些什麼...
今天把我最近研究訊飛語音東東,分享一下,不過有些仍是前輩們提供的。以前公司讓我作一個小的語音識別功能,一開始我就建議使用訊飛語音,我的以爲訊飛識別正確率仍是可觀的。但是老總說不能考 慮聯網,還有就是錢的問題。想到微軟自帶語音識別引擎(基於win7)。第一次接觸到語音識別,沒什麼頭緒,只有收集相關資料 。最後成品出來了,可是識別效果不是那麼滿意,老總說那就將就用吧,我想他都那樣說了,我也沒多大意見...開年後老總老總 買了個iphone5玩了siri後,以爲咱們如今那個語音太醜陋了,讓換一個解決方案,識別率要達到90%。國內有好幾家公司作語音識 別的好比科大訊飛、雲知聲、捷通華聲以及紫冬銳意語音都作了必定開放。市面上我知道語音助手有百度語音助手、蟲洞語音助手 、360語音助手以及科大訊飛語點;前兩個我不知道採用那家公司的仍是本身研發的不過都沒開開放,360語音助手採用訊飛的。然 後我就繼續提議使用訊飛語音SDK,因而乎同事們都下載訊飛語點來玩玩,老總說那就試試訊飛語音SDK。
先作一個簡單demo,看看識別效果,感受識別率上可以知足要求。通常要的結果不光只是要把所說的話翻譯成文字,而是須要的是 語義的理解:例如我要去北京,直接返回北京這個關鍵。目前訊飛還沒把這個接口開放出來,公司負責人說今年會把這個開放出來 。那如今只能使用關鍵詞識別語法,一種是直接是文本詞庫;另外一種是ABNF語法。ABNF寫法有點煩雜(語法文件裏使用到的詞句都是指定的,對於沒法枚舉的詞句暫時沒有很好的解決辦法。),就直接採用文本詞庫(由於關鍵詞有點多)。訊飛還有專門人負責關於訊飛語音問題解答(QQ羣:153789256)。html
訊飛提供msc.dll這個DLL,調用DLL的封裝:前端
/// <summary> /// MSCDLL入口封裝 /// </summary> private class MscDll { #region MscDLL /// <summary> /// 初始化MSC的ISR部分 /// </summary> /// <param name="configs">初始化時傳入的字符串,以指定合成用到的一些配置參數,各個參數以「參數名=參數值」的形式出現,大小寫不敏感,不一樣的參數之間以「,」或「\n」隔開,不設置任何值時能夠傳入NULL或空串:</param> /// <returns>若是函數調用成功返回MSP_SUCCESS,不然返回錯誤代碼,錯誤代碼參見msp_errors</returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern int QISRInit(string configs); /// <summary> /// 開始一個ISR會話 /// </summary> /// <param name="grammarList">uri-list格式的語法,能夠是一個語法文件的URL或者一個引擎內置語法列表。能夠同時指定多個語法,不一樣的語法之間以「,」 /// 隔開。進行語音聽寫時不須要語法,此參數設定爲NULL或空串便可;進行語音識別時則須要語法,語法能夠在此參數中指定,也能夠隨後調用QISRGrammarActivate指定識別所用的語法。</param> /// <param name="_params">本路ISR會話使用的參數,可設置的參數及其取值範圍請參考《可設置參數列表_MSP20.xls》,各個參數以「參數名=參數值」 的形式出現,不一樣的參數之間以「,」或者「\n」隔開。</param> /// <param name="errorCode">若是函數調用成功則其值爲MSP_SUCCESS,不然返回錯誤代碼,錯誤代碼參見msp_errors。幾個主要的返回值: MSP_ERROR_NOT_INIT 未初始化 MSP_ERROR_INVALID_PARA 無效的參數; MSP_ERROR_NO_LICENSE 開始一路會話失敗</param> /// <returns>MSC爲本路會話創建的ID,用來惟一的標識本路會話,供之後調用其餘函數時使用。函數調用失敗則會返回NULL。</returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern IntPtr QISRSessionBegin(string grammarList, string _params, ref int errorCode); /// <summary> /// 傳入語法 /// </summary> /// <param name="sessionID">由QISRSessionBegin返回過來的會話ID</param> /// <param name="grammar">語法字符串</param> /// <param name="type">語法類型,能夠是uri-list、abnf、xml等</param> /// <param name="weight">本次傳入語法的權重,本參數在MSP 2.0中會被忽略。</param> /// <returns>若是函數調用成功返回MSP_SUCCESS,不然返回錯誤代碼,錯誤代碼參見msp_errors</returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern int QISRGrammarActivate(string sessionID, string grammar, string type, int weight); /// <summary> /// 寫入用來識別的語音 /// </summary> /// <param name="sessionID">由QISRSessionBegin返回過來的會話ID</param> /// <param name="waveData">音頻數據緩衝區起始地址</param> /// <param name="waveLen">音頻數據長度,其大小不能超過設定的max_audio_size</param> /// <param name="audioStatus">用來指明用戶本次識別的音頻是否發送完畢,可能值以下: /// MSP_AUDIO_SAMPLE_FIRST = 1 第一塊音頻 /// MSP_AUDIO_SAMPLE_CONTINUE = 2 還有後繼音頻 /// MSP_AUDIO_SAMPLE_LAST = 4 最後一塊音頻</param> /// <param name="epStatus">端點檢測(End-point detected)器所處的狀態,可能的值以下: /// MSP _EP_LOOKING_FOR_SPEECH = 0 尚未檢測到音頻的前端點。 /// MSP _EP_IN_SPEECH = 1 已經檢測到了音頻前端點,正在進行正常的音頻處理。 /// MSP _EP_AFTER_SPEECH = 3 檢測到音頻的後端點,後繼的音頻會被MSC忽略。 /// MSP _EP_TIMEOUT = 4 超時。 /// MSP _EP_ERROR= 5 出現錯誤。 /// MSP _EP_MAX_SPEECH = 6 音頻過大。</param> /// <param name="recogStatus">識別器所處的狀態</param> /// <returns></returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern int QISRAudioWrite(string sessionID, byte[] waveData, uint waveLen, AudioStatus audioStatus, ref EpStatus epStatus, ref RecogStatus recogStatus); /// <summary> /// 獲取識別結果 /// </summary> /// <param name="sessionID">由QISRSessionBegin返回過來的會話ID</param> /// <param name="rsltStatus">識別結果的狀態,其取值範圍和含義請參考QISRAudioWrite的參數recogStatus</param> /// <param name="waitTime">與服務器交互的間隔時間,能夠控制和服務器的交互頻度。單位爲ms,建議取值爲5000</param> /// <param name="errorCode">若是函數調用成功返回MSP_SUCCESS,不然返回錯誤代碼,錯誤代碼參見msp_errors</param> /// <returns>函數執行成功而且獲取到識別結果時返回識別結果,函數執行成功沒有獲取到識別結果時返回NULL</returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern IntPtr QISRGetResult(string sessionID, ref RecogStatus rsltStatus, int waitTime, ref int errorCode); /// <summary> /// 結束一路會話 /// </summary> /// <param name="sessionID">由QISRSessionBegin返回過來的會話ID</param> /// <param name="hints">結束本次會話的緣由描述,用於記錄日誌,便於用戶查閱或者跟蹤某些問題</param> /// <returns></returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern int QISRSessionEnd(string sessionID, string hints); /// <summary> /// 獲取與識別交互相關的參數 /// </summary> /// <param name="sessionID">由QISRSessionBegin返回過來的會話ID</param> /// <param name="paramName">要獲取的參數名稱;支持同時查詢多個參數,查詢多個參數時,參數名稱按「,」 或「\n」分隔開來</param> /// <param name="paramValue">獲取的參數值,以字符串形式返回;查詢多個參數時,參數值之間以「;」分開,不支持的參數將返回空的值</param> /// <param name="valueLen">參數值的長度</param> /// <returns></returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern int QISRGetParam(string sessionID, string paramName, string paramValue, ref uint valueLen); /// <summary> /// 逆初始化MSC的ISR部分 /// </summary> /// <returns></returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern int QISRFini(); /// <summary> /// 上傳用戶自定義詞庫 /// </summary> /// <param name="sessionID">由QISRSessionBegin返回過來的會話ID</param> /// <param name="dataName">詞庫名稱</param> /// <param name="userData">詞庫數據採用是utf8格式</param> /// <param name="lenght">詞庫大小</param> /// <param name="paramValue">參數值</param> /// <param name="errorCode">若是函數調用成功返回MSP_SUCCESS,不然返回錯誤代碼,錯誤代碼參見msp_errors</param> /// <returns>函數執行成功而且返回exID(詞庫編號)</returns> [DllImport("msc.dll", CallingConvention = CallingConvention.StdCall)] public static extern IntPtr QISRUploadData(string sessionID, string dataName, byte[] userData, uint lenght, string paramValue, ref int errorCode); #endregion }
說明一下:「QISRUploadData」(上傳詞庫)這個函數在開發文檔裏面沒的,訊飛遺漏了。後端
具體實現(關鍵詞識別,文本詞庫):服務器
類:MscNetsession
1 #region 定義字段 2 3 //返回錯誤代號 4 private int ret = 0; 5 private RecoErrors Re = null; 6 /// <summary> 7 /// 會話ID 8 /// </summary> 9 private string sess_id = null; 10 /// <summary> 11 /// 參數 12 /// </summary> 13 private string param = null; 14 /// <summary> 15 /// 語法 16 /// </summary> 17 private string grammar = null; 18 //錯誤消息通知託管 19 public delegate void delegdateOnerror(string Msg); 20 private string path = null; 21 /// <summary> 22 /// 識別數據返回的事件 23 /// </summary> 24 public event EventHandler<DataArrivedEventArgs> DataArrived; 25 /// <summary> 26 /// 識別過程結束的事件 27 /// </summary> 28 public event EventHandler ISREnd; 29 /// <summary> 30 /// 正在識別 31 /// </summary> 32 public event EventHandler Spoting; 33 34 #endregion 35 36 #region 構造函數 37 38 /// <summary> 39 /// 構造函數,初始化引擎 40 /// </summary> 41 /// <param name="appid">appid</param> 42 /// <param name="param">參數</param> 43 /// <param name="grammar">語法ID</param> 44 /// <param name="path">路徑</param> 45 public MscNet(string appid, string param, string path, string grammar) 46 { 47 this.path = path; 48 this.param = param; 49 this.grammar = grammar; 50 Re = new RecoErrors(); 51 //引擎初始化,只需初始化一次 52 ret = MscDll.QISRInit("appid=" + appid); 53 try 54 { 55 Re.GetError(ret); 56 } 57 catch (MscException ex) 58 { 59 RaiseError(ex.Message.ToString()); 60 } 61 } 62 #endregion 63 64 #region 公共方法 65 66 /// <summary> 67 /// 開始識別語音 68 /// </summary> 69 /// <param name="buffer">音頻數據</param> 70 public void InterpretVoice(byte[] buffer) 71 { 72 //用來指明用戶本次識別的音頻是否發送完畢 73 AudioStatus audioStatus = AudioStatus.ISR_AUDIO_SAMPLE_LAST; 74 //端點檢測(End-point detected)器所處的狀態 75 EpStatus ep_status = EpStatus.ISR_EP_NULL; 76 //識別器所處的狀態 77 RecogStatus rec_status = RecogStatus.ISR_REC_NULL; 78 //識別結果的狀態 79 RecogStatus rslt_status = RecogStatus.ISR_REC_NULL; 80 Loadgrammar(); 81 int ret = MscDll.QISRAudioWrite(sess_id, buffer, (uint)buffer.Length, audioStatus, ref ep_status, ref rec_status); 82 try 83 { 84 Re.GetError(ret); 85 do 86 { 87 if (rslt_status == RecogStatus.ISR_REC_STATUS_INCOMPLETE) 88 { 89 Spoting(this, new EventArgs());//通知正在識別 90 } 91 IntPtr p = MscDll.QISRGetResult(sess_id, ref rslt_status, 0, ref ret); 92 Re.GetError(ret); 93 if (p != IntPtr.Zero) 94 { 95 string tmp = PtrToStr(p); 96 DataArrived(this, new DataArrivedEventArgs(tmp));//激發識別數據到達事件 97 } 98 System.Threading.Thread.Sleep(500); 99 } while (rslt_status != RecogStatus.ISR_REC_STATUS_SPEECH_COMPLETE); 100 } 101 catch (MscException ex) 102 { 103 RaiseError(ex.Message); 104 } 105 finally 106 { 107 try 108 { 109 ret = MscDll.QISRSessionEnd(sess_id, string.Empty); 110 Re.GetError(ret); 111 ISREnd(this, new EventArgs());//通知識別結束 112 } 113 catch (MscException ex) 114 { 115 RaiseError(ex.Message); 116 } 117 } 118 } 119 120 /// <summary> 121 /// 上傳詞庫詞庫採用是utf8格式 122 /// </summary> 123 /// <param name="txtFile">詞庫名稱</param> 124 /// <param name="path">詞庫路徑</param> 125 /// <param name="param">參數</param> 126 /// <returns>返回詞庫編號</returns> 127 public string GetExID(string txtFile, string path, string param) 128 { 129 string filePath = Path.Combine(path, txtFile); 130 string tmp = string.Empty; 131 if (!string.IsNullOrEmpty(filePath)) 132 { 133 try 134 { 135 sess_id = PtrToStr(MscDll.QISRSessionBegin(null, param, ref ret)); 136 Re.GetError(ret); 137 try 138 { 139 using (FileStream fs = File.Open(filePath, FileMode.Open)) 140 { 141 long len = fs.Length; 142 byte[] buffer = new byte[len]; 143 fs.Read(buffer, 0, (int)len); 144 IntPtr p = MscDll.QISRUploadData(sess_id, "sces", buffer, (uint)fs.Length, "dtt=keylist", ref ret); 145 Re.GetError(ret); 146 if (p != IntPtr.Zero) 147 { 148 tmp = PtrToStr(p); 149 } 150 } 151 } 152 catch (FileNotFoundException ex) 153 { 154 RaiseError(ex.Message); 155 } 156 157 } 158 catch (MscException ex) 159 { 160 RaiseError(ex.Message); 161 } 162 finally 163 { 164 try 165 { 166 ret = MscDll.QISRSessionEnd(sess_id, null); 167 Re.GetError(ret); 168 } 169 catch (MscException ex) 170 { 171 RaiseError(ex.Message.ToString()); 172 } 173 } 174 } 175 else 176 { 177 RaiseError("路徑不正確!"); 178 } 179 return tmp; 180 } 181 182 /// <summary> 183 /// 對MSC的ISR部分進行逆初始化。 184 /// </summary> 185 public void QISRFini() 186 { 187 try 188 { 189 ret = MscDll.QISRFini(); 190 Re.GetError(ret); 191 } 192 catch (MscException ex) 193 { 194 RaiseError(ex.Message.ToString()); 195 } 196 } 197 198 #endregion 199 200 #region 受保護方法 201 /// <summary> 202 /// 加載語法 203 /// </summary> 204 private void Loadgrammar() 205 { 206 try 207 { 208 sess_id = PtrToStr(MscDll.QISRSessionBegin(grammar, param, ref ret)); 209 Re.GetError(ret); 210 } 211 catch (MscException ex) 212 { 213 RaiseError(ex.Message); 214 } 215 } 216 217 /// <summary> 218 /// 指針轉字符串 219 /// </summary> 220 /// <param name="p">指向非託管代碼字符串的指針</param> 221 /// <returns>返回指針指向的字符串</returns> 222 private string PtrToStr(IntPtr p) 223 { 224 List<byte> lb = new List<byte>(); 225 try 226 { 227 while (Marshal.ReadByte(p) != 0) 228 { 229 lb.Add(Marshal.ReadByte(p)); 230 p = p + 1; 231 } 232 } 233 catch (AccessViolationException ex) 234 { 235 RaiseError(ex.Message); 236 } 237 return Encoding.Default.GetString(lb.ToArray()); 238 } 239 #endregion 240 241 #region 事件 242 /// <summary> 243 /// 錯誤通知事件 244 /// </summary> 245 public event delegdateOnerror OnError; 246 private void RaiseError(string Msg) 247 { 248 if (OnError != null) 249 { 250 OnError(Msg); 251 } 252 } 253 /// <summary> 254 /// 有識別數據返回的事件參數,包含了識別的文本結果 255 /// </summary> 256 public class DataArrivedEventArgs : EventArgs 257 { 258 public string result; 259 public DataArrivedEventArgs(string rs) 260 { 261 result = rs; 262 } 263 } 264 #endregion
若是採用ABNF語法,只是與文本詞庫加載語法方式有點不同:多線程
1 /// <summary> 2 /// 加載語法 3 /// </summary> 4 private void Loadgrammar() 5 { 6 try 7 { 8 9 //sess_id = PtrToStr(MscDll.QISRSessionBegin(grammar, param, ref ret)); 10 /*ABNF語法*/ 11 sess_id = PtrToStr(MscDll.QISRSessionBegin(null, "rst=plain,sub=asr,ssm=1,aue=speex,auf=audio/L16;rate=16000,cfd=350", ref ret)); 12 em.GetError(ret); 13 string grammar1 = "#ABNF 1.0 GB2312;\n mode voice;\n language zh-cn;\n\n\n root $main;\n public $main = 我[想要]看$place1;\n $place1=足球;\n"; 14 ret = MscDll.QISRGrammarActivate(sess_id, grammar1, "abnf", 0);//將語法ID傳入QISRSessionBegin 15 /*end */ 16 em.GetError(ret); 17 } 18 catch (MscException ex) 19 { 20 RaiseError(ex.Message.ToString()); 21 } 22 }
常量的枚舉:app
1 #region 錯誤代號 2 enum ErrorCode 3 { 4 MSP_SUCCESS= 0, 5 MSP_ERROR_FAIL = -1, 6 MSP_ERROR_EXCEPTION = -2, 7 8 /* General errors 10100(0x2774) */ 9 MSP_ERROR_GENERAL = 10100, /* 0x2774 */ 10 MSP_ERROR_OUT_OF_MEMORY = 10101, /* 0x2775 */ 11 MSP_ERROR_FILE_NOT_FOUND = 10102, /* 0x2776 */ 12 MSP_ERROR_NOT_SUPPORT = 10103, /* 0x2777 */ 13 MSP_ERROR_NOT_IMPLEMENT = 10104, /* 0x2778 */ 14 MSP_ERROR_ACCESS = 10105, /* 0x2779 */ 15 MSP_ERROR_INVALID_PARA = 10106, /* 0x277A */ 16 MSP_ERROR_INVALID_PARA_VALUE = 10107, /* 0x277B */ 17 MSP_ERROR_INVALID_HANDLE = 10108, /* 0x277C */ 18 MSP_ERROR_INVALID_DATA = 10109, /* 0x277D */ 19 MSP_ERROR_NO_LICENSE = 10110, /* 0x277E */ 20 MSP_ERROR_NOT_INIT = 10111, /* 0x277F */ 21 MSP_ERROR_NULL_HANDLE = 10112, /* 0x2780 */ 22 MSP_ERROR_OVERFLOW = 10113, /* 0x2781 */ 23 MSP_ERROR_TIME_OUT = 10114, /* 0x2782 */ 24 MSP_ERROR_OPEN_FILE = 10115, /* 0x2783 */ 25 MSP_ERROR_NOT_FOUND = 10116, /* 0x2784 */ 26 MSP_ERROR_NO_ENOUGH_BUFFER = 10117, /* 0x2785 */ 27 MSP_ERROR_NO_DATA = 10118, /* 0x2786 */ 28 MSP_ERROR_NO_MORE_DATA = 10119, /* 0x2787 */ 29 MSP_ERROR_SKIPPED = 10120, /* 0x2788 */ 30 MSP_ERROR_ALREADY_EXIST = 10121, /* 0x2789 */ 31 MSP_ERROR_LOAD_MODULE = 10122, /* 0x278A */ 32 MSP_ERROR_BUSY = 10123, /* 0x278B */ 33 MSP_ERROR_INVALID_CONFIG = 10124, /* 0x278C */ 34 MSP_ERROR_VERSION_CHECK = 10125, /* 0x278D */ 35 MSP_ERROR_CANCELED = 10126, /* 0x278E */ 36 MSP_ERROR_INVALID_MEDIA_TYPE = 10127, /* 0x278F */ 37 MSP_ERROR_CONFIG_INITIALIZE = 10128, /* 0x2790 */ 38 MSP_ERROR_CREATE_HANDLE = 10129, /* 0x2791 */ 39 MSP_ERROR_CODING_LIB_NOT_LOAD = 10130, /* 0x2792 */ 40 41 /* Error codes of network 10200(0x27D8)*/ 42 MSP_ERROR_NET_GENERAL = 10200, /* 0x27D8 */ 43 MSP_ERROR_NET_OPENSOCK = 10201, /* 0x27D9 */ /* Open socket */ 44 MSP_ERROR_NET_CONNECTSOCK = 10202, /* 0x27DA */ /* Connect socket */ 45 MSP_ERROR_NET_ACCEPTSOCK = 10203, /* 0x27DB */ /* Accept socket */ 46 MSP_ERROR_NET_SENDSOCK = 10204, /* 0x27DC */ /* Send socket data */ 47 MSP_ERROR_NET_RECVSOCK = 10205, /* 0x27DD */ /* Recv socket data */ 48 MSP_ERROR_NET_INVALIDSOCK = 10206, /* 0x27DE */ /* Invalid socket handle */ 49 MSP_ERROR_NET_BADADDRESS = 10207, /* 0x27EF */ /* Bad network address */ 50 MSP_ERROR_NET_BINDSEQUENCE = 10208, /* 0x27E0 */ /* Bind after listen/connect */ 51 MSP_ERROR_NET_NOTOPENSOCK = 10209, /* 0x27E1 */ /* Socket is not opened */ 52 MSP_ERROR_NET_NOTBIND = 10210, /* 0x27E2 */ /* Socket is not bind to an address */ 53 MSP_ERROR_NET_NOTLISTEN = 10211, /* 0x27E3 */ /* Socket is not listenning */ 54 MSP_ERROR_NET_CONNECTCLOSE = 10212, /* 0x27E4 */ /* The other side of connection is closed */ 55 MSP_ERROR_NET_NOTDGRAMSOCK = 10213, /* 0x27E5 */ /* The socket is not datagram type */ 56 MSP_ERROR_NET_DNS=10214, 57 /* Error codes of mssp message 10300(0x283C) */ 58 MSP_ERROR_MSG_GENERAL = 10300, /* 0x283C */ 59 MSP_ERROR_MSG_PARSE_ERROR = 10301, /* 0x283D */ 60 MSP_ERROR_MSG_BUILD_ERROR = 10302, /* 0x283E */ 61 MSP_ERROR_MSG_PARAM_ERROR = 10303, /* 0x283F */ 62 MSP_ERROR_MSG_CONTENT_EMPTY = 10304, /* 0x2840 */ 63 MSP_ERROR_MSG_INVALID_CONTENT_TYPE = 10305, /* 0x2841 */ 64 MSP_ERROR_MSG_INVALID_CONTENT_LENGTH = 10306, /* 0x2842 */ 65 MSP_ERROR_MSG_INVALID_CONTENT_ENCODE = 10307, /* 0x2843 */ 66 MSP_ERROR_MSG_INVALID_KEY = 10308, /* 0x2844 */ 67 MSP_ERROR_MSG_KEY_EMPTY = 10309, /* 0x2845 */ 68 MSP_ERROR_MSG_SESSION_ID_EMPTY = 10310, /* 0x2846 */ 69 MSP_ERROR_MSG_LOGIN_ID_EMPTY = 10311, /* 0x2847 */ 70 MSP_ERROR_MSG_SYNC_ID_EMPTY = 10312, /* 0x2848 */ 71 MSP_ERROR_MSG_APP_ID_EMPTY = 10313, /* 0x2849 */ 72 MSP_ERROR_MSG_EXTERN_ID_EMPTY = 10314, /* 0x284A */ 73 MSP_ERROR_MSG_INVALID_CMD = 10315, /* 0x284B */ 74 MSP_ERROR_MSG_INVALID_SUBJECT = 10316, /* 0x284C */ 75 MSP_ERROR_MSG_INVALID_VERSION = 10317, /* 0x284D */ 76 MSP_ERROR_MSG_NO_CMD = 10318, /* 0x284E */ 77 MSP_ERROR_MSG_NO_SUBJECT = 10319, /* 0x284F */ 78 MSP_ERROR_MSG_NO_VERSION = 10320, /* 0x2850 */ 79 MSP_ERROR_MSG_MSSP_EMPTY = 10321, /* 0x2851 */ 80 MSP_ERROR_MSG_NEW_RESPONSE = 10322, /* 0x2852 */ 81 MSP_ERROR_MSG_NEW_CONTENT = 10323, /* 0x2853 */ 82 MSP_ERROR_MSG_INVALID_SESSION_ID = 10324, /* 0x2854 */ 83 84 /* Error codes of DataBase 10400(0x28A0)*/ 85 MSP_ERROR_DB_GENERAL = 10400, /* 0x28A0 */ 86 MSP_ERROR_DB_EXCEPTION = 10401, /* 0x28A1 */ 87 MSP_ERROR_DB_NO_RESULT = 10402, /* 0x28A2 */ 88 MSP_ERROR_DB_INVALID_USER = 10403, /* 0x28A3 */ 89 MSP_ERROR_DB_INVALID_PWD = 10404, /* 0x28A4 */ 90 MSP_ERROR_DB_CONNECT = 10405, /* 0x28A5 */ 91 MSP_ERROR_DB_INVALID_SQL = 10406, /* 0x28A6 */ 92 MSP_ERROR_DB_INVALID_APPID = 10407, /* 0x28A7 */ 93 94 /* Error codes of Resource 10500(0x2904)*/ 95 MSP_ERROR_RES_GENERAL = 10500, /* 0x2904 */ 96 MSP_ERROR_RES_LOAD = 10501, /* 0x2905 */ /* Load resource */ 97 MSP_ERROR_RES_FREE = 10502, /* 0x2906 */ /* Free resource */ 98 MSP_ERROR_RES_MISSING = 10503, /* 0x2907 */ /* Resource File Missing */ 99 MSP_ERROR_RES_INVALID_NAME = 10504, /* 0x2908 */ /* Invalid resource file name */ 100 MSP_ERROR_RES_INVALID_ID = 10505, /* 0x2909 */ /* Invalid resource ID */ 101 MSP_ERROR_RES_INVALID_IMG = 10506, /* 0x290A */ /* Invalid resource image pointer */ 102 MSP_ERROR_RES_WRITE = 10507, /* 0x290B */ /* Write read-only resource */ 103 MSP_ERROR_RES_LEAK = 10508, /* 0x290C */ /* Resource leak out */ 104 MSP_ERROR_RES_HEAD = 10509, /* 0x290D */ /* Resource head currupt */ 105 MSP_ERROR_RES_DATA = 10510, /* 0x290E */ /* Resource data currupt */ 106 MSP_ERROR_RES_SKIP = 10511, /* 0x290F */ /* Resource file skipped */ 107 108 /* Error codes of TTS 10600(0x2968)*/ 109 MSP_ERROR_TTS_GENERAL = 10600, /* 0x2968 */ 110 MSP_ERROR_TTS_TEXTEND = 10601, /* 0x2969 */ /* Meet text end */ 111 MSP_ERROR_TTS_TEXT_EMPTY = 10602, /* 0x296A */ /* no synth text */ 112 113 /* Error codes of Recognizer 10700(0x29CC) */ 114 MSP_ERROR_REC_GENERAL = 10700, /* 0x29CC */ 115 MSP_ERROR_REC_INACTIVE = 10701, /* 0x29CD */ 116 MSP_ERROR_REC_GRAMMAR_ERROR = 10702, /* 0x29CE */ 117 MSP_ERROR_REC_NO_ACTIVE_GRAMMARS = 10703, /* 0x29CF */ 118 MSP_ERROR_REC_DUPLICATE_GRAMMAR = 10704, /* 0x29D0 */ 119 MSP_ERROR_REC_INVALID_MEDIA_TYPE = 10705, /* 0x29D1 */ 120 MSP_ERROR_REC_INVALID_LANGUAGE = 10706, /* 0x29D2 */ 121 MSP_ERROR_REC_URI_NOT_FOUND = 10707, /* 0x29D3 */ 122 MSP_ERROR_REC_URI_TIMEOUT = 10708, /* 0x29D4 */ 123 MSP_ERROR_REC_URI_FETCH_ERROR = 10709, /* 0x29D5 */ 124 125 /* Error codes of Speech Detector 10800(0x2A30) */ 126 MSP_ERROR_EP_GENERAL = 10800, /* 0x2A30 */ 127 MSP_ERROR_EP_NO_SESSION_NAME = 10801, /* 0x2A31 */ 128 MSP_ERROR_EP_INACTIVE = 10802, /* 0x2A32 */ 129 MSP_ERROR_EP_INITIALIZED = 10803, /* 0x2A33 */ 130 131 /* Error codes of TUV */ 132 MSP_ERROR_TUV_GENERAL = 10900, /* 0x2A94 */ 133 MSP_ERROR_TUV_GETHIDPARAM = 10901, /* 0x2A95 */ /* Get Busin Param huanid*/ 134 MSP_ERROR_TUV_TOKEN = 10902, /* 0x2A96 */ /* Get Token */ 135 MSP_ERROR_TUV_CFGFILE = 10903, /* 0x2A97 */ /* Open cfg file */ 136 MSP_ERROR_TUV_RECV_CONTENT = 10904, /* 0x2A98 */ /* received content is error */ 137 MSP_ERROR_TUV_VERFAIL = 10905, /* 0x2A99 */ /* Verify failure */ 138 139 /* Error codes of IMTV */ 140 MSP_ERROR_IMTV_SUCCESS = 11000, /* 0x2AF8 */ /* 成功 */ 141 MSP_ERROR_IMTV_NO_LICENSE = 11001, /* 0x2AF9 */ /* 試用次數結束,用戶須要付費 */ 142 MSP_ERROR_IMTV_SESSIONID_INVALID = 11002, /* 0x2AFA */ /* SessionId失效,須要從新登陸通行證 */ 143 MSP_ERROR_IMTV_SESSIONID_ERROR = 11003, /* 0x2AFB */ /* SessionId爲空,或者非法 */ 144 MSP_ERROR_IMTV_UNLOGIN = 11004, /* 0x2AFC */ /* 未登陸通行證 */ 145 MSP_ERROR_IMTV_SYSTEM_ERROR = 11005, /* 0x2AFD */ /* 系統錯誤 */ 146 147 /* Error codes of HCR */ 148 MSP_ERROR_HCR_GENERAL = 11100, 149 MSP_ERROR_HCR_RESOURCE_NOT_EXIST = 11101, 150 151 /* Error codes of http 12000(0x2EE0) */ 152 MSP_ERROR_HTTP_BASE = 12000, /* 0x2EE0 */ 153 154 /*Error codes of ISV */ 155 MSP_ERROR_ISV_NO_USER = 13000, /* 32C8 */ /* the user doesn't exist */ 156 } 157 #endregion 158 159 #region ISR枚舉常量 160 public enum AudioStatus 161 { 162 ISR_AUDIO_SAMPLE_INIT = 0x00, 163 ISR_AUDIO_SAMPLE_FIRST = 0x01, 164 ISR_AUDIO_SAMPLE_CONTINUE = 0x02, 165 ISR_AUDIO_SAMPLE_LAST = 0x04, 166 ISR_AUDIO_SAMPLE_SUPPRESSED = 0x08, 167 ISR_AUDIO_SAMPLE_LOST = 0x10, 168 ISR_AUDIO_SAMPLE_NEW_CHUNK = 0x20, 169 ISR_AUDIO_SAMPLE_END_CHUNK = 0x40, 170 171 ISR_AUDIO_SAMPLE_VALIDBITS = 0x7f /* to validate the value of sample->status */ 172 } 173 174 public enum EpStatus 175 { 176 ISR_EP_NULL = -1, 177 ISR_EP_LOOKING_FOR_SPEECH = 0, ///尚未檢測到音頻的前端點 178 ISR_EP_IN_SPEECH = 1, ///已經檢測到了音頻前端點,正在進行正常的音頻處理。 179 ISR_EP_AFTER_SPEECH = 3, ///檢測到音頻的後端點,後繼的音頻會被MSC忽略。 180 ISR_EP_TIMEOUT = 4, ///超時 181 ISR_EP_ERROR = 5, ///出現錯誤 182 ISR_EP_MAX_SPEECH = 6 ///音頻過大 183 } 184 185 public enum RecogStatus 186 { 187 ISR_REC_NULL = -1, 188 ISR_REC_STATUS_SUCCESS = 0, ///識別成功,此時用戶能夠調用QISRGetResult來獲取(部分)結果。 189 ISR_REC_STATUS_NO_MATCH = 1, ///識別結束,沒有識別結果 190 ISR_REC_STATUS_INCOMPLETE = 2, ///正在識別中 191 ISR_REC_STATUS_NON_SPEECH_DETECTED = 3, ///保留 192 ISR_REC_STATUS_SPEECH_DETECTED = 4, ///發現有效音頻 193 ISR_REC_STATUS_SPEECH_COMPLETE = 5, ///識別結束 194 ISR_REC_STATUS_MAX_CPU_TIME = 6, ///保留 195 ISR_REC_STATUS_MAX_SPEECH = 7, ///保留 196 ISR_REC_STATUS_STOPPED = 8, ///保留 197 ISR_REC_STATUS_REJECTED = 9, ///保留 198 ISR_REC_STATUS_NO_SPEECH_FOUND = 10 ///沒有發現音頻 199 } 200 #endregion 201 }
自定義異常:iphone
1 [Serializable] //聲明爲可序列化的 由於要寫入文件中 2 public class MscException : ApplicationException//由用戶程序引起,用於派生自定義的異常類型 3 { 4 /// <summary> 5 /// 默認構造函數 6 /// </summary> 7 public MscException() { } 8 public MscException(string message) 9 : base(message) { } 10 public MscException(string message, Exception inner) 11 : base(message, inner) { } 12 } 13 /// <summary> 14 /// 是否出錯 15 /// </summary> 16 internal class RecoErrors 17 { 18 public RecoErrors() { } 19 /// <summary> 20 /// 是否發生錯誤. 21 /// </summary> 22 /// <param name="id">錯誤ID</param> 23 public virtual void GetError(int id) 24 { 25 if (id != 0) 26 { 27 var ex = new MscException(((ErrorCode)id).ToString("G")); 28 // var ex = new MscException(Enum.GetName(typeof(ErrorCode),id)); 29 throw ex; 30 } 31 } 32 }
訊飛語音支持邊錄邊上傳,不過我這裏採用是一次性上傳。起初我採用的是邊錄邊上傳,不過感受有數字混合後識別正常率很差(還沒跟訊飛那邊溝通。),最後才使用一次性上傳,畢竟語音文件也不是大就200KB一下。訊飛語音識別不支持多線程識別。socket
我作的這個語音識別產品,作成服務端與客戶端。服務端:放在一個能鏈接外網機子上提供語音識別(作了一個簡單隊列),客戶端:將音頻數據採集後發送到局域網內的語音識別服務端進行識別。ide
以上有些代碼是藉助別人的,第一次寫你們儘可能不要吐槽,不過能夠給點意見。你們相互學習...
出處:http://www.cnblogs.com/milian/archive/2013/04/08/3007315.html