2016-07-06 16:37:35 victor_barnett 阅读数 3500
  • 如何用卷积神经网络打造图片识别应用

    AI100 特邀阿里2017 云栖大会 API Solution大赛一等奖团队的联合创始人智亮先生,他将给大家介绍当前图像识别领域中先进的深度学习模型,并从源码级给大家讲解Tensorflow实现工业级图像识别应用的详细过程。通过本次公开分享课程大家将能掌握从零开始使用Tensorflow搭建一个图像识别引擎,包括训练、评估及服务的能力。

    18940 人正在学习 去看看 AI100讲师

        用了半天时间弄明白了在iOS上如何配置语音识别功能,然后用半天时间写了一个demo,公司坑爹的是不用科大飞讯的语音识别,而使用的是OpenEars,用google查了一下最新的介绍文章是2013年的,OpenEars是一款国外比较主流的语音识别的第三方框架,全是英文文档(吐槽一下,做开发必须要学好英语啊).

1.什么是OpenEars?

        OpenEars是面向iOS平台的一个离线的语音识别和text-to-speech(文字语音转换)开发工具包.OpenEars主要是针对英语,也支持中文的语言包,但是我感觉它的识别性不是太好.最重要的是,这是一款免费的工具包,除了基本的免费功能,它还提供了可以用来扩展基本功能的付费插件.今天主要介绍的是它的免费功能,即简单的语音识别功能.


        当前OpenEars的最新版本为2.5,下载地址为http://www.politepix.com/wp-content/uploads/OpenEarsDistribution.tar.bz2


2.详细配置OpenEars的步骤

(1)点击上方链接下载OpenEars的扩展包,打击打开扩展包,里面有一个Framework的文件夹,将这个文件拖进你的工程文件中.然后检查这个文件的路径(正常情况下Xcode会为你自动添加好文件的路径),点击你的工程文件,然后点击Build Settings,在搜索输入框输入Framework Search Paths,右键点击刚刚添加的Framework文件夹,然后show in finder即可查看文件的路径,核对两个路径是否正确.不正确或者不存在,手动添加即可.见图


核对检查好路径之后,为了添加二进制文件的存储,需要将Build Settings里的Deployment Postprocessing设置为YES.然后添加AudioToolbox库和AVFoundation库到你的项目里边.



(2)在你需要进行语音识别的.m文件下引入头文件,需引入头文件如下:


在你需要进行语音识别的.h文件下引入头文件,需引入头文件如下:


然后跟你需要实现语音识别的文件下引入协议(绿色<>部分为需要引入的协议),例如


并将OEEventsObserver属性添加到您的其他类属性(OEEventsObserver必须您的类的属性,否则它不会工作):



然后在viewDidLoad或者你需要的地方进行初始化观察者并签订协议:



下一步是创建你需要使用到的语音类文件,这决定你将使用什么语言进行识别,在viewDidLoad或者其他地方均可,具体实现如下:


其中的words是你创建的需要识别的单词.

最后在你需要开启语音识别的地方添加如下方法,开启语音识别:



其中你注册的观察者签订的协议方法如下所示



包含中文和英文声学模型的demo地址:Demo地址



2014-07-30 21:28:39 Vintage_1 阅读数 5571
  • 如何用卷积神经网络打造图片识别应用

    AI100 特邀阿里2017 云栖大会 API Solution大赛一等奖团队的联合创始人智亮先生,他将给大家介绍当前图像识别领域中先进的深度学习模型,并从源码级给大家讲解Tensorflow实现工业级图像识别应用的详细过程。通过本次公开分享课程大家将能掌握从零开始使用Tensorflow搭建一个图像识别引擎,包括训练、评估及服务的能力。

    18940 人正在学习 去看看 AI100讲师
       在跑通Android离线语音识别demo PocketSpinxAndroiDemo后,发现其使用pocketsphinx进行语音识别的准确率并不是很低。这和pocketsphinx语音识别所用的语言模型和声学模型相关。pocketsphinx-0.8源码自带几个语言模型和声学模型,pocketsphinx-0.7/model/hmm下的是声学模型(hmm应该指的是隐马尔科夫模型),pocketsphinx-0.7/model/lm下的是语言模型(lm表示language model)。运行demo时使用的是美国英语的语言模型(/lm/en_US/hub4.5000.DMP)和声学模型(/hmm/en_US/hub4wsj_sc_8k)以及字典文件(/lm/en_US/hub4.5000.dic),/pocketsphinx/model目录 内容如下,
