精华内容
下载资源
问答
  • 语音命令词识别

    千次阅读 2018-08-25 16:46:53
    语音命令词识别的方案有:讯飞在线\离线语音命令词识别,还有一个方案是基于TensorFlow的机器学习。后者不需要费用,但是需要训练(所谓训练不是像宠物一样,每个宠物都需要训练一遍,而一次训练生成模板后,所...

    现在反倒自然语言处理的API比较多,各大厂都有。能快速处理语音命令词(关灯,开灯,左转,右转,停止)的并不多,都默认按照自然语言处理的,这会带来两个问题: 1是识别速度慢 2.准确度不够高。

    语音命令词识别的方案有:讯飞在线\离线语音命令词识别,还有一个方案是基于TensorFlow的机器学习。后者不需要费用,但是需要训练(所谓训练不是像宠物一样,每个宠物都需要训练一遍,而一次训练生成模板后,所有的设备上都可以使用)。

    TensorFlow语音命令词识别

    这个文章中有相应的介绍,会让你在自己的电脑上基于Google搜集的语音命令词语音(wav文件)进行训练,大概需要几个小时模板文件就能创建了,可以识别测试。我按照这些步骤都走通了。在测试时基本也能识别,但是似乎有一个问题,识别速度比较慢,大概需要2秒中能给出答案,这让我感觉不是太好。不过最终没有放弃,准备试试Google做的Android系统的Demo(TF Speech)直接用来测试。
    这里写图片描述
    这里测试的速度基本达到预期了,话音刚落就识别出来了。

    注:没有下载到编译好的,只得自己编译,我把我编译好的上传,方便各位测试。
    下载地址:https://download.csdn.net/download/kangear/10626585

    如果需要自行编译,可以按照https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android#prebuilt-components步骤,需要把build.gradle改一点就可以编译通过了:

    def nativeBuildSystem = 'none'

    展开全文
  • 科大讯飞离线语音命令词识别的使用说明

    万次阅读 多人点赞 2018-08-27 22:30:29
    最近因为项目的需求,需要在无网络的情况下实现语音识别的功能,因为之前在线识别一直用的科大的,所以经理就和我说,你花半天时间简单熟悉一下,然后出一个Demo,下午有人过来看;因为之前科大在线SR也是别人做的,...

          最近因为项目的需求,需要在无网络的情况下实现语音识别的功能,因为之前在线识别一直用的科大的,所以经理就和我说,你花半天时间简单熟悉一下,然后出一个Demo,下午有人过来看;因为之前科大在线SR也是别人做的,准确的说我只是了解过一点,也写过相关的blog——百度语音识别结合云知声离线TTSDemo(AS)Android原生TTS的基本使用以及配合中文语音包实现中文TTS等,但是就半天不到的时间写一个Demo还是很赶的,比较不熟悉。下面就来简单的总结一下这半天的经历。   

    源码下载地址

     

    第一阶段    基础准备

    第一步:找到科大讯飞开发平台官网,注册账户

    平台地址

    第二步:点击右上角“控制台”进入个人控制台

    第三步:创建应用,根据选择的服务生成SDK并下载

     

          这里我们添加离线命令词识别服务,获取了对应SDK之后,也就完成的最基本的准备工作了,生成的APPID很重要哟,这个不用说你也应该知道。我们的第一阶段就算完成了

     

    第二阶段    Demo导入

    第四步:打开AS,创建一个和上图同名的应用

    第五步:导入SDK解压文件夹下的sample目录里面的的mscV5PlusDemomodule

     

    这里面需要实现在AS项目中导入module操作,如下图所示:

     

    选择上面sample下面对应的mscV5PlusDemo即可,如果有需要调整sdk版本的就按照错误提示调整就好了,比较简单;至此,我们就把SDK中的Demo(mscV5PlusDemo)导入到了我们的项目中:

     

    第六步:这个时候选择导入的module,在arm机上运行,发现并不能正常运行,那么你需要考虑以下几个问题

    (1)Demo中的离线命令词识别的commen.jet文件位置错误

    在解压文件夹的res目录下找到asr文件夹,将其copy到Demo里面的assets目录下:

     

    (2)一定要在arm机上测试,因为这个Demo里面只有armeabi的so文件

    (3)如果可以运行,进入如下界面,发现里面不仅仅只有我们需要的离线命令词识别,还有在线识别等等:

     

    我们点击“立刻体验语法识别”,关闭设备网络,选择下图中的“本地”,然后点击“构建语法”,再点击“开始识别”;

    这个时候很有可能再报错误,查看错误码发现原来是没有录音权限等权限问题,这个时候你就纳闷了,明明Demo代码中已经添加了权限:

       <uses-permission android:name="android.permission.RECORD_AUDIO" />
       <uses-permission android:name="android.permission.INTERNET" />
       <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
       <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
       <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
       <uses-permission android:name="android.permission.READ_PHONE_STATE" />
       <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
       <uses-permission android:name="android.permission.READ_CONTACTS" />
       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
       <uses-permission android:name="android.permission.WRITE_SETTINGS" />
       <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
       <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
       <uses-permission android:name="android.permission.BLUETOOTH" />
       <uses-permission android:name="android.permission.BROADCAST_STICKY" />

    为什么还有问题,这个时候你再进入到Demo代码里面查看,里面并没有做6.0以及以上版本的动态权限申请处理,所以怎么办了,要么我们自己加上,要么换一个低一点的机子测试一下。

    // 开始识别,没有权限判断
    case R.id.isr_recognize:
       ((EditText)findViewById(R.id.isr_text)).setText(null);// 清空显示内容
       // 设置参数
       if (!setParam()) {
          showTip("请先构建语法。");
          return;
       };
       
       ret = mAsr.startListening(mRecognizerListener);
       if (ret != ErrorCode.SUCCESS) {
          showTip("识别失败,错误码: " + ret);   
       }
       break;
    
    

    这里我们就不深究了,因为后面还有好多内容了,假设这个时候你能够正常运行了,也能在Demo中完成离线命令词识别了。那么下一阶段就是瘦身处理了。

     

    第三阶段    功能瘦身

    第七步:提取离线命令词识别功能

          不得不说,这个Demo对于我们只使用离线命令词识别来说有一点冗余,太多了;下面我们就来把离线命令词功能抽取出来,如下图:

     

    实现离线命令词识别的功能实现主要是上图中红色框中AsrDemo中的逻辑,其源码如下:

    package com.iflytek.mscv5plusdemo;
    
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.content.SharedPreferences;
    import android.content.SharedPreferences.Editor;
    import android.os.Bundle;
    import android.os.Environment;
    import android.text.TextUtils;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.Window;
    import android.widget.EditText;
    import android.widget.RadioGroup;
    import android.widget.RadioGroup.OnCheckedChangeListener;
    import android.widget.Toast;
    
    import com.iflytek.cloud.ErrorCode;
    import com.iflytek.cloud.GrammarListener;
    import com.iflytek.cloud.InitListener;
    import com.iflytek.cloud.LexiconListener;
    import com.iflytek.cloud.RecognizerListener;
    import com.iflytek.cloud.RecognizerResult;
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechError;
    import com.iflytek.cloud.SpeechRecognizer;
    import com.iflytek.cloud.util.ContactManager;
    import com.iflytek.cloud.util.ContactManager.ContactListener;
    import com.iflytek.cloud.util.ResourceUtil;
    import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;
    import com.iflytek.speech.util.FucUtil;
    import com.iflytek.speech.util.JsonParser;
    import com.iflytek.speech.util.XmlParser;
    
    public class AsrDemo extends Activity implements OnClickListener{
       private static String TAG = AsrDemo.class.getSimpleName();
       // 语音识别对象
       private SpeechRecognizer mAsr;
       private Toast mToast;  
       // 缓存
       private SharedPreferences mSharedPreferences;
       // 本地语法文件
       private String mLocalGrammar = null;
       // 本地词典
       private String mLocalLexicon = null;
       // 云端语法文件
       private String mCloudGrammar = null;
       // 本地语法构建路径    
       private String grmPath = Environment.getExternalStorageDirectory()
                            .getAbsolutePath() + "/msc/test";
       // 返回结果格式,支持:xml,json
       private String mResultType = "json";
       
       private  final String KEY_GRAMMAR_ABNF_ID = "grammar_abnf_id";
       private  final String GRAMMAR_TYPE_ABNF = "abnf";
       private  final String GRAMMAR_TYPE_BNF = "bnf";
    
       private String mEngineType = "cloud";
       @SuppressLint("ShowToast")
       public void onCreate(Bundle savedInstanceState)
       {
          super.onCreate(savedInstanceState);
          this.requestWindowFeature(Window.FEATURE_NO_TITLE);
          setContentView(R.layout.isrdemo);
          initLayout();
          
          // 初始化识别对象
          mAsr = SpeechRecognizer.createRecognizer(this, mInitListener);    
    
          // 初始化语法、命令词
          mLocalLexicon = "张海羊\n刘婧\n王锋\n";
          mLocalGrammar = FucUtil.readFile(this,"call.bnf", "utf-8");
          mCloudGrammar = FucUtil.readFile(this,"grammar_sample.abnf","utf-8");
          
          // 获取联系人,本地更新词典时使用
          ContactManager mgr = ContactManager.createManager(AsrDemo.this, mContactListener); 
          mgr.asyncQueryAllContactsName();
          mSharedPreferences = getSharedPreferences(getPackageName(),    MODE_PRIVATE);
          mToast = Toast.makeText(this,"",Toast.LENGTH_SHORT);   
          
       }
       
       /**
        * 初始化Layout。
        */
       private void initLayout(){
          findViewById(R.id.isr_recognize).setOnClickListener(this);
          
          findViewById(R.id.isr_grammar).setOnClickListener(this);
          findViewById(R.id.isr_lexcion).setOnClickListener(this);
          
          findViewById(R.id.isr_stop).setOnClickListener(this);
          findViewById(R.id.isr_cancel).setOnClickListener(this);
    
          //选择云端or本地
          RadioGroup group = (RadioGroup)this.findViewById(R.id.radioGroup);
          group.setOnCheckedChangeListener(new OnCheckedChangeListener() {
             @Override
             public void onCheckedChanged(RadioGroup group, int checkedId) {
                if(checkedId == R.id.radioCloud)
                {
                   ((EditText)findViewById(R.id.isr_text)).setText(mCloudGrammar);
                   findViewById(R.id.isr_lexcion).setEnabled(false);
                   mEngineType = SpeechConstant.TYPE_CLOUD;
                }else if(checkedId == R.id.radioLocal)
                {
                   ((EditText)findViewById(R.id.isr_text)).setText(mLocalGrammar);
                   findViewById(R.id.isr_lexcion).setEnabled(true);
                   mEngineType =  SpeechConstant.TYPE_LOCAL;
                }
             }
          });
       }
        
       
       String mContent;// 语法、词典临时变量
        int ret = 0;// 函数调用返回值
       @Override
       public void onClick(View view) {      
          if( null == mAsr ){
             // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
             this.showTip( "创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化" );
             return;
          }
          
          if(null == mEngineType) {
             showTip("请先选择识别引擎类型");
             return;
          }  
          switch(view.getId())
          {
             case R.id.isr_grammar:
                showTip("上传预设关键词/语法文件");
                // 本地-构建语法文件,生成语法id
                if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) {
                   ((EditText)findViewById(R.id.isr_text)).setText(mLocalGrammar);
                   mContent = new String(mLocalGrammar);
                   mAsr.setParameter(SpeechConstant.PARAMS, null);
                   // 设置文本编码格式
                   mAsr.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
                   // 设置引擎类型
                   mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
                   // 设置语法构建路径
                   mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
                   //使用8k音频的时候请解开注释
    //             mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
                   // 设置资源路径
                   mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
                   ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mContent, grammarListener);
                   if(ret != ErrorCode.SUCCESS){
                      showTip("语法构建失败,错误码:" + ret);
                   }
                }
                // 在线-构建语法文件,生成语法id
                else { 
                   ((EditText)findViewById(R.id.isr_text)).setText(mCloudGrammar);
                   mContent = new String(mCloudGrammar);
                   // 指定引擎类型
                   mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
                   // 设置文本编码格式
                   mAsr.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
                    ret = mAsr.buildGrammar(GRAMMAR_TYPE_ABNF, mContent, grammarListener);
                   if(ret != ErrorCode.SUCCESS)
                      showTip("语法构建失败,错误码:" + ret);
                }
                break;
             // 本地-更新词典
             case R.id.isr_lexcion: 
                ((EditText)findViewById(R.id.isr_text)).setText(mLocalLexicon);
                mContent = new String(mLocalLexicon);
                mAsr.setParameter(SpeechConstant.PARAMS, null);
                // 设置引擎类型
                mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
                // 设置资源路径
                mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
                //使用8k音频的时候请解开注释
    //          mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
                // 设置语法构建路径
                mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
                // 设置语法名称
                mAsr.setParameter(SpeechConstant.GRAMMAR_LIST, "call");
                // 设置文本编码格式
                mAsr.setParameter(SpeechConstant.TEXT_ENCODING,"utf-8");
                ret = mAsr.updateLexicon("contact", mContent, lexiconListener);
                if(ret != ErrorCode.SUCCESS){
                   showTip("更新词典失败,错误码:" + ret);
                }
                break;
             // 开始识别
             case R.id.isr_recognize:
                ((EditText)findViewById(R.id.isr_text)).setText(null);// 清空显示内容
                // 设置参数
                if (!setParam()) {
                   showTip("请先构建语法。");
                   return;
                };
                
                ret = mAsr.startListening(mRecognizerListener);
                if (ret != ErrorCode.SUCCESS) {
                   showTip("识别失败,错误码: " + ret);   
                }
                break;
             // 停止识别
             case R.id.isr_stop:
                mAsr.stopListening();
                showTip("停止识别");
                break;
             // 取消识别
             case R.id.isr_cancel:
                mAsr.cancel();
                showTip("取消识别");
                break;
          }
       }
       
       /**
         * 初始化监听器。
         */
        private InitListener mInitListener = new InitListener() {
    
          @Override
          public void onInit(int code) {
             Log.d(TAG, "SpeechRecognizer init() code = " + code);
             if (code != ErrorCode.SUCCESS) {
                  showTip("初始化失败,错误码:"+code);
               }
          }
        };
           
       /**
         * 更新词典监听器。
         */
       private LexiconListener lexiconListener = new LexiconListener() {
          @Override
          public void onLexiconUpdated(String lexiconId, SpeechError error) {
             if(error == null){
                showTip("词典更新成功");
             }else{
                showTip("词典更新失败,错误码:"+error.getErrorCode());
             }
          }
       };
       
       /**
         * 构建语法监听器。
         */
       private GrammarListener grammarListener = new GrammarListener() {
          @Override
          public void onBuildFinish(String grammarId, SpeechError error) {
             if(error == null){
                if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
                   Editor editor = mSharedPreferences.edit();
                   if(!TextUtils.isEmpty(grammarId))
                      editor.putString(KEY_GRAMMAR_ABNF_ID, grammarId);
                   editor.commit();
                }
                showTip("语法构建成功:" + grammarId);
             }else{
                showTip("语法构建失败,错误码:" + error.getErrorCode());
             }        
          }
       };
       /**
        * 获取联系人监听器。
        */
       private ContactListener mContactListener = new ContactListener() {
          @Override
          public void onContactQueryFinish(String contactInfos, boolean changeFlag) {
             //获取联系人
             mLocalLexicon = contactInfos;
          }     
       };
       /**
         * 识别监听器。
         */
        private RecognizerListener mRecognizerListener = new RecognizerListener() {
            
            @Override
            public void onVolumeChanged(int volume, byte[] data) {
               showTip("当前正在说话,音量大小:" + volume);
               Log.d(TAG, "返回音频数据:"+data.length);
            }
            
          @Override
          public void onResult(final RecognizerResult result, boolean isLast) {
             if (null != result && !TextUtils.isEmpty(result.getResultString())) {
                Log.d(TAG, "recognizer result:" + result.getResultString());
                String text = "";
                if (mResultType.equals("json")) {
                   text = JsonParser.parseGrammarResult(result.getResultString(), mEngineType);
                } else if (mResultType.equals("xml")) {
                   text = XmlParser.parseNluResult(result.getResultString());
                }
                // 显示
                ((EditText) findViewById(R.id.isr_text)).setText(text);
             } else {
                Log.d(TAG, "recognizer result : null");
             }
          }
            
            @Override
            public void onEndOfSpeech() {
               // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入          
             showTip("结束说话");
            }
            
            @Override
            public void onBeginOfSpeech() {
               // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
               showTip("开始说话");
            }
    
          @Override
          public void onError(SpeechError error) {
             showTip("onError Code:"    + error.getErrorCode());
          }
    
          @Override
          public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
             // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
             // 若使用本地能力,会话id为null
             // if (SpeechEvent.EVENT_SESSION_ID == eventType) {
             //    String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
             //    Log.d(TAG, "session id =" + sid);
             // }
          }
    
        };
        
       
    
       private void showTip(final String str) {
          runOnUiThread(new Runnable() {
             @Override
             public void run() {
                mToast.setText(str);
                mToast.show();
             }
          });
       }
    
       /**
        * 参数设置
        * @param
        * @return 
        */
       public boolean setParam(){
          boolean result = false;
          // 清空参数
          mAsr.setParameter(SpeechConstant.PARAMS, null);
          // 设置识别引擎
          mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
          if("cloud".equalsIgnoreCase(mEngineType))
          {
             String grammarId = mSharedPreferences.getString(KEY_GRAMMAR_ABNF_ID, null);
             if(TextUtils.isEmpty(grammarId))
             {
                result =  false;
             }else {
                // 设置返回结果格式
                mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType);
                // 设置云端识别使用的语法id
                mAsr.setParameter(SpeechConstant.CLOUD_GRAMMAR, grammarId);
                result =  true;
             }
          }
          else
          {
             // 设置本地识别资源
             mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
             // 设置语法构建路径
             mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
             // 设置返回结果格式
             mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType);
             // 设置本地识别使用语法id
             mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, "call");
             // 设置识别的门限值
             mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30");
             // 使用8k音频的时候请解开注释
    //       mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
             result = true;
          }
          
          // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
          // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
          mAsr.setParameter(SpeechConstant.AUDIO_FORMAT,"wav");
          mAsr.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory()+"/msc/asr.wav");
          return result;
       }
       
       //获取识别资源路径
       private String getResourcePath(){
          StringBuffer tempBuffer = new StringBuffer();
          //识别通用资源
          tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, "asr/common.jet"));
          //识别8k资源-使用8k的时候请解开注释
    //    tempBuffer.append(";");
    //    tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, "asr/common_8k.jet"));
          return tempBuffer.toString();
       }
       
       @Override
       protected void onDestroy() {
          super.onDestroy();
          if( null != mAsr ){
             // 退出时释放连接
             mAsr.cancel();
             mAsr.destroy();
          }
       }
       
    }
    
    

    看着还是比较多的,我之所以说多而没有说难就是因为它并不难;下面的介绍中我们会对其进行再次瘦身。

     

    第八步:为自己的Demo做准备工作

    (1)把assets目录copy到我们的module中

    (2)把jniLibs目录copy到我们的module中

    这里是在Project视图下完成的,这里在Android视图下展示效果更好一下

    (3)打开Project视图,把libs目录中的内容复制到我们的module中

    (4)在build.gradle(Module:app)中的depandencies下添加依赖:

    compile files('libs/Msc.jar')

     

    (5)把Demo中的工具类copy到我们的module中

     

    截止到现在,我们还在准备阶段,下面就进入正题,来对我们的需要的功能的实现做一个简要的梳理

     

    第九步:提取离线命令词识别功能到我们的项目

    定义一个activity,CallStepActivity,把AsrDemo中的逻辑代码copy到CallStepActivty中,把对应的布局文件也对应copy进来

     

    第十步:梳理逻辑,继续瘦身

    上面也说了,AsrDemo中的Demo还是有点冗余,因为好多我们用不上或者暂时用不上,比如在线的命令词识别等肯定用不上,比如词典更新我们暂时用不上,下面就来分析一下单纯使用离线命令词识别的实现(下面是重点

    (1)根据应用ID初始化SpeechUtility,通常在程序入口Application中完成

    package com.hfut.offlinerecongnizer.activity.util;
    
    import android.app.Application;
    
    import com.hfut.offlinerecongnizer.R;
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechUtility;
    
    /**
     * author:why
     * created on: 2018/8/27 11:10
     * description:
     */
    public class MyApplication extends Application {
    
        @Override
        public void onCreate() {
            // 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史intent进入Activity造成SpeechUtility对象为null
            // 注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请增加参数:SpeechConstant.FORCE_LOGIN+"=true"
            // 参数间使用“,”分隔。
            // 设置你申请的应用appid
            // 注意: appid 必须和下载的SDK保持一致,否则会出现10407错误
            StringBuffer param = new StringBuffer();
            param.append("appid=" + getString(R.string.app_id));
            param.append(",");
            // 设置使用v5+
            param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
            SpeechUtility.createUtility(MyApplication.this, param.toString());
            super.onCreate();
        }
    }
    

    (2)在Activity中初始化初始化监听器,用于初始化语音识别引擎

    /**
     * 初始化监听器。
     */
    private InitListener mInitListener = new InitListener() {
    
        @Override
        public void onInit(int code) {
            Log.d(TAG, "SpeechRecognizer init() code = " + code);
            if (code != ErrorCode.SUCCESS) {
                showTip("初始化失败,错误码:" + code);
            }
        }
    };

    (3)初始化语音识别监听器

    /**
     * 识别监听器。
     */
    private RecognizerListener mRecognizerListener = new RecognizerListener() {
    
        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            showTip("当前正在说话,音量大小:" + volume);
            Log.d(TAG, "返回音频数据:" + data.length);
        }
    
        @Override
        public void onResult(final RecognizerResult result, boolean isLast) {
            if (null != result && !TextUtils.isEmpty(result.getResultString())) {
                Log.d(TAG, "recognizer result:" + result.getResultString());
                String text = "";
                if (mResultType.equals("json")) {
                    text = JsonParser.parseGrammarResult(result.getResultString(), SpeechConstant.TYPE_LOCAL);
                } else if (mResultType.equals("xml")) {
                    text = XmlParser.parseNluResult(result.getResultString());
                }
                // 显示
                ((EditText) findViewById(R.id.isr_text)).setText(text);
            } else {
                Log.d(TAG, "recognizer result : null");
            }
        }
    
        @Override
        public void onEndOfSpeech() {
            // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
            showTip("结束说话");
        }
    
        @Override
        public void onBeginOfSpeech() {
            // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
            showTip("开始说话");
        }
    
        @Override
        public void onError(SpeechError error) {
            showTip("onError Code:" + error.getErrorCode());
        }
    
        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {
    
        }
    };

    (4)初始化语法文件构建监听器

    /**
     * 构建语法监听器。
     */
    private GrammarListener grammarListener = new GrammarListener() {
        @Override
        public void onBuildFinish(String grammarId, SpeechError error) {
            if (error == null) {
                showTip("语法构建成功:" + grammarId);
            } else {
                showTip("语法构建失败,错误码:" + error.getErrorCode());
            }
        }
    };

    (5)初始化语音识别引擎并完成参数设置

    // 初始化识别引擎
    mAsr = SpeechRecognizer.createRecognizer(this, mInitListener);
    //设置识别引擎参数
    setParam();

    其中setPatam():

    public void setParam() {
        boolean result = true;
        // 清空参数
        mAsr.setParameter(SpeechConstant.PARAMS, null);
        // 设置识别引擎
        mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
        // 设置本地识别资源
        mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
        // 设置语法构建路径
        mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
        // 设置返回结果格式
        mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType);
        // 设置本地识别使用语法id
        mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, "call");
        // 设置识别的门限值
        mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30");
    
    }

    (6)完成语法构建

    private void  buildGrammer() {
            mLocalGrammar = FucUtil.readFile(this, "call.bnf", "utf-8");
            // 本地-构建语法文件,生成语法id
            ((EditText) findViewById(R.id.isr_text)).setText(mLocalGrammar);
            mContent = new String(mLocalGrammar);
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            // 设置文本编码格式
            mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
            // 设置引擎类型
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
            // 设置语法构建路径
            mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
            // 设置资源路径
            mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
            ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mContent, grammarListener);
            if (ret != ErrorCode.SUCCESS) {
                showTip("语法构建失败,错误码:" + ret);
            } else {
                showTip("语法构建成功");
            }
    
        }

    (7)开启识别,停止识别,取消识别分别是:

     mAsr.startListening(mRecognizerListener);
     mAsr.stopListening();
     mAsr.cancel();

    第十一步:最简单的功能实现代码

    所以最后组合起来,我们实现剥离了所有其他功能的只是实现离线命令词识别的代码,CallStepActivity代码如下:

    package com.hfut.offlinerecongnizer.activity.activity;
    
    import android.annotation.SuppressLint;
    import android.app.AlertDialog;
    import android.app.Dialog;
    import android.content.SharedPreferences;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import com.hfut.offlinerecongnizer.R;
    import com.hfut.offlinerecongnizer.activity.util.FucUtil;
    import com.hfut.offlinerecongnizer.activity.util.JsonParser;
    import com.hfut.offlinerecongnizer.activity.util.XmlParser;
    import com.iflytek.cloud.ErrorCode;
    import com.iflytek.cloud.GrammarListener;
    import com.iflytek.cloud.InitListener;
    import com.iflytek.cloud.LexiconListener;
    import com.iflytek.cloud.RecognizerListener;
    import com.iflytek.cloud.RecognizerResult;
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechError;
    import com.iflytek.cloud.SpeechRecognizer;
    import com.iflytek.cloud.util.ContactManager;
    import com.iflytek.cloud.util.ResourceUtil;
    
    /**
     * @author why
     * @date 2018-8-27 15:09:38
     */
    public class CallStepActivity extends AppCompatActivity implements View.OnClickListener {
    
        private static String TAG = OffLineTestActivity.class.getSimpleName();
        // 语音识别对象
        private SpeechRecognizer mAsr;
        private Toast mToast;
        // 本地语法文件
        private String mLocalGrammar = null;
        // 本地语法构建路径
        private String grmPath = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/msc/call";
        // 返回结果格式,支持:xml,json
        private String mResultType = "json";
        private final String GRAMMAR_TYPE_BNF = "bnf";
    
        @SuppressLint("ShowToast")
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.activity_call_step);
            initLayout();
            mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
            // 初始化识别引擎
            mAsr = SpeechRecognizer.createRecognizer(this, mInitListener);
    
            //构建本地语法
            buildGrammer();
        }
    
        /**
         * 初始化Layout。
         */
        private void initLayout() {
            findViewById(R.id.isr_recognize).setOnClickListener(this);
            findViewById(R.id.isr_stop).setOnClickListener(this);
            findViewById(R.id.isr_cancel).setOnClickListener(this);
        }
    
        String mContent;// 语法、词典临时变量
        int ret = 0;// 函数调用返回值
    
        @Override
        public void onClick(View view) {
            if (null == mAsr) {
                // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
                this.showTip("创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化");
                return;
            }
            switch (view.getId()) {
    
                // 开始识别
                case R.id.isr_recognize:
                    ((EditText) findViewById(R.id.isr_text)).setText(null);// 清空显示内容
                    //设置识别引擎参数
                    setParam();
                    ret = mAsr.startListening(mRecognizerListener);
                    if (ret != ErrorCode.SUCCESS) {
                        showTip("识别失败,错误码: " + ret);
                    }
                    break;
    
                // 停止识别
                case R.id.isr_stop:
                    mAsr.stopListening();
                    showTip("停止识别");
                    break;
    
                // 取消识别
                case R.id.isr_cancel:
                    mAsr.cancel();
                    showTip("取消识别");
                    break;
            }
        }
    
        /**
         * 初始化监听器。
         */
        private InitListener mInitListener = new InitListener() {
    
            @Override
            public void onInit(int code) {
                Log.d(TAG, "SpeechRecognizer init() code = " + code);
                if (code != ErrorCode.SUCCESS) {
                    showTip("初始化失败,错误码:" + code);
                }
            }
        };
    
    
        /**
         * 构建语法监听器。
         */
        private GrammarListener grammarListener = new GrammarListener() {
            @Override
            public void onBuildFinish(String grammarId, SpeechError error) {
                if (error == null) {
                    showTip("语法构建成功:" + grammarId);
                } else {
                    showTip("语法构建失败,错误码:" + error.getErrorCode());
                }
            }
        };
    
        /**
         * 识别监听器。
         */
        private RecognizerListener mRecognizerListener = new RecognizerListener() {
    
            @Override
            public void onVolumeChanged(int volume, byte[] data) {
                showTip("当前正在说话,音量大小:" + volume);
                Log.d(TAG, "返回音频数据:" + data.length);
            }
    
            @Override
            public void onResult(final RecognizerResult result, boolean isLast) {
                if (null != result && !TextUtils.isEmpty(result.getResultString())) {
                    Log.d(TAG, "recognizer result:" + result.getResultString());
                    String text = "";
                    if (mResultType.equals("json")) {
                        text = JsonParser.parseGrammarResult(result.getResultString(), SpeechConstant.TYPE_LOCAL);
                    } else if (mResultType.equals("xml")) {
                        text = XmlParser.parseNluResult(result.getResultString());
                    }
                    // 显示
                    ((EditText) findViewById(R.id.isr_text)).setText(text);
                } else {
                    Log.d(TAG, "recognizer result : null");
                }
            }
    
            @Override
            public void onEndOfSpeech() {
                // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
                showTip("结束说话");
            }
    
            @Override
            public void onBeginOfSpeech() {
                // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
                showTip("开始说话");
            }
    
            @Override
            public void onError(SpeechError error) {
                showTip("onError Code:" + error.getErrorCode());
            }
    
            @Override
            public void onEvent(int i, int i1, int i2, Bundle bundle) {
    
            }
        };
    
        private void showTip(final String str) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mToast.setText(str);
                    mToast.show();
                }
            });
        }
    
        /**
         * 参数设置
         *
         * @param
         * @return
         */
        public void setParam() {
            boolean result = true;
            // 清空参数
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            // 设置识别引擎
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
            // 设置本地识别资源
            mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
            // 设置语法构建路径
            mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
            // 设置返回结果格式
            mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType);
            // 设置本地识别使用语法id
            mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, "call");
            // 设置识别的门限值
            mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30");
            // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
            // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
            mAsr.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
            mAsr.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/asr.wav");
        }
    
        //获取识别资源路径
        private String getResourcePath() {
            StringBuffer tempBuffer = new StringBuffer();
            //识别通用资源
            tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "asr/common.jet"));
            return tempBuffer.toString();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (null != mAsr) {
                // 退出时释放连接
                mAsr.cancel();
                mAsr.destroy();
            }
        }
    
    
        private void buildGrammer() {
    
            mLocalGrammar = FucUtil.readFile(this, "call.bnf", "utf-8");
            // 本地-构建语法文件,生成语法id
            ((EditText) findViewById(R.id.isr_text)).setText(mLocalGrammar);
            mContent = new String(mLocalGrammar);
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            // 设置文本编码格式
            mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
            // 设置引擎类型
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
            // 设置语法构建路径
            mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
            //使用8k音频的时候请解开注释
    //             mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
            // 设置资源路径
            mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
            ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mContent, grammarListener);
            if (ret != ErrorCode.SUCCESS) {
                showTip("语法构建失败,错误码:" + ret);
            } else {
                showTip("语法构建成功");
            }
    
        }
    }
    

    activity_call_step.xml文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="10dip" >
        <include layout="@layout/title" />
    
        <EditText
            android:id="@+id/isr_text"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:gravity="top|left"
            android:textSize="20sp" />
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dip"
            android:layout_marginBottom="2dip"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dip"
            android:layout_marginBottom="2dip"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
            <Button
                android:id="@+id/isr_recognize"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="开始识别"
                android:textSize="20sp" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="2dip"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="10dip"
            android:layout_marginTop="2dip"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
    
            <Button
                android:id="@+id/isr_stop"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="停止录音"
                android:textSize="20sp" />
    
            <Button
                android:id="@+id/isr_cancel"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="取消"
                android:textSize="20sp" />
        </LinearLayout>
    
    </LinearLayout>

    如果不出意外的话,运行应该没有任何问题的。至此,最难的最复杂的第三阶段已经结束了,下面就来看看第四阶段的工作任务:

     

    第四阶段    提高

    第十二步:丰富我们的功能

    因为API里面提供了更新词典的功能(从这里我们也可以推出来后面介绍的bnf文件中词槽的定义也可以通过代码来实现):

    mAsr.updateLexicon(groupName, mLocalLexicon, lexiconListener);

    所以我们就该利用起来,毕竟如果我想修改某一个词槽的定义时,不能每次都是通过编辑bnf文件,然后在运行程序来实现,太麻烦了。这里我通过一个自定义的AlertDialog来实现对词槽的重新赋值,并列的同义词用“,”隔开即可,类似于bnf文件中的  |  符号;下面直接给出OffLineTestActivity代码:

    package com.hfut.offlinerecongnizer.activity.activity;
    
    import android.annotation.SuppressLint;
    import android.app.AlertDialog;
    import android.app.Dialog;
    import android.content.SharedPreferences;
    import android.os.Bundle;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.text.TextUtils;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.RadioGroup;
    import android.widget.Toast;
    
    import com.hfut.offlinerecongnizer.R;
    import com.hfut.offlinerecongnizer.activity.util.FucUtil;
    import com.hfut.offlinerecongnizer.activity.util.JsonParser;
    import com.hfut.offlinerecongnizer.activity.util.XmlParser;
    import com.iflytek.cloud.ErrorCode;
    import com.iflytek.cloud.GrammarListener;
    import com.iflytek.cloud.InitListener;
    import com.iflytek.cloud.LexiconListener;
    import com.iflytek.cloud.RecognizerListener;
    import com.iflytek.cloud.RecognizerResult;
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechError;
    import com.iflytek.cloud.SpeechRecognizer;
    import com.iflytek.cloud.util.ContactManager;
    import com.iflytek.cloud.util.ContactManager.ContactListener;
    import com.iflytek.cloud.util.ResourceUtil;
    import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;
    
    /**
     * @author why
     * @date 2018-8-27 13:20:58
     */
    public class OffLineTestActivity extends AppCompatActivity implements View.OnClickListener {
    
        private static String TAG = OffLineTestActivity.class.getSimpleName();
        // 语音识别对象
        private SpeechRecognizer mAsr;
        private Toast mToast;
        // 缓存
        //private SharedPreferences mSharedPreferences;
        // 本地语法文件
        private String mLocalGrammar = null;
        // 本地词典
        private String mLocalLexicon = null;
        // 本地语法构建路径
        private String grmPath = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/msc/call";
        // 返回结果格式,支持:xml,json
        private String mResultType = "json";
        private final String GRAMMAR_TYPE_BNF = "bnf";
    
        private String groupName;
        private String groupInfo;
    
        @SuppressLint("ShowToast")
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            setContentView(R.layout.activity_off_line_test);
            initLayout();
    
            // 初始化识别引擎对象
            mAsr = SpeechRecognizer.createRecognizer(this, mInitListener);
            mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
    
            //构建本地语法
            buildGrammer();
        }
    
        /**
         * 初始化Layout
         */
        private void initLayout() {
            findViewById(R.id.isr_recognize).setOnClickListener(this);
            findViewById(R.id.isr_lexcion).setOnClickListener(this);
            findViewById(R.id.isr_stop).setOnClickListener(this);
            findViewById(R.id.isr_cancel).setOnClickListener(this);
        }
    
        String mContent;// 语法、词典临时变量
        int ret = 0;// 函数调用返回值
    
        @Override
        public void onClick(View view) {
            if (null == mAsr) {
                // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
                this.showTip("创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化");
                return;
            }
            switch (view.getId()) {
                // 本地-更新词典
                case R.id.isr_lexcion:
    
                    AlertDialog.Builder builder = new AlertDialog.Builder(this);
                    LayoutInflater inflater = LayoutInflater.from(this);
                    final View v = inflater.inflate(R.layout.user_info_editor, null);
                    final EditText wordGroupName = v.findViewById(R.id.enter_word_group_name);
                    final EditText wordGroupInfo = v.findViewById(R.id.enter_word_group_info);
                    Button cancleButton = v.findViewById(R.id.register_cancle);
                    Button confirmButton = v.findViewById(R.id.register_confirm);
                    final Dialog dialog = builder.create();
                    //点击EditText弹出软键盘
                    cancleButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Toast.makeText(OffLineTestActivity.this, "取消", Toast.LENGTH_SHORT).show();
                            dialog.cancel();
                        }
                    });
    
    
                    confirmButton.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
    
                            if (!wordGroupName.getText().toString().equals("")) {
                                groupName= wordGroupName.getText().toString();
                            }
                            if (!wordGroupInfo.getText().toString().equals("")) {
                                groupInfo = wordGroupInfo.getText().toString();
                            }
                            mLocalLexicon=getUpdateInfo(groupInfo);
                            ((EditText) findViewById(R.id.isr_text)).setText(mLocalLexicon);
                            mAsr.setParameter(SpeechConstant.PARAMS, null);
                            // 设置引擎类型
                            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
                            // 设置资源路径
                            mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
                            // 设置语法构建路径
                            mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
                            // 设置语法名称
                            mAsr.setParameter(SpeechConstant.GRAMMAR_LIST, "call");
                            // 设置文本编码格式
                            mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
                            //执行更新操作
                            ret = mAsr.updateLexicon(groupName, mLocalLexicon, lexiconListener);
                            if (ret != ErrorCode.SUCCESS) {
                                showTip("更新词典失败,错误码:" + ret);
                            }
                            else{
                                showTip("更新词典成功" );
                            }
                            dialog.cancel();
                        }
                    });
    
                    dialog.show();
                    dialog.getWindow().setContentView(v);//自定义布局应该在这里添加,要在dialog.show()的后面
                    dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
                    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
                    break;
                // 开始识别
                case R.id.isr_recognize:
                    //设置识别引擎参数
                    setParam();
                    ((EditText) findViewById(R.id.isr_text)).setText(null);// 清空显示内容
                    ret = mAsr.startListening(mRecognizerListener);
                    if (ret != ErrorCode.SUCCESS) {
                        showTip("识别失败,错误码: " + ret);
                    }
                    break;
                // 停止识别
                case R.id.isr_stop:
                    mAsr.stopListening();
                    showTip("停止识别");
                    break;
                // 取消识别
                case R.id.isr_cancel:
                    mAsr.cancel();
                    showTip("取消识别");
                    break;
            }
        }
    
        private String getUpdateInfo(String groupInfo) {
            String[] wordList=groupInfo.split(",");
            StringBuilder builder=new StringBuilder();
            for(int i=0;i<wordList.length;i++){
                if(i==wordList.length-1) {
                    builder.append(wordList[i] );
                    Log.d(TAG, "getUpdateInfo: "+wordList[i]);
                }else{
                    builder.append(wordList[i] + "\n");
                }
            }
            return builder.toString();
        }
    
        /**
         * 初始化监听器。
         */
        private InitListener mInitListener = new InitListener() {
    
            @Override
            public void onInit(int code) {
                Log.d(TAG, "SpeechRecognizer init() code = " + code);
                if (code != ErrorCode.SUCCESS) {
                    showTip("初始化失败,错误码:" + code);
                }
            }
        };
    
        /**
         * 更新词典监听器。
         */
        private LexiconListener lexiconListener = new LexiconListener() {
            @Override
            public void onLexiconUpdated(String lexiconId, SpeechError error) {
                if (error == null) {
                    showTip("词典更新成功");
                } else {
                    showTip("词典更新失败,错误码:" + error.getErrorCode());
                }
            }
        };
    
        /**
         * 构建语法监听器。
         */
        private GrammarListener grammarListener = new GrammarListener() {
            @Override
            public void onBuildFinish(String grammarId, SpeechError error) {
                if (error == null) {
                    showTip("语法构建成功:" + grammarId);
                } else {
                    showTip("语法构建失败,错误码:" + error.getErrorCode());
                }
            }
        };
    
        /**
         * 识别监听器。
         */
        private RecognizerListener mRecognizerListener = new RecognizerListener() {
    
            @Override
            public void onVolumeChanged(int volume, byte[] data) {
                showTip("当前正在说话,音量大小:" + volume);
                Log.d(TAG, "返回音频数据:" + data.length);
            }
    
            @Override
            public void onResult(final RecognizerResult result, boolean isLast) {
                if (null != result && !TextUtils.isEmpty(result.getResultString())) {
                    Log.d(TAG, "recognizer result:" + result.getResultString());
                    String text = "";
                    if (mResultType.equals("json")) {
                        text = JsonParser.parseGrammarResult(result.getResultString(), SpeechConstant.TYPE_LOCAL);
                    } else if (mResultType.equals("xml")) {
                        text = XmlParser.parseNluResult(result.getResultString());
                    }
                    // 显示
                    ((EditText) findViewById(R.id.isr_text)).setText(text);
                } else {
                    Log.d(TAG, "recognizer result : null");
                }
            }
    
            @Override
            public void onEndOfSpeech() {
                // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
                showTip("结束说话");
            }
    
            @Override
            public void onBeginOfSpeech() {
                // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
                showTip("开始说话");
            }
    
            @Override
            public void onError(SpeechError error) {
                showTip("onError Code:" + error.getErrorCode());
            }
    
            @Override
            public void onEvent(int i, int i1, int i2, Bundle bundle) {
    
            }
        };
    
        private void showTip(final String str) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mToast.setText(str);
                    mToast.show();
                }
            });
        }
    
        /**
         * 参数设置
         *
         * @param
         * @return
         */
        public void setParam() {
            // 清空参数
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            // 设置识别引擎
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE,SpeechConstant.TYPE_LOCAL);
            // 设置本地识别资源
            mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
            // 设置语法构建路径
            mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
            // 设置返回结果格式
            mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType);
            // 设置本地识别使用语法id
            mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, "call");
            // 设置识别的门限值
            mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30");
            // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
            // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
            mAsr.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
            mAsr.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/asr.wav");
    
        }
    
        //获取识别资源路径
        private String getResourcePath() {
            StringBuffer tempBuffer = new StringBuffer();
            //识别通用资源
            tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, "asr/common.jet"));
            return tempBuffer.toString();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (null != mAsr) {
                // 退出时释放连接
                mAsr.cancel();
                mAsr.destroy();
            }
        }
    
    
        private boolean buildGrammer() {
    
                 mLocalGrammar = FucUtil.readFile(this, "call.bnf", "utf-8");
                // 本地-构建语法文件,生成语法id
                ((EditText) findViewById(R.id.isr_text)).setText(mLocalGrammar);
                mContent = new String(mLocalGrammar);
                mAsr.setParameter(SpeechConstant.PARAMS, null);
                // 设置文本编码格式
                mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
                // 设置引擎类型
                mAsr.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
                // 设置语法构建路径
                mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
                //使用8k音频的时候请解开注释
    //             mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
                // 设置资源路径
                mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
                ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mContent, grammarListener);
                if (ret != ErrorCode.SUCCESS) {
                    showTip("语法构建失败,错误码:" + ret);
                }
                else{
                    showTip("语法构建成功");
                }
            return true;
        }
    }

    activity_off_line_test.xml代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:gravity="center_horizontal"
        android:orientation="vertical"
        android:padding="10dip" >
        <include layout="@layout/title" />
    
        <EditText
            android:id="@+id/isr_text"
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:gravity="top|left"
            android:textSize="20sp" />
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dip"
            android:layout_marginBottom="2dip"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
    
            <Button
                android:id="@+id/isr_recognize"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="开始识别"
                android:textSize="20sp" />
    
            <Button
                android:id="@+id/isr_lexcion"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="更新词典"
                android:textSize="20sp"
                android:enabled="true" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="2dip"
            android:layout_marginLeft="10dip"
            android:layout_marginRight="10dip"
            android:layout_marginTop="2dip"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
    
            <Button
                android:id="@+id/isr_stop"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="停止录音"
                android:textSize="20sp" />
    
            <Button
                android:id="@+id/isr_cancel"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="取消"
                android:textSize="20sp" />
        </LinearLayout>
    
    </LinearLayout>

     

    word_info_editor.xml代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#B0C4DE"
        android:orientation="vertical">
    
        <TextView
            android:layout_marginLeft="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="请编辑更新信息:"
            android:textColor="#000000"
            android:textSize="30dp" />
    
        <LinearLayout
            android:layout_marginLeft="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="词组名称:"
                android:textSize="20dp" />
    
            <EditText
                android:id="@+id/enter_word_group_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="30dp"
                android:hint="请输入词组名称" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_marginLeft="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="词组信息:"
                android:textSize="20dp" />
    
            <EditText
                android:id="@+id/enter_word_group_info"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="30dp"
                android:hint="请编写词组信息" />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <Button
                android:id="@+id/register_cancle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="350dp"
                android:text="取消" />
    
            <Button
                android:id="@+id/register_confirm"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:text="确定" />
    
        </LinearLayout>
    
    </LinearLayout>

    其中还有一个所有布局都用到的title.xml代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:layout_gravity="top"
      android:gravity="center">
      <TextView
              android:text="@string/app_name"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:gravity="center"
              android:textSize="30sp"
              android:layout_margin="10dip"
        />
    </LinearLayout>
    

    上面介绍的离线命令词识别都是基于我们自己编辑的bnf文件中的规则来识别,下面给出一个文件示例:

    #BNF+IAT 1.0 UTF-8;
    !grammar call;
    
    //通用词槽
    !slot <want>;
    !slot <deal>;
    !slot <how>;
    
    //联系相关词槽声明
    !slot <contact>;//联系人
    !slot <callPhone>;//联系方式
    !slot <callTo>;//联系动作
    
    //巡游相关词槽声明
    !slot <destination>;//巡游点
    !slot <goTo>;//去
    !slot <goToPre>;//准备去
    
    /*
    专业语料相关
     */
     //办卡业务
     !slot <cardType>;
    
     //公积金业务
     !slot <percent>;
     !slot <wagesDeal>;
     !slot <wages>;
    
    !start <commands>;
    <commands>:<callRule>|<guideRule>|<dealCardRule>|<wagesDealRule>;
    
    //通用语料
    <want>:我想|我要|我准备;
    <how>:如何|怎么|怎样;
    <deal>:办理|解决|处理;
    
    //测试语料
    <contact>:黄老板|王华洋|齐带华|火警!id(119);
    <callPhone>:打电话|发微信|发短信;
    <callTo>:给;
    <callRule>:<callTo><contact><callPhone>|<callPhone><callTo><contact>;//联系语料相关规则
    
    //巡游语料
    <destination>:卫生间|饮水机|现金柜台|取款机|充电器|大堂经理;
    <goTo>:去|到|找;
    <goToPre>:带我|请带我|我想;
    <guideRule>:[<goToPre>]<goTo><destination>;//巡游语料相关规则
    
    //办卡语料
    <cardType>:卡|信用卡|儿童卡|储蓄卡;//卡片类型
    <dealCardRule>:[<want>]<deal><cardType>;
    
    //公积金业务
    <percent>:比例;//公积金比例
    <wagesDeal>:转移|提取;//处理公积金
    <wages>:公积金;
    <wagesDealRule>:[<how>]<wagesDeal><wages>;
    
    
    具体的编辑规则请参考bnf文档编辑指南,后续我还会对这个编辑规则进行介绍,具体就介绍到这里。
    

    注:欢迎扫码关注

     

    展开全文
  • 讯飞语义及其编写规范,在线离线合成文档,官方api
  • 讯飞离线语音命令词识别

    万次阅读 2017-12-28 17:58:50
    讯飞离线语音命令词识别 1、注册并下载sdk 2、创建工程 3、权限 4、拷贝jar包 5、初始化引擎 6、功能代码 7、打赏1、注册并下载sdk讯飞官网地址:http://www.xfyun.cn/*选择立即开通并登录* 弹出对话框,选择创建...

    讯飞离线语音命令词识别

    强烈推荐

    分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来! 网址:http://www.captainbed.net/yancyang

    • 1、注册并下载sdk
    • 2、创建工程
    • 3、权限
    • 4、拷贝jar包
    • 5、初始化引擎
    • 6、功能代码
    • 7、打赏

    弹出对话框,选择创建应用。

    这里写图片描述

    按照提示填写。

    应用创建完毕,接下来就是开通服务,以及获取AppID了。

    这里写图片描述

    Yancy是我创建的应用名称,记住AppID,选择开通服务为离线命令词识别

    • 2、创建工程

    Android studio创建工程就不说了。

    3、权限

    拷贝权限到功能清单文件中。

    	<uses-permission android:name="android.permission.RECORD_AUDIO"/>
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission android:name="android.permission.READ_CONTACTS"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    

    4、拷贝jar包
    下载的SDK文档中so库太多,离线命令词识别只需要用到 Msc.jar和libmsc.so

    上传的资源下载需要积分,这里就放百度云。

    地址:https://pan.baidu.com/s/1hsanJBe

    密码:523z

    记得关联jar包与.so库

    5、初始化引擎

    public class SpeechApp extends Application {
    
        @Override
        public void onCreate() {
            // 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史intent进入Activity造成SpeechUtility对象为null
            // 注意:此接口在非主进程调用会返回null对象,如需在非主进程使用语音功能,请增加参数:SpeechConstant.FORCE_LOGIN+"=true"
            // 参数间使用“,”分隔。
            // 设置你申请的应用appid
    
            // 注意: appid 必须和下载的SDK保持一致,否则会出现10407错误
    		// 5a4448f4更换成自己的appID.
            StringBuffer param = new StringBuffer();
            param.append("appid=5a4448f4");
            param.append(",");
            // 设置使用v5+
            param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
            SpeechUtility.createUtility(SpeechApp.this, param.toString());
            super.onCreate();
        }
    }
    

    别忘了,在功能清单中申明Application 。

       <application
            android:name=".SpeechApp"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
        </application>
    

    6、功能代码

    package hyco_voice.hyco.com.hycovoicedemo;
    
    import android.content.SharedPreferences;
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.util.Log;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import com.iflytek.cloud.ErrorCode;
    import com.iflytek.cloud.GrammarListener;
    import com.iflytek.cloud.InitListener;
    import com.iflytek.cloud.RecognizerListener;
    import com.iflytek.cloud.RecognizerResult;
    import com.iflytek.cloud.SpeechConstant;
    import com.iflytek.cloud.SpeechError;
    import com.iflytek.cloud.SpeechRecognizer;
    import com.iflytek.cloud.util.ResourceUtil;
    
    import static com.iflytek.cloud.SpeechConstant.TYPE_LOCAL;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "yancy";
    
        private EditText message;
    
        // 语音识别对象
        private SpeechRecognizer mAsr;
        private Toast mToast;
    
        //引擎类型 本地
        private String mEngineType = TYPE_LOCAL;
    
        // 本地语法构建路径
        private String grmPath = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/msc/test";
        // 返回结果格式,支持:xml,json
        private String mResultType = "json";
    
        // 本地语法文件
        private String mLocalGrammar = null;
    
        private final String GRAMMAR_TYPE_BNF = "bnf";
    
        // 缓存
        private SharedPreferences mSharedPreferences;
    
        private final String KEY_GRAMMAR_ABNF_ID = "grammar_abnf_id";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            message = findViewById(R.id.message);
    
            // 1.初始化识别对象
            mAsr = SpeechRecognizer.createRecognizer(this, mInitListener);
            mToast = Toast.makeText(this, "", Toast.LENGTH_SHORT);
    
    
            //2.构件语法
            build();
        }
    
        /**
         * 1.1 初始化监听器。
         */
        private InitListener mInitListener = new InitListener() {
            @Override
            public void onInit(int code) {
                Log.e(TAG, "SpeechRecognizer init() code = " + code);
                if (code != ErrorCode.SUCCESS) {
                    showTip("初始化失败,错误码:" + code);
                }
            }
        };
        String mContent;// 语法、词典临时变量
    
        //2.构件语法
        public void build() {
            mLocalGrammar = FucUtil.readFile(this, "call.bnf", "utf-8");
            mSharedPreferences = getSharedPreferences(getPackageName(), MODE_PRIVATE);
            message.setText(mLocalGrammar);
            mContent = new String(mLocalGrammar);
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            // 设置文本编码格式
            mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
            // 设置引擎类型
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
            // 设置语法构建路径
            mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
            //使用8k音频的时候请解开注释
    //					mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
            // 设置资源路径
            mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
            ret = mAsr.buildGrammar(GRAMMAR_TYPE_BNF, mContent, grammarListener);
            if (ret != ErrorCode.SUCCESS) {
                showTip("语法构建失败,错误码:" + ret);
            }
        }
    
        /**
         * 2.1 构建语法监听器。
         */
        private GrammarListener grammarListener = new GrammarListener() {
            @Override
            public void onBuildFinish(String grammarId, SpeechError error) {
                if (error == null) {
                    if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
                        SharedPreferences.Editor editor = mSharedPreferences.edit();
                        if (!TextUtils.isEmpty(grammarId))
                            editor.putString(KEY_GRAMMAR_ABNF_ID, grammarId);
                        editor.commit();
                    }
                    showTip("语法构建成功:" + grammarId);
                } else {
                    showTip("语法构建失败,错误码:" + error.getErrorCode());
                }
            }
        };
    
        int ret = 0;//返回值
    
        /**
         * 点击事件
         *
         * @param view
         */
        public void onClick(View view) {
            if (null == mAsr) {
                // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
                this.showTip("创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化");
                return;
            }
            // 设置参数
            if (!setParam()) {
                showTip("请先构建语法。");
                return;
            }
            ret = mAsr.startListening(mRecognizerListener);
            if (ret != ErrorCode.SUCCESS) {
                showTip("识别失败,错误码: " + ret);
            }
        }
    
        /**
         * toast 消息
         *
         * @param str
         */
        private void showTip(final String str) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mToast.setText(str);
                    mToast.show();
                }
            });
        }
    
        /**
         * 识别监听器。
         */
        private RecognizerListener mRecognizerListener = new RecognizerListener() {
    
            @Override
            public void onVolumeChanged(int volume, byte[] data) {
                showTip("当前正在说话,音量大小:" + volume);
                Log.d(TAG, "返回音频数据:" + data.length);
            }
    
            @Override
            public void onResult(final RecognizerResult result, boolean isLast) {
                if (null != result && !TextUtils.isEmpty(result.getResultString())) {
                    Log.d(TAG, "recognizer result:" + result.getResultString());
                    String text = "";
                    if (mResultType.equals("json")) {
                        text = JsonParser.parseGrammarResult(result.getResultString(), mEngineType);
                    }/* else if (mResultType.equals("xml")) {
                        text = XmlParser.parseNluResult(result.getResultString());
                    }*/
                    // 显示
                    message.setText(text);
                } else {
                    Log.d(TAG, "recognizer result : null");
                }
            }
    
            @Override
            public void onEndOfSpeech() {
                // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
                showTip("结束说话");
            }
    
            @Override
            public void onBeginOfSpeech() {
                // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
                showTip("开始说话");
            }
    
            @Override
            public void onError(SpeechError error) {
                showTip("onError Code:" + error.getErrorCode());
            }
    
            @Override
            public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
                // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
                // 若使用本地能力,会话id为null
                //	if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                //		String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
                //		Log.d(TAG, "session id =" + sid);
                //	}
            }
    
        };
    
        public boolean setParam() {
            boolean result = false;
            // 清空参数
            mAsr.setParameter(SpeechConstant.PARAMS, null);
            // 设置识别引擎
            mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
            if (TYPE_LOCAL.equalsIgnoreCase(mEngineType)) {
                // 设置本地识别资源
                mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
                // 设置语法构建路径
                mAsr.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
                // 设置返回结果格式
                mAsr.setParameter(SpeechConstant.RESULT_TYPE, mResultType);
                // 设置本地识别使用语法id
                mAsr.setParameter(SpeechConstant.LOCAL_GRAMMAR, "call");
                // 设置识别的门限值
                mAsr.setParameter(SpeechConstant.MIXED_THRESHOLD, "30");
                // 使用8k音频的时候请解开注释
    //			mAsr.setParameter(SpeechConstant.SAMPLE_RATE, "8000");
                result = true;
            }
            // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
            // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
            mAsr.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
            mAsr.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/asr.wav");
            return result;
        }
    
        //获取识别资源路径
        private String getResourcePath() {
            StringBuffer tempBuffer = new StringBuffer();
            //识别通用资源
            tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "asr/common.jet"));
            //识别8k资源-使用8k的时候请解开注释
            //tempBuffer.append(";");
            //tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, "asr/common_8k.jet"));
            return tempBuffer.toString();
        }
    }
    
    

    DEMO下载http://download.csdn.net/download/weixin_39923324/10178489

    百度云Demo下载地址

    如果运行中出现问题,欢迎留下你的评论。
    转注注明出处。

    强烈推荐

    分享一个大神的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来! 网址:http://www.captainbed.net/yancyang

    展开全文
  • 讯飞离线语音命令词识别语Demo
  • 科大讯飞的语音命令词识别(离线): 首先去科大讯飞官网注册App、拿到key,然后下载相应的SDK, 然后把下载下来的demo倒入到项目中,在下载文件中的demo在sampel的下级文件中 在Android studio中选择 ...

    科大讯飞的语音命令词识别(离线):

    首先去科大讯飞官网注册App、拿到key,然后下载相应的SDK,

    然后把下载下来的demo倒入到项目中,在下载文件中的demo在sampel的下级文件中

    在Android studio中选择

    然后导入成功,

     

    主要是。bnf文件,其他倒是有Dome,

    下面是我自己写的命令词;

    #BNF+IAT 1.0 UTF-8;
    !grammar call;
    !slot <action>;
    !slot <callCmd>;
    !start <callStart>;
    <callStart>:<callCmd><action>;
    <callCmd>:小智请;
    <action>:起飞|降落|拍照|录像;
    

     

    展开全文
  • 之前因为一次比赛App要用到语音识别,做一个通过手机输入语音指令然后根据输入内容做出响应的功能,当时请教了一下别人决定采用科大讯飞的在线命令词识别工程集成的SDK,当时先申请Appid,再下载SDK。(这里推荐大家...
  • 测试通过的C#讯飞语音识别离线命令词demo,适用于用C#和unity接入讯飞语音的开发者
  • 讯飞语音离线命令词识别示例demo

    热门讨论 2015-08-19 14:31:45
    博客讲解离线命令词识别的示例Demo源码
  • asr_record_sample.c 讯飞命令词识别 打包dll 修改 xunfei_speech 讯飞语音库模型等文件,测试时候放到C盘目录下 相关使用说明 https://blog.csdn.net/lijiefu123456/article/details/109568797
  • 讯飞离线语音命令识别测试, 做的DEMO测试, 想交流的可以联系我。
  • 这个语音唤醒与命令词识别一开始也主要想用在ROS系统进行机器人语音控制。这里给出了indigo版本的实现。 在这个包中,我定义了一个sr_order的msg,然后定义一个awaken_asr节点,当获取到识别结果时就发布消息。...
  • 语音离线命令词识别

    千次阅读 2017-03-07 02:54:55
    最近帮别人的车载系统整了一个小项目,分享一下最原始的Demo!**说明:**XF的语音服务很多,类似...如下简单的实现了命令控制,使用XF的离线命令词识别+TTS服务。第一步:编写离线命令词文件,遵守它的语法规则 BNF
  • 这里写自定义目录标题如何插入一段漂亮的代码片生成一个适合你的列表创建一...## unity语音离线命令词识别(windows) using System.Collections; using System.Collections.Generic; using UnityEngine; using Unity
  • 导语:在本文中,我们描述了Google最新发布的一个用于帮助训练和评估关键词识别系统的口语词汇组成的音频数据集。讨论了为什么这个任务是一个有趣的挑战,以及为什么它需要一个专门的,与用于对完整句子进行自动语音...
  • 这是我们计算机视听觉的第三个实验,也是本学期语音部分的最后一个实验,大概花了两天才写完。上个实验做的是语音编码问题,这个实验是语音识别的事,感觉处理语音还是比较有意思的。
  • 因为我们跑的是离线命令词识别功能所以这些脚本都是其他功能使用的,不用管他,直接删掉就行了。 大家看清楚这段代码,这段代码的意思是将你讯飞平台上的appid注册到应用中去。就是上一张我同样涂红的那部分。这里...
  • 2.命令词识别,开发中用得到的还是离线模式,所以在demo中如果想要写自己的命令词,可assets目录在创建grammar_main.bnf(离线的命令词写法),后面会附上测试的语法命令,在AsrDemo类中将改成mLocalGrammar = FucUtil...
  • 本文尝试将i-vector以及PLDA模型作为一种命令词识别结果置信度分析方法, 其无需声学模型、语言模型支撑, 且实验表明性能良好. 在此基础上, 针对i-vector在刻画时序信息方面的不足, 尝试将该系统与DTW融合, 有效提升...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,271
精华内容 2,108
关键字:

语音命令词识别