/**
  *
  *  recognize by wav audio buffer(RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 8000 Hz)
  *
  *  @param wavAudioBuffer query audio buffer
  *  @param wavAudioBufferLen the length of wavAudioBuffer
  *
  *  @return result
  *
  **/
 public string Recognize(byte[] pcmAudioBuffer, int pcmAudioBufferLen)
 {
     byte[] fp = null;
     try {
         fp = ACRCloudFingerprintTool.CreateFingerprint(pcmAudioBuffer, pcmAudioBufferLen);
     }catch (Exception e) {
         return(ACRCloudErrorInfo.getJsonInfo(ACRCloudErrorInfo.GEN_FP_ERROR, e.ToString()));
     }
     if (fp == null)
     {
         return(null);
     }
     return(this.DoRecognize(fp));
 }
        /**
         *
         *  ACRCloud Worker main function.
         *
         *    Every (mRecognizeInterval) seconds recognize ACRCloud Server by audio buffer.
         *  If has result and callback OnResult.
         *
         **/
        private void Run()
        {
            if (this.mRecorder == null || this.mListener == null)
            {
                return;
            }

            this.mIsRunning = true;

            string result              = "";
            int    retryNum            = this.mHttpErrorRetryNum;
            int    nextRecognizeTime   = 3;        // seconds
            int    preRecorderAudioLen = 0;
            int    recordRetryNum      = 10;

            while (this.mIsRunning)
            {
                Thread.Sleep(100);

                byte[] pcmData           = null;
                int    nowRecordAudioLen = this.mRecorder.GetAudioDataLen();
                if ((!this.mIsStopRecord) && nowRecordAudioLen == preRecorderAudioLen)                   // check microphone is OK
                {
                    recordRetryNum--;
                    if (recordRetryNum <= 0)
                    {
                        if (result == "")
                        {
                            result = ACRCloudErrorInfo.getJsonInfo(ACRCloudErrorInfo.RECORD_ERROR, "record error");
                        }
                        if (result == null)                           // mute audio and create fingerprint null
                        {
                            result = ACRCloudErrorInfo.getJsonInfo(ACRCloudErrorInfo.NO_RESULT, "No Result");
                        }
                        break;
                    }
                    continue;
                }
                preRecorderAudioLen = nowRecordAudioLen;
                recordRetryNum      = 10;

                if (this.mIsStopRecord || this.mRecorder.GetAudioDataLen() >= nextRecognizeTime * 2 * 8000)
                {
                    pcmData = this.mRecorder.GetAudioData();
                    if (pcmData == null)
                    {
                        result = ACRCloudErrorInfo.getJsonInfo(ACRCloudErrorInfo.RECORD_ERROR, "record error");
                        break;
                    }
                    result = this.DoRecognize(pcmData);
                    Debug.LogError(result);

                    if (result == "")
                    {
                        retryNum--;

                        result = ACRCloudErrorInfo.getJsonInfo(ACRCloudErrorInfo.HTTP_ERROR, "http error");
                        if (retryNum <= 0)
                        {
                            break;
                        }
                        continue;
                    }
                    retryNum = this.mHttpErrorRetryNum;

                    if (result != null)
                    {
                        try {
                            JsonData rTmp = JsonMapper.ToObject(result);
                            if ((int)rTmp ["status"] ["code"] == 1001)                               // no result
                            {
                                if (nextRecognizeTime >= this.mMaxRecognizeAudioTime)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        } catch (Exception e) {
                            result = ACRCloudErrorInfo.getJsonInfo(ACRCloudErrorInfo.JSON_ERROR, "json error (" + result + ")");
                            break;
                        }
                    }

                    if (this.mIsStopRecord)
                    {
                        if (result == null)
                        {
                            result = ACRCloudErrorInfo.getJsonInfo(ACRCloudErrorInfo.NO_RESULT, "No Result");
                        }
                        break;
                    }
                    nextRecognizeTime = pcmData.Length / (2 * 8000) + this.mRecognizeInterval;
                    if (nextRecognizeTime > this.mMaxRecognizeAudioTime)
                    {
                        nextRecognizeTime = this.mMaxRecognizeAudioTime;
                    }
                }
            }
            if (this.mIsRunning)
            {
                this.mListener.OnResult(result);
            }
            this.mIsRunning = false;
        }