├── hmm
│   ├── en
│   │  └── tidigits
│   │      ├── feat.params
│   │      ├── mdef
│   │      ├── means
│   │      ├── sendump
│   │      ├── transition_matrices
│   │       └── variances
│   ├── en_US
│   │  └── hub4wsj_sc_8k
│   │      ├── feat.params
│   │      ├── mdef
│   │      ├── means
│   │      ├── noisedict
│   │      ├── sendump
│   │      ├── transition_matrices
│   │      └── variances
│   └── zh
│       └── tdt_sc_8k
│           ├── feat.params
│           ├── mdef
│           ├── means
│           ├── noisedict
│           ├── sendump
│           ├── transition_matrices
│           └── variances
└── lm
    ├── en
    │  ├── tidigits.dic
    │  ├── tidigits.DMP
    │  ├── tidigits.fsg
    │  ├── turtle.dic
    │  └── turtle.DMP
    ├── en_US
    │  ├── cmu07a.dic
    │  ├── hub4.5000.DMP
    │  └── wsj0vp.5000.DMP
    ├── zh_CN
    │  ├── gigatdt.5000.DMP
    │  └── mandarin_notone.dic
    └── zh_TW
        ├── gigatdt.5000.DMP
        └── mandarin_notone.dic
这个目录下的内容在后面还要使用到。
        此外,CMU sphinx的官网提供了各种语言的声学模型和语言模型的下载,具体见,
http://sourceforge.net/projects/cmusphinx/files/Acoustic%20and%20Language%20Models/
本来应该有中文的,
声学模型:zh_broadcastnews_16k_ptm256_8000.tar.bz2
语言模型:zh_broadcastnews_64000_utf8.DMP
字典文件:zh_broadcastnews_utf8.dic
但现在去其官网上找已经没中文的了。。。另外,还可以使用语言模型训练工具CMUCLMTK和声学模型训练工具sphinxtrain自己训练得到语言模型和声学模型,这样的效果应该是最好的(识别范围应该也能扩大不少),这里不详细讲述,可以参考最后的参考链接1。

小范围英文准确识别
       Demo用的字典太大,相应的语言模型也很大,而这个语言模型和字典并非针对你而训练的,这是造成识别率低下的主要原因。因此,下面创建自己的语料库drone_ctr.txt,文件的内容是,
take off
land
turn left
turn right
forward
backward
spin left
spin right
up
down
hover
利用在线工具——http://www.speech.cs.cmu.edu/tools/lmtool.html上点Browse提交drone_ctr.txt,在线生成语言模型文件(一个压缩文件),下载生成的压缩文件,解压,我们要使用其中的1172.lm和1172.dic代替原来使用的hub4.5000.DMP和hub4.5000.dic。打开1172.dic文件,其内容主要也就是drone_ctr.txt每一条语料加上其注音。替换语言模型和字典后,修改PocketSpinxAndroiDemo中RecognizerTask.java的代码如下,
c.setString("-hmm",
                "/sdcard/Android/data/edu.cmu.pocketsphinx/hmm/en_US/hub4wsj_sc_8k");
c.setString("-dict",
                "/sdcard/Android/data/edu.cmu.pocketsphinx/lm/1172.dic");
c.setString("-lm",
                "/sdcard/Android/data/edu.cmu.pocketsphinx/lm/1172.lm");
由代码可知,我们仍然使用原来的声学模型,改变的只是语言模型和字典(1172.dic和1172.lm)。然后真机上调试,准确率就上来了~
        经过试验,发现准确率在不改变字典的情况下仍然不高,这说明声学模型不变的情况下,字典范围得足够小才能准确识别。

小范围中文准确识别
       和英文情况类似,先创建语料库drone_ctr.txt,文件的内容是,
