Esempio n. 1
0
        /// <summary>
        /// 获取语法的ID
        /// </summary>
        /// <returns></returns>
        private string GetGrammarID()
        {
            int    ret  = -1;
            string temp = Application.dataPath;

#if UNITY_ANDROID
            temp = Application.persistentDataPath + "/gm_continuous_digit.abnf";
#elif UNITY_STANDALONE_WIN
            temp = Application.streamingAssetsPath + "/gm_continuous_digit.abnf";
#endif

            byte[] grammarBytes = Utils.ReadFile(temp);

            int grammar_len = grammarBytes.Length;

            IntPtr ptrGrammarID = DllImports.MSPUploadData("usergram", grammarBytes, (uint)grammar_len, "dtt = abnf, sub = asr", out ret);
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                Utils.CustomPrint("MSPUploadData error, errCode=" + ((ErrorCode)ret).ToString("G"));
                return(null);
            }
            string grammarID = Marshal.PtrToStringAnsi(ptrGrammarID);
            Utils.CustomPrint("grammarID:" + grammarID + "\r\n");
            return(grammarID);
        }
Esempio n. 2
0
 /// <summary>
 /// 处理错误
 /// </summary>
 /// <param name="errorMsg">错误的函数</param>
 /// <param name="ret">错误的返回值</param>
 /// <param name="sessionID">sessionID</param>
 /// <param name="fs">打开的文件</param>
 private void HandleErrorMsg(string errorMsg, int ret, string sessionID, FileStream fs)
 {
     Utils.CustomPrint(errorMsg + " err,errCode=" + ((ErrorCode)ret).ToString("G"));
     DllImports.QISRSessionEnd(sessionID, errorMsg);
     if (fs != null)
     {
         fs.Close();
         fs = null;
     }
 }
Esempio n. 3
0
 /// <summary>
 /// 处理错误
 /// </summary>
 /// <param name="errorMsg">错误的函数</param>
 /// <param name="ret">错误的返回值</param>
 /// <param name="sessionID">sessionID</param>
 /// <param name="writer">打开的文件</param>
 /// <param name="fs">打开的文件</param>
 private static void HandleErrorMsg(string errorMsg, int ret, string sessionID, BinaryWriter writer, FileStream fs)
 {
     Utils.CustomPrint(errorMsg + " err,errCode=" + ((ErrorCode)ret).ToString("G"));
     DllImports.QTTSSessionEnd(sessionID, errorMsg);
     if (writer != null)
     {
         writer.Close();
         writer = null;
     }
     if (fs != null)
     {
         fs.Close();
         fs = null;
     }
 }