起飞
降落
向左
向右
向前
向后
左转
右转
上升
下降
盘旋
利用在线工具——http://www.speech.cs.cmu.edu/tools/lmtool.html上点Browse提交drone_ctr.txt,在线生成语言模型文件,下载生成的压缩文件,解压,我们要使用其中的9930.lm和9930.dic代替原来使用的hub4.5000.DMP和hub4.5000.dic。这时打开字典9930.dic,发现其内容和语料库drone_ctr.txt是一摸一样的,并没有在每一行后面加上音注,这是因为该在线工具不支持中文注音(由参考链接3可知,原来可能是支持的),所以需要自己加音注,加音注后的9930.dic文件如下,
上升    sh ang sh eng
下降    x ia j iang
右转    y ou zh uan
向前    x iang q ian
向右    x iang y ou
向后    x iang h ou
向左    x iang z uo
左转    z uo zh uan
盘旋    p an x uxan
起飞    q i f ei
降落    j iang l uo
后面音注我是从/pocketsphinx/model/lm/zh_CN/mandarin_notone.dic中找到相应的语料,然后将其音注拷过来的(本来想用zh_broadcastnews_utf8.dic字典库,但现在CMU sphinx的官网上已经下不到中文声学模型和语言模型以及字典了),这再次证明了字典文件其实就是“语料+音注”。接下来,使用生成的语言模型9930.lm和自己编辑的字典9930.dic以及pocketsphinx-0.8源码自带中文声学模型/pocketsphinx/model/hmm/zh/tdt_sc_8k,并修改RecognizerTask.java代码,
c.setString("-hmm",
                "/sdcard/Android/data/edu.cmu.pocketsphinx/hmm/zh/tdt_sc_8k");
c.setString("-dict",
                "/sdcard/Android/data/edu.cmu.pocketsphinx/lm/9930.dic");
c.setString("-lm",
                "/sdcard/Android/data/edu.cmu.pocketsphinx/lm/9930.lm");
这样就可以进行语料库范围的中文语音识别了,准确率很高!

参考:
http://blog.csdn.net/zouxy09/article/details/7942784语言/声学模型介绍)
http://blog.csdn.net/zouxy09/article/category/1218766Sphinx很好很全面的资料,工具使用、API编程等
http://zuoshu.iteye.com/blog/1463867  (修改Demo的语言/声学模型,英文识别)
http://www.cnblogs.com/yin52133/archive/2012/07/12/2588201.html#2525875  (中文识别解决方案)

2014-05-17 18:50:06 zhonglunshun 阅读数 78
  • 如何用卷积神经网络打造图片识别应用

    AI100 特邀阿里2017 云栖大会 API Solution大赛一等奖团队的联合创始人智亮先生,他将给大家介绍当前图像识别领域中先进的深度学习模型,并从源码级给大家讲解Tensorflow实现工业级图像识别应用的详细过程。通过本次公开分享课程大家将能掌握从零开始使用Tensorflow搭建一个图像识别引擎,包括训练、评估及服务的能力。

    18940 人正在学习 去看看 AI100讲师

一个很小简单的语音识别源码,欢迎下载

2017-03-07 02:54:55 ItJavawfc 阅读数 4304
  • 如何用卷积神经网络打造图片识别应用

    AI100 特邀阿里2017 云栖大会 API Solution大赛一等奖团队的联合创始人智亮先生,他将给大家介绍当前图像识别领域中先进的深度学习模型,并从源码级给大家讲解Tensorflow实现工业级图像识别应用的详细过程。通过本次公开分享课程大家将能掌握从零开始使用Tensorflow搭建一个图像识别引擎,包括训练、评估及服务的能力。

    18940 人正在学习 去看看 AI100讲师

最近帮别人的车载系统整了一个小项目,分享一下最原始的Demo!

**说明:**XF的语音服务很多,类似提供语音服务的国内巨头还有百度!

客户需求:实现简单的语音控制指令【听音乐、暂停、下一首、上一曲、声音大一点、声音小一点】,程序入口:打开某某应用,嵌入到项目中实现TTS服务,人机交互。

如下简单的实现了命令控制,使用XF的离线命令词识别+TTS服务。

第一步:编写离线命令词文件,遵守它的语法规则
BNF文件如下:

#BNF+IAT 1.0 UTF-8;
!grammar call;
!slot <usOprate>;
!slot <usAccess>;
!slot <FuncTemp>;
!slot <FuncModel>;
!slot <ModelType>;
!slot <acModel>;
!start <acStart>;
<acStart>:<Model>;
<Model>: <ModelType>;
<ModelType>:暂停!id(101)|上一曲!id(102)|下一曲!id(103)|关机!id(104)|大点声!id(105)|大声!id(106)|小点声!id(107)|小声!id(108)
|后退!id(109)|天气!id(110)|天气!id(111)|唱首歌!id(112)|唱歌!id(113)|讲故事!id(114)|打开地图!id(115)
|打电话!id(116)|打开相册!id(117)|音乐!id(118)|拍照!id(119)|QQ!id(120)|扣扣!id(121)|口口!id(122)|叩叩!id(123)|微信!id(124);

配上语法详解:
这里写图片描述

第二步:接口调用
封装XF的离线命令词识别和和TTS服务,基于接口的实现而已。当用户说的话是命令词的时候,就直接触发命令执行相关业务逻辑。系统始终监听声音。
采用多态思想,让抽象方法实现接口,使得具体运用时候可以不实现接口中所有的方法,而且在抽象类中实现想实现的方法,需要时候,直接用抽象类的实例直接调用就OK。
部分代码如下:

public interface IVoiceCommandListener {
    // 打电话
    void onCallSomebody();
    // 打开的相册
    void onViewPhoto();
    // 我想听歌
    void onPlayMusic();
    // 查询天气命令
    void onViewQQ();
    // 拍照、照相
    public void onTakePhoto();
    // 微信
    public void onViewWX();
}
public abstract class VoiceCmdListener implements IVoiceCommandListener {

    private Context mContext;

    public VoiceCmdListener(Context context) {
        mContext = context;

    }
    @Override
    public void onCallSomebody() {
        String pkg = "com.example.news.movenews";
        String cls = "com.wxzh.news.MainActivity";
        ComponentName componet = new ComponentName(pkg, cls);
        Intent intent = new Intent();
        intent.setComponent(componet);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mContext.startActivity(intent);

    }

实例化:

voiceCommandListener = new VoiceCmdListener(UnderstanderService.this) {
 };

直接调用抽象类中实现的方法:
voiceCommandListener.onPlayMusic();

这里写图片描述

此项目主要为最原始的测试的离线命令词+TTS服务的Demo,有非常大的借鉴的意义,项目已经运用到市场中去了。读者拿了之后直接更换资源即可测试,更改拓展项目。

项目下载地址
可参考前几天的demo,机器人语音系统的文章:
机器人语音系统项目

2016-08-15 16:31:15 q4878802 阅读数 2631
  • 如何用卷积神经网络打造图片识别应用

    AI100 特邀阿里2017 云栖大会 API Solution大赛一等奖团队的联合创始人智亮先生,他将给大家介绍当前图像识别领域中先进的深度学习模型,并从源码级给大家讲解Tensorflow实现工业级图像识别应用的详细过程。通过本次公开分享课程大家将能掌握从零开始使用Tensorflow搭建一个图像识别引擎,包括训练、评估及服务的能力。

    18940 人正在学习 去看看 AI100讲师

源码

GitHub

在线语音识别

SDK下载

灵云SDK下载

SDK集成

下载SDK以后,将jar和so导入工程

权限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

封装

灵云配置类

package kong.qingwei.kqwhcidemo;

/**
 * Created by kqw on 2016/8/12.
 * 灵云配置信息
 */
public final class ConfigUtil {

    /**
     * 灵云APP_KEY
     */
    public static final String APP_KEY = "3d5d5466";

    /**
     * 开发者密钥
     */
    public static final String DEVELOPER_KEY = "eca643ff7b3c758745d7cf516e808d34";

    /**
     * 灵云云服务的接口地址
     */
    public static final String CLOUD_URL = "test.api.hcicloud.com:8888";

    /**
     * 需要运行的灵云能力
     */
    public static final String CAP_KEY = "tts.local.synth";
    //    public static final String CAP_KEY = "tts.cloud.wangjing";
    public static final String CAP_KEY_NUL = "nlu.cloud";
}

初始化灵云语音能力的工具类

package kong.qingwei.kqwhcidemo;

import android.app.Activity;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

import com.sinovoice.hcicloudsdk.api.HciCloudSys;
import com.sinovoice.hcicloudsdk.common.AuthExpireTime;
import com.sinovoice.hcicloudsdk.common.HciErrorCode;
import com.sinovoice.hcicloudsdk.common.InitParam;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * Created by kqw on 2016/8/12.
 * 初始化灵云语音
 */
public class HciUtil {

    private static final String TAG = "HciUtil";
    private Activity mActivity;
    private final String mConfigStr;

    public HciUtil(Activity activity) {
        mActivity = activity;

        // 加载信息,返回InitParam, 获得配置参数的字符串
        InitParam initParam = getInitParam();
        mConfigStr = initParam.getStringConfig();
    }