Esempio n. 4
0
        /// <summary>
        /// 运行语音合成功能
        /// </summary>
        /// <returns></returns>
        public IEnumerator RunTTS()
        {
            if (text == null)
            {
                yield break;
            }

            WaveFormat waveFormat         = new WaveFormat();
            int        nLength            = 0;
            int        nFormatChunkLength = 0x10; // Format chunk length.
            short      shPad = 1;                 // File padding

            int  ret         = 0;
            uint audioLen    = 0;
            int  sampleCount = 0;

            int synthStatus = (int)TTSStatus.MSP_TTS_FLAG_STILL_HAVE_DATA;

            IntPtr ptrSessionID = DllImports.QTTSSessionBegin(sessionTTSBeginParams, out ret);
            string sessionID    = Marshal.PtrToStringAnsi(ptrSessionID);

            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                Utils.CustomPrint("TTSSessionBegin failed, errCode=" + ((ErrorCode)ret).ToString("G"));
                yield break;
            }

            FileStream   waveFile = new FileStream(textPath, FileMode.OpenOrCreate);
            BinaryWriter writer   = new BinaryWriter(waveFile);

            char[] chunkRiff = { 'R', 'I', 'F', 'F' };
            char[] chunkType = { 'W', 'A', 'V', 'E' };
            char[] chunkFmt  = { 'f', 'm', 't', ' ' };
            char[] chunkData = { 'd', 'a', 't', 'a' };

            //RIFF块
            writer.Write(chunkRiff);
            writer.Write(nLength);
            writer.Write(chunkType);

            //WAVE块
            writer.Write(chunkFmt);
            writer.Write(nFormatChunkLength);
            writer.Write(shPad);
            writer.Write(waveFormat.mChannels);
            writer.Write(waveFormat.mSamplesPerSecond);
            writer.Write(waveFormat.mAverageBytesPerSecond);
            writer.Write(waveFormat.mBlockAlign);
            writer.Write(waveFormat.mBitsPerSample);

            //数据块
            writer.Write(chunkData);
            writer.Write((int)0);   // The sample length will be written in later.

            ret = DllImports.QTTSTextPut(sessionID, text, (uint)text.Length, null);
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                HandleErrorMsg("QTTSTextPut", ret, sessionID, writer, waveFile);
                yield break;
            }

            Utils.CustomPrint("正在合成 ...\n");

            while (true)
            {
                ///获取合成音频
                IntPtr data = DllImports.QTTSAudioGet(sessionID, ref audioLen, ref synthStatus, out ret);
                if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
                {
                    break;
                }
                if (IntPtr.Zero != data)
                {
                    byte[] buff = new byte[audioLen];
                    Marshal.Copy(data, buff, 0, buff.Length);
                    writer.Write(buff, 0, buff.Length);
                    sampleCount += (int)audioLen;///计算data_size大小
                    buff         = null;
                }
                if (TTSStatus.MSP_TTS_FLAG_DATA_END == (TTSStatus)synthStatus)
                {
                    break;
                }
                Utils.CustomPrint(">");
                yield return(new WaitForSeconds(0.2f));
            }

            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                Utils.CustomPrint("QTTSAudioGet failed, errCode=" + ((ErrorCode)ret).ToString("G"));
                DllImports.QTTSSessionEnd(sessionID, "AudioGetError");
                writer.Close();
                waveFile.Close();
                yield break;
            }

            //写WAV文件尾
            writer.Seek(4, SeekOrigin.Begin);
            writer.Write((int)(sampleCount + 36));
            writer.Seek(40, SeekOrigin.Begin);
            writer.Write(sampleCount);

            writer.Close();
            waveFile.Close();
            writer   = null;
            waveFile = null;

            ///合成完毕
            ret = DllImports.QTTSSessionEnd(sessionID, "Normal");
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                Utils.CustomPrint("QTTSSessionEnd failed, errCode=" + ((ErrorCode)ret).ToString("G"));
            }
            ptrSessionID = IntPtr.Zero;
            Utils.CustomPrint("合成完毕");
            yield break;
        }