    public boolean initHci() {
        // 初始化
        int errCode = HciCloudSys.hciInit(mConfigStr, mActivity);
        if (errCode != HciErrorCode.HCI_ERR_NONE && errCode != HciErrorCode.HCI_ERR_SYS_ALREADY_INIT) {
            Toast.makeText(mActivity, "hciInit error: " + HciCloudSys.hciGetErrorInfo(errCode), Toast.LENGTH_SHORT).show();
            return false;
        }

        // 获取授权/更新授权文件 :
        errCode = checkAuthAndUpdateAuth();
        if (errCode != HciErrorCode.HCI_ERR_NONE) {
            // 由于系统已经初始化成功,在结束前需要调用方法hciRelease()进行系统的反初始化
            Toast.makeText(mActivity, "CheckAuthAndUpdateAuth error: " + HciCloudSys.hciGetErrorInfo(errCode), Toast.LENGTH_SHORT).show();
            HciCloudSys.hciRelease();
            return false;
        }
        return true;
    }

    /**
     * 释放
     */
    public void hciRelease(){
        HciCloudSys.hciRelease();
    }

    /**
     * 加载初始化信息
     *
     * @return 系统初始化参数
     */
    private InitParam getInitParam() {
        String authDirPath = mActivity.getFilesDir().getAbsolutePath();
        // 前置条件:无
        InitParam initparam = new InitParam();
        // 授权文件所在路径,此项必填
        initparam.addParam(InitParam.AuthParam.PARAM_KEY_AUTH_PATH, authDirPath);
        // 是否自动访问云授权,详见 获取授权/更新授权文件处注释
        initparam.addParam(InitParam.AuthParam.PARAM_KEY_AUTO_CLOUD_AUTH, "no");
        // 灵云云服务的接口地址,此项必填
        initparam.addParam(InitParam.AuthParam.PARAM_KEY_CLOUD_URL, ConfigUtil.CLOUD_URL);
        // 开发者Key,此项必填,由捷通华声提供
        initparam.addParam(InitParam.AuthParam.PARAM_KEY_DEVELOPER_KEY, ConfigUtil.DEVELOPER_KEY);
        // 应用Key,此项必填,由捷通华声提供
        initparam.addParam(InitParam.AuthParam.PARAM_KEY_APP_KEY, ConfigUtil.APP_KEY);
        // 配置日志参数
        String sdcardState = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(sdcardState)) {
            String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
            String packageName = mActivity.getPackageName();
            String logPath = sdPath + File.separator + "sinovoice" + File.separator + packageName + File.separator + "log" + File.separator;
            // 日志文件地址
            File fileDir = new File(logPath);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }
            // 日志的路径,可选,如果不传或者为空则不生成日志
            initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_PATH, logPath);
            // 日志数目,默认保留多少个日志文件,超过则覆盖最旧的日志
            initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_COUNT, "5");
            // 日志大小,默认一个日志文件写多大,单位为K
            initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_FILE_SIZE, "1024");
            // 日志等级,0=无,1=错误,2=警告,3=信息,4=细节,5=调试,SDK将输出小于等于logLevel的日志信息
            initparam.addParam(InitParam.LogParam.PARAM_KEY_LOG_LEVEL, "5");
        }
        return initparam;
    }

    /**
     * 获取授权
     *
     * @return 授权结果
     */
    private int checkAuthAndUpdateAuth() {
        // 获取系统授权到期时间
        int initResult;
        AuthExpireTime objExpireTime = new AuthExpireTime();
        initResult = HciCloudSys.hciGetAuthExpireTime(objExpireTime);
        if (initResult == HciErrorCode.HCI_ERR_NONE) {
            // 显示授权日期,如用户不需要关注该值,此处代码可忽略
            Date date = new Date(objExpireTime.getExpireTime() * 1000);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
            Log.i(TAG, "expire time: " + sdf.format(date));
            if (objExpireTime.getExpireTime() * 1000 > System.currentTimeMillis()) {
                // 已经成功获取了授权,并且距离授权到期有充足的时间(>7天)
                Log.i(TAG, "checkAuth success");
                return initResult;
            }
        }
        // 获取过期时间失败或者已经过期
        initResult = HciCloudSys.hciCheckAuth();
        if (initResult == HciErrorCode.HCI_ERR_NONE) {
            Log.i(TAG, "checkAuth success");
            return initResult;
        } else {
            Log.e(TAG, "checkAuth failed: " + initResult);
            return initResult;
        }
    }
}

语音识别的类

package kong.qingwei.kqwhcidemo;

import android.app.Activity;
import android.util.Log;

import com.sinovoice.hcicloudsdk.android.asr.recorder.ASRRecorder;
import com.sinovoice.hcicloudsdk.common.asr.AsrConfig;
import com.sinovoice.hcicloudsdk.common.asr.AsrInitParam;
import com.sinovoice.hcicloudsdk.common.asr.AsrRecogResult;
import com.sinovoice.hcicloudsdk.recorder.ASRRecorderListener;
import com.sinovoice.hcicloudsdk.recorder.RecorderEvent;


/**
 * Created by kqw on 2016/8/15.
 * 语音识别类
 */
public class AsrUtil {

    private static final String TAG = "AsrUtil";
    private Activity mActivity;
    private ASRRecorder mAsrRecorder;
    private AsrConfig asrConfig;
    private OnAsrRecogListener mOnAsrRecogListener;

    public AsrUtil(Activity activity) {
        mActivity = activity;
        initAsr();
    }

    private void initAsr() {
        Log.i(TAG, "initAsr: ");
        // 初始化录音机
        mAsrRecorder = new ASRRecorder();

        // 配置初始化参数
        AsrInitParam asrInitParam = new AsrInitParam();
        String dataPath = mActivity.getFilesDir().getPath().replace("files", "lib");
        asrInitParam.addParam(AsrInitParam.PARAM_KEY_INIT_CAP_KEYS, ConfigUtil.CAP_KEY_ASR_CLOUD_FREETALK);
        asrInitParam.addParam(AsrInitParam.PARAM_KEY_DATA_PATH, dataPath);
        asrInitParam.addParam(AsrInitParam.PARAM_KEY_FILE_FLAG, AsrInitParam.VALUE_OF_PARAM_FILE_FLAG_ANDROID_SO);
        Log.v(TAG, "init parameters:" + asrInitParam.getStringConfig());

        // 设置初始化参数
        mAsrRecorder.init(asrInitParam.getStringConfig(), new ASRResultProcess());

        // 配置识别参数
        asrConfig = new AsrConfig();
        // PARAM_KEY_CAP_KEY 设置使用的能力
        asrConfig.addParam(AsrConfig.SessionConfig.PARAM_KEY_CAP_KEY, ConfigUtil.CAP_KEY_ASR_CLOUD_FREETALK);
        // PARAM_KEY_AUDIO_FORMAT 音频格式根据不同的能力使用不用的音频格式
        asrConfig.addParam(AsrConfig.AudioConfig.PARAM_KEY_AUDIO_FORMAT, AsrConfig.AudioConfig.VALUE_OF_PARAM_AUDIO_FORMAT_PCM_16K16BIT);
        // PARAM_KEY_ENCODE 音频编码压缩格式,使用OPUS可以有效减小数据流量
        asrConfig.addParam(AsrConfig.AudioConfig.PARAM_KEY_ENCODE, AsrConfig.AudioConfig.VALUE_OF_PARAM_ENCODE_SPEEX);
        // 其他配置,此处可以全部选取缺省值

        asrConfig.addParam("intention", "weather");
    }

    /**
     * 开始语音识别
     */
    public void start(OnAsrRecogListener listener) {
        mOnAsrRecogListener = listener;
        if (mAsrRecorder.getRecorderState() == ASRRecorder.RECORDER_STATE_IDLE) {
            asrConfig.addParam(AsrConfig.SessionConfig.PARAM_KEY_REALTIME, "no");
            mAsrRecorder.start(asrConfig.getStringConfig(), null);
        } else {
            Log.i(TAG, "start: 录音机未处于空闲状态,请稍等");
        }
    }

    private class ASRResultProcess implements ASRRecorderListener {
        @Override
        public void onRecorderEventError(RecorderEvent event, int errorCode) {
            Log.i(TAG, "onRecorderEventError: errorCode = " + errorCode);
            if (null != mOnAsrRecogListener) {

                mOnAsrRecogListener.onError(errorCode);
            }
        }