Esempio n. 5
0
        /// <summary>
        /// 运行声音识别功能
        /// </summary>
        /// <returns></returns>
        public IEnumerator RunISR()
        {
            ///模拟录音,输入音频
            if (!File.Exists(path))
            {
                Utils.CustomPrint("文件" + path + "不存在!");
                yield break;
            }

            const int BUFFER_NUM = 640 * 10;/// 每次写入200ms音频(16k,16bit):1帧音频20ms,10帧=200ms。16k采样率的16位音频,一帧的大小为640Byte
            int       ret        = 0;
            string    result     = "";
            int       len;
            int       audStatus  = (int)AudioStatus.MSP_AUDIO_SAMPLE_CONTINUE; ///音频状态
            int       epStatus   = (int)EpStatus.MSP_EP_NULL;                  ///端点检测
            int       recStatus  = (int)RecogStatus.MSP_REC_NULL;              ///识别状态
            int       rsltStatus = (int)RecogStatus.MSP_REC_NULL;
            bool      first      = true;

            int errcode = 0;

            Utils.CustomPrint("上传语法 ...+\r\n");
            string grammarID = GetGrammarID();

            if (!string.IsNullOrEmpty(grammarID))
            {
                Utils.CustomPrint("上传语法成功\r\n");
            }
            else
            {
                Utils.CustomPrint("MSPUploadData error");
                yield break;
            }

            IntPtr ptrSessionID = DllImports.QISRSessionBegin(grammarID, sessionISRBeginParams, out errcode);
            string sessionID    = Marshal.PtrToStringAnsi(ptrSessionID);

            if (ErrorCode.MSP_SUCCESS != (ErrorCode)errcode)
            {
                Utils.CustomPrint("QISRSessionBegin err,errCode=" + ((ErrorCode)errcode).ToString("G"));
                yield break;
            }

            FileStream fp = new FileStream(path, FileMode.Open);

            byte[] buff = new byte[BUFFER_NUM];
            IntPtr bp   = Marshal.AllocHGlobal(BUFFER_NUM);

            while (fp.Position != fp.Length)
            {
                len = fp.Read(buff, 0, BUFFER_NUM);
                Marshal.Copy(buff, 0, bp, buff.Length);

                audStatus = (int)AudioStatus.MSP_AUDIO_SAMPLE_CONTINUE;
                if (first)
                {
                    audStatus = (int)AudioStatus.MSP_AUDIO_SAMPLE_FIRST;
                    first     = false;
                }

                Utils.CustomPrint(">");
                ///开始向服务器发送音频数据
                ret = DllImports.QISRAudioWrite(sessionID, bp, (uint)len, audStatus, ref epStatus, ref recStatus);

                if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
                {
                    HandleErrorMsg("QISRAudioWrite", ret, sessionID, fp);
                    yield break;
                }

                if (EpStatus.MSP_EP_AFTER_SPEECH == (EpStatus)epStatus)
                {
                    break;
                }

                ///sleep一下很有必要,防止MSC端无缓冲的识别结果时浪费CPU资源
                yield return(new WaitForSeconds(0.2f));
            }
            buff = null;
            fp.Close();
            fp = null;
            Marshal.FreeHGlobal(bp);

            ret = DllImports.QISRAudioWrite(sessionID, IntPtr.Zero, 0, (int)AudioStatus.MSP_AUDIO_SAMPLE_LAST, ref epStatus, ref recStatus);
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                HandleErrorMsg("QISRAudioWrite", ret, sessionID, null);
                yield break;
            }

            ///最后一块数据发完之后,循环从服务器端获取结果
            ///考虑到网络环境不好的情况下,需要对循环次数作限定
            while (RecogStatus.MSP_REC_STATUS_COMPLETE != (RecogStatus)rsltStatus)
            {
                IntPtr rec_result = DllImports.QISRGetResult(sessionID, ref rsltStatus, 0, out ret);
                if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
                {
                    HandleErrorMsg("QISRGetResult", ret, sessionID, null);
                    yield break;
                }
                if (IntPtr.Zero != rec_result)
                {
                    string tmp = Marshal.PtrToStringAnsi(rec_result);
                    Utils.CustomPrint("---:" + tmp);
                    result += tmp;
                    Utils.CustomPrint("传完音频后返回结果!:" + result);
                }
                yield return(new WaitForSeconds(0.2f));
            }

            ret = DllImports.QISRSessionEnd(sessionID, "Normal");
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                Utils.CustomPrint("QISRSessionEnd failed, errCode=" + ((ErrorCode)ret).ToString("G"));
            }
            ptrSessionID = IntPtr.Zero;
            Utils.CustomPrint("识别完成\r\n");
            yield break;
        }