        @Override
        public void onRecorderEventRecogFinsh(RecorderEvent recorderEvent, final AsrRecogResult arg1) {
            if (recorderEvent == RecorderEvent.RECORDER_EVENT_RECOGNIZE_COMPLETE) {
                Log.i(TAG, "onRecorderEventRecogFinsh: 识别结束");
            }
            if (null != mOnAsrRecogListener) {
                mActivity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mOnAsrRecogListener.onAsrRecogResult(arg1);
                    }
                });
            }
        }

        @Override
        public void onRecorderEventStateChange(RecorderEvent recorderEvent) {
            if (recorderEvent == RecorderEvent.RECORDER_EVENT_BEGIN_RECORD) {
                Log.i(TAG, "onRecorderEventStateChange: 开始录音");
            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_BEGIN_RECOGNIZE) {
                Log.i(TAG, "onRecorderEventStateChange: 开始识别");
            } else if (recorderEvent == RecorderEvent.RECORDER_EVENT_NO_VOICE_INPUT) {
                Log.i(TAG, "onRecorderEventStateChange: 无音频输入");
            } else {
                Log.i(TAG, "onRecorderEventStateChange: recorderEvent = " + recorderEvent);
            }
        }

        @Override
        public void onRecorderRecording(byte[] volumedata, int volume) {
            if (null != mOnAsrRecogListener) {
                mOnAsrRecogListener.onVolume(volume);
            }
        }

        @Override
        public void onRecorderEventRecogProcess(RecorderEvent recorderEvent, AsrRecogResult arg1) {
            if (recorderEvent == RecorderEvent.RECORDER_EVENT_RECOGNIZE_PROCESS) {
                Log.i(TAG, "onRecorderEventRecogProcess: 识别中间反馈");
            }
            if (arg1 != null) {
                if (arg1.getRecogItemList().size() > 0) {
                    Log.i(TAG, "onRecorderEventRecogProcess: 识别中间结果结果为:" + arg1.getRecogItemList().get(0).getRecogResult());
                } else {
                    Log.i(TAG, "onRecorderEventRecogProcess: 未能正确识别,请重新输入");
                }
            }
        }
    }

    /**
     * 语音识别的回调接口
     */
    public interface OnAsrRecogListener {
        // 识别结果
        void onAsrRecogResult(AsrRecogResult asrRecogResult);

        // 识别错误码
        void onError(int errorCode);

        // 录音音量
        void onVolume(int volume);
    }
}

使用

初始化灵云的语音能力和语音识别

// 灵云语音工具类
mInitTts = new HciUtil(this);
// 初始化灵云语音
boolean isInitHci = mInitTts.initHci();
if (isInitHci) { // 初始化成功
    ……
    // 语音识别
    mAsrUtil = new AsrUtil(this);
}

语音识别

/**
 * 语音识别(语音转文字)
 *
 * @param view view
 */
public void asr(View view) {
    mAsrUtil.start(new AsrUtil.OnAsrRecogListener() {
        @Override
        public void onAsrRecogResult(AsrRecogResult asrRecogResult) {
            StringBuilder stringBuffer = new StringBuilder();
            ArrayList<AsrRecogItem> asrRecogItemArrayList = asrRecogResult.getRecogItemList();
            for (AsrRecogItem asrRecogItem : asrRecogItemArrayList) {
                String result = asrRecogItem.getRecogResult();
                Log.i(TAG, "onAsrRecogResult: " + result);
                stringBuffer.append(result).append("\n");
            }
            showDialog("识别结果", stringBuffer.toString());
        }

        @Override
        public void onError(int errorCode) {
            Log.i(TAG, "onError: " + errorCode);
        }

        @Override
        public void onVolume(int volume) {
            Log.i(TAG, "onVolume: " + volume);
        }
    });
}

离线语音识别

离线命令词和在线很类似,只需要更改CapKey,导入离线资源包即可,我们先下载离线资源

下载完解压

解压后的源文件png

将里面所有的文件重命名,前面加lib,后面加.so,然后导入工程

重命名

修改CapKey为asr.local.freetalk

注意,灵云的离线语音功能第一次使用需要联网激活,激活以后才可以使用离线功能。

在线语音识别 + 语义理解

直接在在线语音识别的基础上实现语义理解更加简单,只要将CapKey换成asr.cloud.dialog即可

但是需要注意一点的是,想要使用哪个场景,必须开通以后,在参数里加上对应的场景,才是识别出来。

类似这样

asrConfig.addParam("intention", "weather");
没有更多推荐了,返回首页