Esempio n. 6
0
        /// <summary>
        /// 运行语音评测功能
        /// </summary>
        /// <returns></returns>
        public IEnumerator RunISE()
        {
            int    len;
            int    audStatus = (int)AudioStatus.MSP_AUDIO_SAMPLE_CONTINUE; ///音频状态
            int    epStatus  = (int)EpStatus.MSP_EP_NULL;                  ///端点检测
            int    recStatus = (int)RecogStatus.MSP_REC_NULL;              ///识别状态
            bool   first     = true;
            uint   rlstLen   = 0;
            IntPtr rsltPrt   = IntPtr.Zero;

            int       ret        = 0;
            const int BUFFER_NUM = 640 * 10;/// 每次写入200ms音频(16k,16bit):1帧音频20ms,10帧=200ms。16k采样率的16位音频,一帧的大小为640Byte

            FileStream textFS = null;
            FileStream waveFS = null;

            string parameters, textPath, wavePath;

            GetValuesByCategory(category, out parameters, out textPath, out wavePath);

#if UNITY_ANDROID
            textPath = Application.persistentDataPath + "/" + textPath;
            wavePath = Application.persistentDataPath + "/" + wavePath;
#elif UNITY_STANDALONE_WIN
            textPath = Application.streamingAssetsPath + "/" + textPath;
            wavePath = Application.streamingAssetsPath + "/" + wavePath;
#endif

            IntPtr ptrSessionID = DllImports.QISESessionBegin(parameters, "", out ret);
            string sessionID    = Marshal.PtrToStringAnsi(ptrSessionID);
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                Utils.CustomPrint("QISESessionBegin err,errCode=" + ((ErrorCode)ret).ToString("G"));
                yield break;
            }

            if (!File.Exists(textPath) || !File.Exists(wavePath))
            {
                Utils.CustomPrint("文件" + textPath + " 或者 " + wavePath + "不存在!");
                DllImports.QISESessionEnd(sessionID, "File not exist");
                yield break;
            }
            textFS = new FileStream(textPath, FileMode.Open);
            int    textLength = (int)textFS.Length;
            byte[] buff       = new byte[textLength];
            textFS.Read(buff, 0, textLength);
            textFS.Close();
            textFS = null;

            ret = DllImports.QISETextPut(sessionID, Encoding.Default.GetString(buff), (uint)textLength, "");
            Utils.CustomPrint("Encoding:" + Encoding.Default.EncodingName.ToLower());
            Utils.CustomPrint(Regex.Unescape(Encoding.Default.GetString(buff)) + "|length:" + textLength);
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                HandleErrorMsg("QISETextPut", ret, sessionID, null);
                yield break;
            }

            waveFS = new FileStream(wavePath, FileMode.Open);
            buff   = new byte[BUFFER_NUM];
            IntPtr bp = Marshal.AllocHGlobal(BUFFER_NUM);

            while (waveFS.Position != waveFS.Length)
            {
                len = waveFS.Read(buff, 0, BUFFER_NUM);
                Marshal.Copy(buff, 0, bp, buff.Length);

                audStatus = (int)AudioStatus.MSP_AUDIO_SAMPLE_CONTINUE;
                if (first)
                {
                    audStatus = (int)AudioStatus.MSP_AUDIO_SAMPLE_FIRST;
                    first     = false;
                }

                Utils.CustomPrint(">" + len);
                ///开始向服务器发送音频数据
                ret = DllImports.QISEAudioWrite(sessionID, bp, (uint)len, audStatus, ref epStatus, ref recStatus);
                if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
                {
                    HandleErrorMsg("QISEAudioWrite", ret, sessionID, waveFS);
                    yield break;
                }

                if (RecogStatus.MSP_REC_STATUS_SUCCESS == (RecogStatus)recStatus)
                {
                    rsltPrt = DllImports.QISEGetResult(sessionID, ref rlstLen, ref recStatus, ref ret);
                    if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
                    {
                        HandleErrorMsg("QISEGetResult", ret, sessionID, waveFS);
                        yield break;
                    }
                    if (IntPtr.Zero != rsltPrt)
                    {
                        Utils.CustomPrint("rlstLen:" + rlstLen);
                        byte[] data = new byte[rlstLen];
                        Marshal.Copy(rsltPrt, data, 0, (int)rlstLen);
                        Utils.CustomPrint("+++传完音频后返回结果!:" + GBToUnicode(data, data.Length));
                    }
                }

                if (EpStatus.MSP_EP_AFTER_SPEECH == (EpStatus)epStatus)
                {
                    break;
                }
                ///sleep一下很有必要,防止MSC端无缓冲的识别结果时浪费CPU资源
                yield return(new WaitForSeconds(0.2f));
            }
            buff = null;
            waveFS.Close();
            waveFS = null;
            Marshal.FreeHGlobal(bp);

            ret = DllImports.QISEAudioWrite(sessionID, IntPtr.Zero, 0, (int)AudioStatus.MSP_AUDIO_SAMPLE_LAST, ref epStatus, ref recStatus);
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                HandleErrorMsg("QISEAudioWrite", ret, sessionID, null);
                yield break;
            }

            while (RecogStatus.MSP_REC_STATUS_COMPLETE != (RecogStatus)recStatus)
            {
                rsltPrt = DllImports.QISEGetResult(sessionID, ref rlstLen, ref recStatus, ref ret);
                if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
                {
                    HandleErrorMsg("QISEGetResult", ret, sessionID, null);
                    yield break;
                }
                if (IntPtr.Zero != rsltPrt)
                {
                    Utils.CustomPrint("rlstLen:" + rlstLen);
                    byte[] data = new byte[rlstLen];
                    Marshal.Copy(rsltPrt, data, 0, (int)rlstLen);
                    Utils.CustomPrint("---传完音频后返回结果!:" + GBToUnicode(data, data.Length));
                }
                yield return(new WaitForSeconds(0.2f));
            }
            rsltPrt = IntPtr.Zero;
            ret     = DllImports.QISESessionEnd(sessionID, "Normal");
            if (ErrorCode.MSP_SUCCESS != (ErrorCode)ret)
            {
                Utils.CustomPrint("QISESessionEnd failed, errCode=" + ((ErrorCode)ret).ToString("G"));
            }
            ptrSessionID = IntPtr.Zero;
            Utils.CustomPrint("评测完成\r\n");
            yield break;
        }