He 1 year ago
parent 2bc0b815f4
commit b69b65bbe2

@ -1,2 +0,0 @@
yaw_branch
shm_branch

@ -0,0 +1 @@
由于我组使用的绘图软件功能限制只有以下UML模型能够导出。

@ -0,0 +1 @@
Subproject commit 013c5b7b86275a1f98bcd9e1ab0412c78b36a3e7

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

@ -0,0 +1,10 @@
1.使用demo测试时需将res中除layout外资源拷贝到demo中assets相应的路径下;
2.使用带UI接口时请将assets下文件拷贝到项目中;
3.文档说明请参考:http://doc.xfyun.cn/msc_android/;
4.在调用sdk时,请将res/layout下xml文件拷贝至工程的layout目录下此文件为sdk内置ui所需资源缺失会导致sdk部分功能无法使用;
注: 1. 由于更新优化更新,本次(1138)的libmsc.so库需与本次Msc.jar相匹配使用之前的Msc.jar包可能会导致出错。
感谢您使用科大讯飞服务。
官方网站http://www.xfyun.cn/

@ -0,0 +1,908 @@
1.1140版本更新信息
1. SSL证书更新
1.1139版本更新信息
1. 修复部分已知bug
2. 在线听写增加小语种听写功能;
3. libmsc.so库中唤醒能力单独分出需要唤醒能力时需加入libw_ivw.so
1.1138版本更新信息
1. 优化能量VAD修复已知bug
2. 优化与服务端的网络交互;
3. 由于更新优化更新本次的libmsc.so库需与本次Msc.jar相匹配不然可能出现异常。
1.1137版本更新信息
1.新集成能量VAD效率提升近60%(亮点);
2.优化与服务端的网络交互,服务更稳定(亮点);
3.修复部分已知bug
注: 1. 由于更新优化更新本次的libmsc.so库需与本次Msc.jar相匹配使用之前的Msc.jar包可能会导致出错。
2. 由于本次SDK中集成了最新的能量VAD在线服务将支持arm、arm-v7、arm64-v8离线唤醒支持armv7和arm64,
离线命令词支持armv7。其中arm架构的libmsc.so仅支持在线能力。若在离线组合能力离线唤醒+离线命令词的SDK中
请选用armv7的libmsc.so。
--------------------------------------------------------------------
1.1136版本更新信息
1.修复部分已知安全问题;
2.修复部分已知bug
--------------------------------------------------------------------
1.1135版本更新信息
1.解决speechdemo中合成文本设置失效问题
2.优化msc.jar 业务退出内存释放逻辑;
--------------------------------------------------------------------
1.1134版本更新信息
1.解决Android9.0 部分机型对org.apache.http 不兼容问题
2.优化demo代码增加听写循环调用逻辑支持;增加合成实时音频流输出调用和说明;
MSC 5.0.41.1217
--------------------------------------------------------------------
1.1133版本更新信息
1.大数据设备信息收集更新
MSC 5.0.41.1217
1.增加离线听写能力
--------------------------------------------------------------------
1.1132版本更新信息
1.增加大数据部分日志收集模块
MSC 5.0.40.1214
1.增加唤醒闭环功能
--------------------------------------------------------------------
1.1131版本更新信息
1.增加唤醒音量回调结果返回;
2.demo中合成UI优化;
MSC 5.0.38.1199
1.增加opus编解码支持
--------------------------------------------------------------------
1.1130版本更新信息
MSC 5.0.38.1195
1.更新唤醒引擎为60引擎
2.唤醒的门限值范围修改,为{0,3000}默认值为1450
--------------------------------------------------------------------
1.1129版本更新信息
1.解决蓝牙播报漏字问题;
2.解决8.1上合成漏字问题;
3.解决speechDemo异常崩溃问题;
4.优化speechDemo中UI;
--------------------------------------------------------------------
1.1128版本更新信息
1.合成业务,暂停和重新播放回调接口无返回问题修复;
2.支持听写/识别/评测/声纹结果返回的字符编码配置;
3.支持听写业务中sdk自带ui是否显示错误码信息默认显示通过参数“view_tips_plain” 进行配置,例:
mIat.setParameter("view_tips_plain","false");此处即为设置错误码不显示。
MSC 5.0.37.1181
--------------------------------------------------------------------
1.1127版本更新信息
1.语义模块统一采用aiui语义后续不再继续提供msc语义;
2.speechdemo关于声纹示例体验优化;
3.解决Android8.1上合成文本音频出现乱码问题;
MSC 5.0.36.1178
--------------------------------------------------------------------
1.1126版本更新信息
1.合成语音播放resumeSpeaking 接口增加audio 焦点获取;
2.synthesizeToUri 接口部分参数设置失败问题修复;
3.听写/合成 增加ico编码支持,"aue","ico";
4.修复MODE_WORLD_READABLE调用导致安全检测爆出的安全隐患
MSC 5.0.36.1178 更新信息
1.增加ico编解码支持
2.离线包增加aiui支持
-------------------------------------------------------------------
1.1125版本更新信息
1.听写小窗口提供讯飞输入法下载链接,注意 替换iflytek下的xml资源
2.在线人脸声纹可直接调用身份验证接口speechdemo中包含在线人脸和声纹
3.评测demo中添加直接写入音频方式详见demo中注释说明
MSC 5.0.36.1176更新信息
1.解决Android 8.0上崩溃问题
--------------------------------------------------------------------
1.1121版本更新信息
1.去除语记支持
2.更新底层库版本到5.0.35.1168
MSC 5.0.35.1168更新信息
1.Android 版本编译时增加 -fpic,修复Android 7.0以后Android 版本上出现的so加载崩溃问题
2.完善合成发音人列表
--------------------------------------------------------------------
1.1120版本更新信息
1事件回调修正会话 SID 值正常,但返回为空的问题;
2AIMIC 修正在唤醒会话结束偶现崩溃的问题;
3权限修正没有 android.permission.ACCESS_NETWORK_STATE 时无法使用的问题;
4录音加入录音时使用蓝牙的选项SpeechConstant.BLUETOOTH;
5合成修改合成进度中 spellinfo 的返回以JSON格式并增加音频长度信息需设置 "audio_info" 参数为真);
6识别增加在会话开始时通过参数设置获取设备信息SpeechConstant.DVC_INFO 参数需设置为真);
已知问题:
1AIMIC唤醒一定次数时报 27019 问题,为唤醒引擎返回结果 EOS 值错误引起;
2合成部份手机设备上在蓝牙播放回调 onComplete 时,若马上开始录音,合成播放末尾漏字(安卓系统蓝牙播放延迟原因,暂不解决);
--------------------------------------------------------------------
1.1119版本更新信息
1翻译增加翻译示例和文档说明
2合成1) 增加淡入淡出参数 TTS_FADING默认不启用2) 加长音频结束播放时加播的空白音频,优化蓝牙合成播放末尾漏字问题;
3AIMIC 修正偶现写音频失败问题;(自测通过)
已知问题:
1AIMIC唤醒一定次数时报 27019 问题为唤醒引擎返回结果EOS值错误引起
2合成厂商反馈蓝牙播放回调 onComplete 时,若马上开始录音,合成播放末尾漏字;
--------------------------------------------------------------------
1.1118版本更新信息
1语义理解增加 SCENE 语义情景参数;
2AIMIC修正 27018 问题;
3DEMOa) 语义理解DEMO去掉不支持的语义说法提示修正网址链接b) 加入语义情景设置代码示例;
已知问题:
1AIMIC唤醒一定次数时报 27019 问题为唤醒引擎返回结果EOS值错误引起
---------------------------------------------------------------------
1.1116版本更新信息
1语义理解默认语义使用 3.0 版本;
2文档新手指南文档不能功能用同一个PDF文档修改默认语义版本说明
已知问题:
1AIMIC唤醒一定次数时报 27019 问题为唤醒引擎返回结果EOS值错误引起
---------------------------------------------------------------------
1.1116版本更新信息
1语义理解默认语义使用 3.0 版本;
2文档新手指南文档不能功能用同一个PDF文档修改默认语义版本说明
3DEMOa) 语义理解DEMO去掉不支持的语义说法提示修正网址链接b) 加入语义情景设置代码示例;
已知问题:
1AIMIC唤醒一定次数时报 27019 问题为唤醒引擎返回结果EOS值错误引起
---------------------------------------------------------------------
1.1116版本更新信息
1语义理解默认语义使用 3.0 版本;
2文档新手指南文档不能功能用同一个PDF文档修改默认语义版本说明
3AIMIC a) 增加获取几麦和AIMIC版本的参数( aimic_on_channel, aimic_on_version ),增加设置 REAL BEAM 参数 ( aimic_on_real_beam )
b) 修改清空缓存的处理,增加三个线程同步;减少缓存空间大小,减少由于缓存多时,唤醒结果返回与 CAE frame count 相差较大,使 CAE 不回调结果,而报 27019 的情况;
4DEMO SpeechDemo, MscV5PlusDemo 修改语义报错时的提示,增加新版本重新配置语义的说明;
MSC 5.2.0.1044 更新信息AIMIC SDK
1将AIUI1042版本合并到AIMIC分支版本
已知问题:
1在构建版本时3.0语义在正式域名上还不可用,仅能在测试域名上可用: server_url=http://60.166.12.151/onlytest.htm
2在构建版本时新手指南说明的语义结果说明文档的超链接http://aiui.xfyun.cn/info/protocol里面还没放置文档
3AIMIC唤醒一定次数时报 27019 问题为唤醒引擎返回结果EOS值错误引起
---------------------------------------------------------------------
1.1115版本更新信息
1资源目录删除不要的 IVW 40 的资源;删除 1.0 版本的 ASR 资源,并把原 asr_two 文件夹改名 asrIVW 50 资源区分中英目录;
2因 5.2.0.1040 没有更新最新的 模型VAD 代码,故 AIMIC 用的库为在 5.2.0.1040 基础上同步了最新模型VAD代码后的库
MSC 5.0.32.1156 更新信息(普通 SDK
1、升级唤醒引擎集成5.0.1016版本取代之前的4.0BN引擎:
1支持中文唤醒英文唤醒中文英文唤醒资源不同
2支持windowslinuxAndroid平台
35.0引擎不兼容4.0,3.6引擎资源;
4资源头部格式变化
2、针对唤醒资源头部授权信息的校验添加可以不校验的逻辑如果资源中有授权信息则进行校验如果没有但是提供的msc库编译时添加了宏IFLY_SPEECH_PLUS_SUPPORT则不进行校验否则仍校验。
MSC 5.2.0.1040 更新信息AIMIC SDK
1、唤醒资源合并成一个文件资源头格式变化
2、唤醒多路由单独的宏控制
解决彭锐反馈的开了多路唤醒之后aiui业务cpu占用高的问题经过排查是因为开启多路唤醒打开了宏PARALLEL_LINES_SUPPORT影响了aiui业务多路唤醒控制增加一个新的宏IVW_PARALLEL_LINES_SUPPORT
3、针对唤醒资源头部授权信息的校验添加可以不校验的逻辑如果资源中有授权信息则进行校验如果没有但是提供的msc库编译时添加了宏IFLY_SPEECH_PLUS_SUPPORT则不进行校验否则仍校验。
---------------------------------------------------------------------
1.1114版本更新信息
1识别 a) 增加默认方言设置为 mandarin
2合成 a) 修改淡出字节没有根据采样率调整,而使不同采样率下长短不一的问题;
b) 修正MSC和语记之间切换时可能当前合成播放未停止的问题;
c) 在 ENGINE_TYPE 为 TYPE_DISTRIBUTED 时,默认进行网络检查;
3唤醒 a) 唤醒在音频缓存超过两秒时,清空当前消息中的音频数据, 避免OOM问题;
4录音 a) 修改录音检查时长判断方式,仅在返回字节小于缓存时; sleep避免可能不及时获取音频而缓存满丢失的问题
5AIMIC a) 增加线程优先级设置;
b) 修正在CPU占用较高时由于 frame_count 错误而引起角度不对的问题;
6音频检测 a) 模型VAD增加句子重设参数 RESET_SENTENCE
b) 模型VAD更新引擎和资源修正端点状态返回延迟可能超过 250 ms 的问题;
7日志a) 增加告警级别日志(目前仅在唤醒缓存不足时用到);
8文档a) HTML文档链接大部份在新窗口打开
b) 修改默认ENGINE_MODE 值说明;
c) 增加分布式模式参数值 TYPE_DISTRIBUTED ;
d) 音频检测,增加短音频过滤说明;修改前端点, 后端点值域;修改 start 结果值、状态值说明;每次写入音频长度说明;暂不使用 start 和 end 值说明;
9音频文件保存 a) 修正没有关闭文件句柄的问题;
10, Demo: a) 修正在线人脸 Demo 没有检查会话开始的错误,而一直等待的问题;
b) 音频检测 Demo 修改结果显示;
11错误码 AIMIC 错误码从26XXX改成27XXX
已知问题:
1音频检测 a) 当每次写入的字节比较大如500ms以上时获取的 seg 值不正确;
---------------------------------------------------------------------
1.1113版本更新信息
1唤醒 增加通过事件返回录音音频流参考《MSC Reference Manual.html》关于 WakeuperListener 接口 onEvent 函数说明;
2合成在暂停恢复停止时增加淡入淡出的效果优化播放体验
3demo 修正人脸DEMO由于服务返回结果为错误码而导致崩溃的问题修正在没有放置 libmsc.so 时DEMO因空指针引用而崩溃的问题
4初始化 去掉 Utility setParameter getParameter 时的单例判断,修正因此而导致获取参数和设置参数不生效的问题;
已知问题:
1在合成离线使用语记模式在线SDK默认离线功能使用语记从在线MSC模式合成未播放完马上使用离线语记模式合成时上一次在线合成播放没有被取消而是在当前合成语记模式播放完后继续播放
MSC 5.0.30.1153 更新信息:
1、将1152版本ssl内容同步回主版本nameserver以及结构化日志scs支持ssl加密
2、离线授权auth支持ssl加密业务短连接不计划支持即使设置了ssl如果走短连接也不生效
3、去除日志中认证信息的打印
4、支持SHA204A硬件授权方案
5、解决唤醒可能出现的16005问题论坛开发者反馈
6、代码优化发往服务端参数部分去除冗余逻辑
7、结构化日志里会添加进 几个字段记录的是socket建立后的一些统计信息用来辅助判断网络问题只在Linux和Android平台下收集
8、增加情感发言人设置 ssb 中传入emot
9、修复离线合成自动读取发言人在android平台报错问题
---------------------------------------------------------------------
1.1112版本更新信息
1所有业务功能 创建单例时,若 SpeechUtility.getUtility 为空,返回 null
2注销 SpeechUtility destroy 时先判断当前是否有会话进行修正因会话进行中注销而使SDK不可用的问题
3DEMO 听写 DEMO 提示中,去掉河南话;
4文档 a) VAD 检测功能加入未支持说明; b) 去掉 ISE_ENT以 LANGUAGE 代替;
5IVW 增加保存最近1分钟的音频IVW_AUDIO_PATH
6编译 修改混淆配置在Msc.pro 中,去掉唤醒相关的保留(减小在线 Msc.jar 大小在MscV5luse.pro中包含 Msc.pro 所有配置;
MSC 5.0.29.1151 更新信息:
1、合并张涛1049版本以及revision7804-7820功能点到主版本:
1)增加JNI日志级别函数; 林国雄
2)修改JNI日志打印把频繁打印的日志用INFO重要日志用LOGCAT; 林国雄
3)结构化日志上传支持代理设置 MSPLogin中设置 proxy_host/proxy_ip, proxy_port; 张涛
4) ist ise 在线tts 的ssb请求中 增加 fac参数用于强制 appid校验; 张涛
5)优化unique_id记录改为首次解析lgi_params时记录unique_id后续无需每次都解析lgi_params; 王逸群
6)评测在线合成延迟登录ssb中带入auth_id 张涛
7)更新模型VAD引擎增加置信度函数增加 vad_reduce_flow 参数 张涛,林国雄
2、车载反馈偶尔获取不到结果问题修复
---------------------------------------------------------------------
1.1111版本更新信息
1asr: a) 删除没有使用到的 MscRecognizerAIMic.java 及其引用;
b) 修改前端点消除时的音频处理从独立的线程转回 MscHandler 线程中,并修改可能重复返回同一音频的问题;
2文档开放语义文档更新至语义官网上最新的版本
MSC 5.0.28.1150 更新信息:
1. 回退到1148的代码版本
2. 基于1148代码上解决sessinfo没有传入正确的sid的问题
---------------------------------------------------------------------
1.1110版本更新信息
1ivwa) 修正 SDK 设置的 IVW_NETVAL 覆盖外面设置值的问题;
2aimic a) 修正 aimic BUF_MODE没有设置到JNI的问题
b) 增加无效结果错误码;
c) 减少原始音频的缓存大小;
d) 应用层不直接使用 aimic 的函数, 识别音频通过唤醒事件返回;
e) aimic.jar 合并到 msc.jar中作为唤醒的一部分
f) 增加当前缓存中留存数据大小的日志;
g) 修正在非持续唤醒时因录音机重复开启时状态值没有设置为0而返回 26008 的问题;
h) 修正在 buf_mode=2 时,还会因原始音频缓存不够而返回 26014 错误的问题;
i) 修改调用 alsa 录音的方式从直接引用改为反射调用编译时默认不带 alsa 的类
3日志 a) 调整日志级别,默认为 normal只打印关键的会话日志AUW等频繁打印的日志只在 detail 或 all 级别时打印;
4文档 a) 去掉 HTML 文档中 河南话;
b) 去掉 HTML 文档中 DOMAIN 的默认值说明;
c) PDF 文档中去掉Q群网址改为论坛
5模型VAD a) 增加置信度结果 confidence 和对应的 Native 函数(因 5.2.0.1032 libmsc.so 不带该 Native 函数,此版本 confidence 值全部为0
b) 修改音量值范围修正因引擎变化音量值最大只到7的问题
6asr a) 修改获取默BOS, EOS的方式;
b) 在消除前端点静音时,禁用 libmsc.so 中的VAD直接使用模型VAD检测整个过程;
aimic jni 更新信息:
1增加禁止写入IVW音频的参数 ivw_auw_disable用于测试默认为 FALSE
2char 转 int 时,进行安全判断;
3增加无效结果判断返回 26019
4增加 ivw_sum_disable 参数,判断是否要启用 EOS 累计,适应 IVW 引擎的EOS值返回方式默认为 FALSE
5增加 ivw_sum_by_engine 参数,判断是否已在引擎中累计 EOS 值 ,默认为 TRUE
6增加 唤醒结果全部转为 KEY=VALUE 方式,传给 CAE且 frame_count 一直累计,传给 CAE 时不对1000求余
7 libaimic.so 与 libaimicjni.so 合并为 libaimic.so
8增加线程等待把原来的每一毫秒的SLEEP改成直接等有数据再处理减少空闲时线程对 CPU 的占用;
9增加销毁线程前判断上次的唤醒消息是否有回调完避免因引用音频BUF而崩溃的问题
10 增加 ivw_auw_sync 参数,判断是否要把三个唤醒线程同步,默认为 TRUE
11 增加 AIMIC 未处理唤醒消息时的,返回错误 26018
msc 5.2.0.1032 更新信息:
1、升级唤醒引擎集成5.0.1016版本新增支持英文唤醒资源分为common资源和唤醒词资源common资源不加头英文和中文不同的common资源目前只支持windows和Android不支持linux
2、唤醒闭环优化上传逻辑优化车载需求实现通过参数控制每天上传上传成功的数据条数
3、唤醒闭环优化功能可裁剪IVWNET_NOT_SUPPORT=1
4、QIVWGetResInfo内存泄漏修复
5、离线授权在连接超时情况下报错16005问题修复
---------------------------------------------------------------------
1.1109版本更新信息
1使用 5.0.27.1146 构建 online, mfv, ifd 1109 版本;
---------------------------------------------------------------------
1.1108版本更新信息
1合成增加设置保存预合成音频文件名的参数
MSC更新信息
5.0.27.1146 (不带 VAD 接口)
1、在所有在线业务的ssb请求参数段中添加unique_id字段。
2、"语音云服务端通过nameserver下发ip并新增标识字段""compel""表示是否强制使用80端口。若没有强制使用80端口则由msc自行选择合适的port建立连接1028传输数据。
3、新增当网络类型切换重新进行dns请求。
4、现网ns版本协议号由1.2升级为1.3。
---------------------------------------------------------------------
1.1107 版本更新信息
1录音当录音时返回负值状态时直接抛出异常
2JNI添加AIUI相关的接口仅 Native 定义);
3有数数据采集a) 包由 com.iflytek.thirdparty 移动到 com.iflytek.cloud.thirdparty; b) 捕获异常的 Exception 改为 Throwable
4AIMICa) 主版本与 AIMIC 分支合并; b) aimic 增加 ALSA JNI 日志控制;
5使用 5.0.26.1144 版本库;
MSC更新信息
5.0.26.1144
"基于1133版本维护AIMIC分支版本
1、AIMIC多路唤醒优化修改多路版唤醒会话对象维护方式同识别合成业务去除业务全局锁消除锁带来的性能消耗多路版情况下QISRSessionBegin耗时优化尤为明显。5.0.27.1134加入)
2、唤醒闭环优化唤醒闭环优化5.0.27.1139加入)
1、上传逻辑优化
2、通过参数控制每天上传上传成功的数据条数
3、修改后的详细逻辑参见文档《唤醒闭环客户端唤醒词音频收集及上传.docx》以及《上传数据详细设计.vsd》
3、唤醒闭环优化功能支持裁剪通过宏IVWNET_NOT_SUPPORT裁剪默认包含闭环优化目前裁剪只支持windowslinuxandroid
windows在msc_lua工程添加此宏5.0.27.1134加入)
4、修复QIVWGetResInfo接口的内存泄漏
通过MSPStrSplit函数解析后的数据内存未释放5.0.27.1134加入)
5、离线授权在连接超时情况下报错16005问题修复5.0.27.1135加入)
6、解决在线业务慢问题dns解析问题详细见5.0.27.1139版本修复说明。5.0.27.1139加入)"
7、升级BN唤醒引擎运算量优化版本4.0.1017
---------------------------------------------------------------------
1.1106 版本更新信息
1配置项 a) Setting 中增加设置当前地区的函数 setLocale b) 优化日志类的实现和设置方式,把 Setting 从日志类的分离出来;
2闭环唤醒 a) 修正查询资源时,在更新资源后,没有使用新资源信息来查询的问题;
3合成 a) 优化在获取MSC的合成信息有可能为负数时重置为0 b) 增加返回进度的精度控制参数 tts_proc_scale 默认值与原来不变100
4人脸 a) 会话时增加设置URL参数
5VAD增加VAD检测DEMO开放VAD功能
MSC更新信息
5.0.27.1141
1、将唤醒业务回退到1135版本唤醒引擎回退到4.0.1007唤醒闭环部分除了修复若干问题其他未做修改与1139一致
2、修复唤醒闭环上传模块若干bug
3开启闭环唤醒参数ivwnet_mode=1上传失败情况下保存到本地数据>2M时未丢弃数据
4断开网络执行用例ivw_upload.log日志中显示数据上传失败未将上传失败的数据保存至本地生成ivwnet.txt文件直接丢弃数据
5.0.27.1143
1、解决中文繁体以及英文windows操作系统下离线识别问题
2、QIVWGetResInfo接口只对Android控件开放若需要测试需要修改msc_lua.defwindows和msc.maplinux
3、更新MetaVad代码
4、解决断网时稳定性测试ISR会句柄数一直增加的问题
5、重构sessinfo"
6、解决听写指定aud=raw时多过一次VAD的问题VAD在 isr.lua中先配置并滤过一次
---------------------------------------------------------------------
1.1105 版本更新信息
1修正调用 destroy 时,崩溃的问题;
2闭环唤醒修正查询哪个资源更新时原始资源目录不对的问题在没有配置项时默认进行资源查询
MSC 5.0.26.1140 修改:
基于1133版本维护车载唤醒分支版本
1、升级唤醒引擎集成5.0.1016版本新增支持英文唤醒资源分为common资源和唤醒词资源common资源不加头英文和中文不同的common资源目前只支持windows和Android不支持linux
2、唤醒闭环优化上传逻辑优化车载需求实现通过参数控制每天上传上传成功的数据条数
3、唤醒闭环优化功能可裁剪IVWNET_NOT_SUPPORT=1
4、QIVWGetResInfo内存泄漏修复
5、离线授权在连接超时情况下报错16005问题修复
6、车载反馈在线语义听写慢问题解决
---------------------------------------------------------------------
1.1104 for aimic 版本更新信息:
1更新AIMIC库不修改 NEW 传进来的 UserData,保证那参数是 NULL时也能正常运行在角度回调里通过 param1 把 beam 回调给外面;
2修改 AIMIC JNI每路唤醒使用单独线程进行音频和消息回调使用单独线程进行唤醒音频直接在 JNI 处理,减少音频队列和唤醒结果回调的耗时;修正内存泄漏等;
3更新 MSC 5.0.16.1133,减少唤醒写音频耗时,修正由于阻塞而使缓存用完报错的问题;
4优化缓存的内存占用
5增加 AIMic Reference Manual.html AlsaRecorder Reference Manual.html 文档;
6增加 AIMicDemo
7src 目录新增 AimicTest 测试工具以及AIMIC模块的源码AIMicLibsrcAIMIC_JNI
---------------------------------------------------------------------
1.1103 版本更新信息
1、语义理解语义理解 ASR_UNDERSTAND 参数名,改为 ASR_SCH
2、合成回调合成到文件的打断错误时增加是否在主线程判断在主线程时可避免 在 onComplete 中开启新会话时,死循环而崩溃的问题;非主线程回调时,依然会出现此问题(目前需要应用来避免这种调用);
3、合成增加 tts_min_audio_len 参数可设置合成最短的缓存时长修改默认最短缓存音频时长由原来20秒左右改为60秒以兼容在线合成在指定的符号下返回音频长度与文本长度没有关系的合成情景
4、唤醒优化闭环查询和使用服务器资源修改默认查询间隔为 24 小时;并在当前本地已下载网络资源,且 net_mode 为模式 2 时,网络资源比本地资源新时, 直接使用下载的资源,而不必每次要查询更新才能使用;
5、唤醒在文档和DEMO中去掉 net_mode 参数值中的 模式 2 说明,此模式只在高级用户中告知其使用;
6、编译保留 VolumeUtil FileDownloadListener 两个类;
7、logcat 日志:有数采集 和 MMLC 在获取 MSC 参数失败时的 ERROR 日志,改成 DEBUG 日志不影响SDK使用避免误导开发者
8、JavaDoc语法识别增加网页生成语法的使用说明修改 JavaDoc 概览页作者字样,通过 JS 控制可替换成 灵犀云;
9、有数采集灵犀云修改有数采集逻辑以兼容灵犀SDK分支的数据采集讯飞云版本SDK中不进行有数采集
MSC 5.0.27.1139 修改:
升级唤醒引擎:
1、集成5.0.1016版本;
2、新增支持英文唤醒
3、资源分为common资源和唤醒词资源common资源不加头英文和中文不同的common资源
4、路径参数设置需要传入common资源和唤醒词资源路径且common资源必须放在前面例如ivw_res_path =fo|res/ivw/IvwCommonRes.irf|0|0;fo|res/ivw/ivModel.xiaoainihao.irf.head|0|0
已知问题:
1在调用 SpeechRecognizer, SpeechSynthesizer, VoiceWakeuper 的 destory 销毁引擎时,底层库 MSC 概率性崩溃;
---------------------------------------------------------------------
1.1102 版本更新信息
1、语记链接参数添加设备信息
---------------------------------------------------------------------
1.1101 版本更新信息
1、语音合成修复合成空文本导致的异常问题
2、SDK优化离线功能授权机制
3、SDK优化在会话线程启动时增加异常抛出
4、SDK优化编译指令兼容AS最新版本编译
5、录音机模块修复部分机型上无权限时获取数据不报错问题
6、优化获取版本失败日志改为私有日志
7、有界面识别对象音量回调增加非空判断
---------------------------------------------------------------------
1.1100 版本更新信息
1、语音识别新增模型VAD
2、修复文本语义频繁调用卡死问题
3、修改获取网络类型的参数的逻辑
关于平台1129唤醒支持注意事项
1、1129版本能够加载3.6老资源但不支持3.5老资源;
2、3.6老资源支持闭环优化必须每个词都要设置唤醒门限值否者未设置门限唤醒词唤醒会出问题返回错误码16005
---------------------------------------------------------------------
1.1099 版本更新信息
1、修复SpeechUtility创建异常问题
2、身份验证鉴别功能新增海量鉴别功能
3、优化文档及部分开放类注释说明
---------------------------------------------------------------------
1.1098 版本更新信息
1、MSC修复与第三方jar混淆冲突问题
2、数据收集增加在createUtility进行收集
3、数据收集修复应用列表上传时间设置无效
4、数据收集修复开启统计无法关闭问题
5、数据收集取消GET_TASKS权限判断
6、语音合成修正频繁调用合成播放导致OOM问题
---------------------------------------------------------------------
1.1097 版本更新信息
1、身份验证鉴别功能新增查询用户、退出组、删除组接口
2、移除日志收集权限检查
3、语音合成修改语速倍速方法兼容5.5引擎;
4、修改20002超时错误提示
5、优化消息优先级去除min等级
---------------------------------------------------------------------
1.1096 版本更新信息
1、离线合成引擎升级为aisound 6.0 pro
2、离线识别引擎升级为aitalk two
3、修复特殊设备调用系统API崩溃问题
4、修复getVersion返回不正确问题
5、优化唯一ID中mac地址为动态获取
---------------------------------------------------------------------
1.1093~1.1095 版本更新信息
1、新增应用列表及活跃应用收集功能
2、新增鉴别错误码及错误码描述
---------------------------------------------------------------------
1.1092 版本更新信息
1、唤醒业务增加了推荐门限
2、唤醒业务优化查询和下载内存问题
3、评测业务修改startEvaluating返回值为int类型
4、评测业务修改取消方法为cancel()
5、声纹、评测、身份验证接口调用添加非空判断
---------------------------------------------------------------------
1.1091 版本更新信息
1、增加鉴别功能
2、优化唤醒业务添加强制请求策略不与缓存文件进行比较
3、优化唤醒业务查询和下载接口添加同步锁
4、优化唤醒业务startListening接口增加返回错误码
5、修复评测和声纹业务内部读取文件数据无法中断问题
---------------------------------------------------------------------
1.1089 版本更新信息
1、优化离线人脸返回结果格式
2、支持每个业务setParameter设置engineMode
3、优化文档及部分开放类注释说明
4、修改获取版本号的方法
---------------------------------------------------------------------
1.1088 版本更新信息
1、开放唤醒持续优化功能支持资源持续优化提升唤醒效果
2、修改唤醒业务开启默认不获取音频焦点
3、优化离线人脸视频流接口支持关键点信息参数控制
4、优化命令词识别中是否传入语法判断条件
5、有数数据收集、编解码及VAD模块同步至主版本
---------------------------------------------------------------------
1.1087 版本更新信息
1、集成UniqueID模块增加Manifest权限
2、在线合成增加情感发音人小艾SpeechConstant新增EMOT情感参数
3、在线合成改为只走MSC以解决语记在部分手机后台被限制网络权限的问题
小米MIUI设置->其他高级选项->电量和性能->神隐模式)
---------------------------------------------------------------------
1.1086 版本更新信息
1、使用最新离线人脸so文件支持64位
2、优化部分低端机器上视频流检测不可用问题
3、优化图片检测及视频流检测的返回结果
4、修复图片检测判断条件防止出现空指针
5、优化身份验证参数传递降低CPU使用率
6、SpeechModuleAidl增加异常处理防止启动崩溃
7、优化异常日志输出e.printStackTrace() 改为logE控制输出
8、业务调度Handler增加捕获NATIVE引用的错误
---------------------------------------------------------------------
1.1085 版本更新
1、使用msc版本1101版本测试so增加闭环上传音频
2、添加获取msc引擎版本方法暂不开放
3、开放对外文件下载类回调监听FileDownloadListener
4、唤醒业务改为从SessionBegin启动引擎
5、唤醒业务增加闭环优化网络模式ivw_net_mode参数
6、唤醒业务增加请求闭环模型功能
7、唤醒业务增加下载唤醒模型功能
---------------------------------------------------------------------
1.1084 版本更新
1、修改错误码拼写错误
2、在ResourceUtil添加唤醒资源路径
3、增加身份验证传递网络类型
4、增加获取引擎版本号接口。通过SpeechUtility.getParameter实现
5、增加参数view_tips_plain控制是否在UI中显示错误码
6、解决ASR_NOMATCH_ERROR不生效的问题
7、增加1.login传递基站信息
8、增加本地授权错误码
9、修正注释
---------------------------------------------------------------------
1.1083 版本更新
1.使用msc版本1109版本so增加证书功能
2.修正SpeakerVerifier类注释中有误的地方
3.修正SpeakerVerifier类cancel函数带boolean参数的问题
---------------------------------------------------------------------
1.1082 版本更新
1、唤醒支持Ivw4.0引擎使用msc版本1101
2、接口方法注释信息详细请见代码注释或者javaDoc
3、修改音频数据音量计算方法
---------------------------------------------------------------------
1.1081_release 版本更新
1、关闭动态修正ASR_DWA参数修改Demo及相应说明修改
2、完善v5版本对外接口方法注释信息详细请见代码注释或者javaDoc
---------------------------------------------------------------------
1.1081 版本更新
1、上传字段添加基站信息mmlc
2、完善对外接口方法注释信息
3、修改synthesizerToUri合成无音频时空格、英文发音人合成中文等情况抛出10118错误
---------------------------------------------------------------------
1.1080 版本更新
1、使用1101版本离线功能so库
2、去除v5和v5+判断条件
3、详细部分类的注释说明
---------------------------------------------------------------------
1.1079 版本更新信息
1.接口&参数调整:
1、 新增SpeechUtility增加同步锁
2、 新增prot_ver=50的默认参数设置
3、 新增通过onEvent接口抛出音频数据
4、 新增通过onEvent接口抛出session id
5、 修改onVolumeChange接口回调增加buffer
6、 修改声纹key值ISV_AUDIOPATH为ISV_AUDIO_PATH
7、 修改缓存音频逻辑详见TTS_BUFFER_TIME参数说明
8、 修改人脸、声纹用户id Key值使用新Key值AUTH_ID参数
2.功能优化:
1、 修改性能日志模块
2、 新增load库的错误日志
3、 修改关于防止int数据溢出的代码
4、 修复userwords类无法插入空内容的缺陷
5、 修改constant.TEXT字段移到内部msckeys中
3.语记相关:
1、 修改语音+下载地址为语记新地址
2、 修改语音+action为语记的新action
---------------------------------------------------------------------
1.1077 版本更新信息
1.联系人增加destroy接口
2.支持保存音频wav格式
3.将是否通知异常打断的参数名称由ASR_INTERRUPT_ERROR改为MFV_INTERRUPT_ERROR
4.修改部分注释及去除VerifierUtil中旋转方法,移动FaceRect类和绘图方法至demo
5.去掉对IdentityVerifier中MSC是否已经加载的判断
6.人脸和融合验证错误码和描述
7.混淆文件打开身份验证和工具类
---------------------------------------------------------------------
1.1076 版本更新信息
---------------------------------------------------------------------
1.1075 版本更新信息
1.离线人脸测试稳定版本;
2.离线人脸检测支持图片和视频流;
---------------------------------------------------------------------
1.1074 版本更新信息
1.离线人脸检测能力融合至msc
2.离线人脸检测支持图片和视频流;
3.移除离线人脸关键点检测能力;
---------------------------------------------------------------------
1.1073 版本更新信息
1.合成Aisound合成音频无尾部静音导致读最后一个字很短min基础上增加4KB的静音块。
2.注释完善,官网链接修改。
3.人脸删除离线人脸JNI类保留外部接口类混淆离线人脸接口。
4.语音+避免客户端在使用语音功能的同时语音服务被异常打断造成mService为null的空指针错误
5.优化:
1、将listener置空解决无法释放context的问题2、修改onBeginOfSpeech回调判断快速stop
2、修复int值计算溢出导致播放进度为负值问题
3、增加SSB传递 msc.skin字段
6.性能测试唤醒、声纹、转写、识别、评测添加SessionBeginEnd字段
7.lib_name 对外开放,建议预装软件修改名称
---------------------------------------------------------------------
1.1072 版本更新信息
1.在线听写增加结果动态修正功能;
2.修复SpeechUtility在子线程中创建崩溃的bug
3.cancel前进行判断避免打印errorlog;
4.新增检查语音+时错误码:20020,表示系统预装版本语音+;
5.优化参数注释;
6.删除获取通话记录的接口和观察者;
---------------------------------------------------------------------
1.1071 版本更新信息
1.修正由于读音频比当前播放块多引起CED比音频快的问题
2.修改打包工具根据v5+/语音+来设置engine_mode
3.增加唤醒注册功能(未完成);
4.评测新增两个字段在Demo中解析
---------------------------------------------------------------------
1.1070 版本更新信息
1.使用1089版本so库;
2.新手指南文档修改;
3.语音评测demo修改;
4.修复本地合成多客户端切换调用导致的应用崩溃问题;
5.修改msc_1088版本ced获取方式;
6.评测增加20秒网络超时超时报20002;
---------------------------------------------------------------------
1.1068 版本更新信息
1.使用1086版本so库;
2.增加语音评测接口;
3.增加人脸识别接口;
4.更换1086版ced获取接口;
5.合成UNICODE去除两个字节头部解决ced不准问题;
6.删除地图区域参数area_key;
---------------------------------------------------------------------
1.1067 v5+版本更新信息
1.使用1042版本so库;
2.增加体验包功能;
---------------------------------------------------------------------
1.1063 v5+版本更新信息
1.本地合成语速扩充到0-200
2.初始化时对调用进程名称进行判断,解决由第三方库造成的子进程重复调用问题;
3.修复部分情况下无onEndOfSpeech回调的bug
4.修复在个别手机上获取联系人出错的Bug;
---------------------------------------------------------------------
1.1058 v5+版本更新信息
1.增加本地合成功能;
---------------------------------------------------------------------
1.1057 v5+版本更新信息
1.增加本地命令词功能;
2.增加唤醒+本地命令词识别功能;
---------------------------------------------------------------------
1.1048 v5+版本更新信息
1.使用v5+实现本地能力;
2.优化响应速度,节省用户流量;
---------------------------------------------------------------------
1.1039版本更新信息
1.调整代码,优化接口调用耗时;
2.修复异常调用情况的错误码;
3.更新文档和demo
---------------------------------------------------------------------
1.1038版本更新信息
1.修复检测语音+安装bug
2.文档更新;
---------------------------------------------------------------------
1.1037版本更新信息
1.调整整体识别框架,提升识别效率;
2.提供云+端识别能力;
3.增加错误码提示文字;
4.文档更新;
5.demo重新编写完善;
---------------------------------------------------------------------
1.1032版本更新信息
1.精简so库尺寸
2.增加错误码;
3.修复上次识别立马开始下次识别可能报10132错误的问题
---------------------------------------------------------------------
1.1031版本更新信息
1.修复TextUnderstander非主线程回调的问题
2.增加合成语调参数;
3.默认发音人设置;
4.优化底层协议交互,提升响应时间;
---------------------------------------------------------------------
1.1030版本更新信息
1.修复合成打断失败问题;
2.优化识别和合成效果;
---------------------------------------------------------------------
1.1029版本更新信息
1.增加错误码中文注释;
2.修复部分public字段被混淆的问题
3.增加开放语义2.0协议文档和Demo
---------------------------------------------------------------------
1.1028版本更新信息
1.进一步精简Jar尺寸至179K
2.支持通过参数设置开放语义2.0协议;
3.修复内测版本功能及接口测试过程中发现的问题;
4.完善API手册和新手指南
---------------------------------------------------------------------
1.1027版本更新信息
1.整合语音控件、讯飞语音+、跨平台语音+的错误码文件ErrorCode更新错误提示
2.精简语音控件尺寸由400K减至200K
3.开放无UI的识别、合成接口增加语音转语义SpeechUnderstander和文本转语义TextUnderstander接口
4.传参接口修改为setParameter公用参数通过SpeechConstant类读取相关说明更新在JavaDoc中
5.修改UI界面使用新版简洁风格摒弃“按钮”点击操作通过“点触屏幕”完成相同功能
6.修改识别、合成的引擎参数使用language、domain等
7.支持实时改变合成音频播放的StreamType声音类型
8.支持实时改变语音识别的AudioSource声源
9.提供外部写录音文件接口,同时支持保存识别、合成的音频;
10.修改回调接口删除onEnd等接口在JavaDoc和新手指南中增加相关说明
11.优化底层协议代码,提供识别响应速度;
12.识别和语义返回原始结果通过外部应用层进行解析示例代码更新至MscDemo
---------------------------------------------------------------------
1.1026版本更新信息
1.修复合成缓冲状态下不可以暂停的问题;
2.对Android4.4机型进行适配,优化相关代码兼容性;
---------------------------------------------------------------------
1.1026版本更新信息
1.初始化接口修改为SpeechUser#Login转写、合成服务之前均需要调用
2.优化客户端响应速度;
3.更新Demo和开发文档中初始化部分说明
---------------------------------------------------------------------
1.1025.Lua版本更新信息
1.初始化接口修改为SpeechUser#Login转写、合成服务之前均需要调用
2.优化客户端响应速度;
3.更新Demo和开发文档中初始化部分说明
---------------------------------------------------------------------
1.1025版本更新信息
1.优化识别接口封装,增加连接成功率;
2.SpeechListener类名修改为TextUnderstander
---------------------------------------------------------------------
1.1024版本更新信息
1.优化个性化转写的成功率;
---------------------------------------------------------------------
1.1023版本更新信息
1.优化识别响应时间;
2.更新开发文档,修正部分错误描述;
---------------------------------------------------------------------
1.1022版本更新信息
1.优化客户端调度,提升识别的响应速度;
2.增加系统未安装浏览器情况下,点击"详细"的跳转提示;
---------------------------------------------------------------------
1.1021版本更新信息
1.优化数据上传接口,提升上传的成功率;
---------------------------------------------------------------------
1.1020版本更新信息
1.对网络进行优化解决报20019网络繁忙的问题
---------------------------------------------------------------------
1.1019版本更新信息
1.支持设置识别界面取消按钮的左右位置;
2.支持参数控制音频播放方式和音频焦点的获取;
---------------------------------------------------------------------
1.1018版本更新信息
1、增加联系人ContactManager和用户词表UserWords的个性化接口;
2、增加个性化接口的说明文档并在Demo中添加相关示例代码
3、适配Android2.2版本以上的AudioFocus机制
---------------------------------------------------------------------
1.1017版本更新信息
1、优化网络连接解决长时间录音异常
2、解决部分机器抛出的内存不足错误
---------------------------------------------------------------------
1.1016版本更新信息
1、解决TTS连续播放异常
2、更改默认皮肤
3、优化wap网络成功率
4、优化合成及识别流程提高会话成功率。
---------------------------------------------------------------------
1.1015版本更新信息
1、解决上一版本1.5系统出现的不兼容问题;
2、支持Abnf语法文件上传获得语法ID进行识别
3、解决TTS播放过程中连续调用合成引起的问题。
---------------------------------------------------------------------
1.1013版本更新信息
1、解决Android 4.0部分机型TTS合成颤音的问题
2、处理器支持

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<ImageView
android:id="@+id/ifly_mnotice_image_container"
android:layout_width="match_parent"
android:scaleType="fitXY"
android:layout_height="match_parent"/>
</RelativeLayout>

Binary file not shown.

Binary file not shown.

@ -0,0 +1,39 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.iflytek.mscv5plusdemo"
minSdkVersion 16
targetSdkVersion 30
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
}
dependencies {
implementation files('libs/Msc.jar')
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.4.0'
}

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<lint></lint>

@ -0,0 +1,101 @@
## Copyright (C) 2001-2010 iFLYTEK.
## Use ';' and '#' character for notation
## Note: Commands in this cfg file is case sensitive
[local]
timeout = 15000
pre_connect = 0
search_best_url = 0
upload_info = 1
[aiui]
#aiui_sync_url = http://172.16.154.43:8080/sync/v1/upload.do
#aiui_third_url = http://172.16.154.10:8080/sync/v1/syncthird.do
#aiui_prs_url = http://172.16.154.17:1289/aiui/prs/app/v1/upload.do
#aiui_opsync_url = https://172.16.154.21:443/athena/opsync
##<23><><EFBFBD><EFBFBD>
#aiui_up_url = http://aiui.openspeech.cn:1032/aiui/v1/upload.do
#aiui_pushnode_url = http://aiui.openspeech.cn:80/aiui/v1/pushnode.do
#aiui_chid_url = https://aiui.openspeech.cn:443/v1.1/server/register
##<23><><EFBFBD>Ի<EFBFBD><D4BB><EFBFBD>
#aiui_up_url = http://172.16.154.43:1032/aiui/v1/upload.do
#aiui_pushnode_url = http://172.16.154.43:80/aiui/v1/pushnode.do
#aiui_chid_url = http://172.16.154.43:443/v1.1/server/register
##aiui<75><69>־
#no_sessinfodata = 1
sessinfodata = sessinfo.txt
##<23><><EFBFBD><EFBFBD><EFBFBD>ʱʱ<CAB1><CAB1>
rslt_timeout = 5000
##<23><>ȡchid<69><64>ʱ
chid_timeout = 3000
##<23><>ȡpushnode<64><65>ʱ
pushnode_timeout = 3000
##<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
down_stream_timeout = 20000
##<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʱ<EFBFBD><CAB1>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD><EFBFBD>
up_stream_req_timeout = 50000
##<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʱ<EFBFBD><CAB1>û<EFBFBD><C3BB><EFBFBD>յ<EFBFBD><D5B5><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ڵȴ<DAB5><C8B4><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD><EFBFBD><EFBFBD>
up_stream_resp_timeout = 3000
##<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>һ<EFBFBD><D2BB>ʱ<EFBFBD><CAB1>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
heart_beat_timeout = 15000
##׼<><D7BC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʱ<EFBFBD><CAB1>֮<EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD>ʹ<EFBFBD>Ѿ<EFBFBD>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD>Ҳ<EFBFBD><D2B2>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD><EFBFBD>Ϊû<CEAA><C3BB>׼<EFBFBD><D7BC><EFBFBD>ã<EFBFBD><C3A3><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>
ready_delay_timeout = 1
##<23><>ȡchid<69>쳣ʱ<ECB3A3><CAB1><EFBFBD><EFBFBD>ʱһ<CAB1><D2BB>ʱ<EFBFBD><CAB1><EFBFBD>ٴ<EFBFBD><D9B4><EFBFBD><EFBFBD><EFBFBD>
chid_delay_reset_timeout = 3000
##<23><>ȡpushnode<64>쳣ʱ<ECB3A3><CAB1><EFBFBD><EFBFBD>ʱһ<CAB1><D2BB>ʱ<EFBFBD><CAB1><EFBFBD>ٴ<EFBFBD><D9B4><EFBFBD><EFBFBD><EFBFBD>
pushnode_delay_reset_timeout = 3000
##<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ʱ<EFBFBD><CAB1>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>»<EFBFBD>ȡchid<69><64>pushnode<64><65>Ĭ<EFBFBD><C4AC>ֵ42000000<30><30>11Сʱ40<34><30><EFBFBD>ӣ<EFBFBD>
reset_chid_pushnode_timeout = 42000000
##stmid_q<5F>е<EFBFBD>Ԫ<EFBFBD>س<EFBFBD><D8B3><EFBFBD><EFBFBD><EFBFBD>ֵʱ<D6B5><CAB1><EFBFBD><EFBFBD>ǰ<EFBFBD>ʼɾ<CABC><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC>stmidͬʱ<CDAC><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ֵ20
stmid_q_max = 20
[tts]
##<23>ϳ<EFBFBD><CFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD>Χ(0, 4096]<5D><>Ĭ<EFBFBD><C4AC>ֵ1024<32><34>
max_text_size = 1024
##<23><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1>غϳ<D8BA>ʱ<EFBFBD><CAB1>Ч<EFBFBD><D0A7>Ϊÿ<CEAA>η<EFBFBD><CEB7>ص<EFBFBD><D8B5><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ݴ<EFBFBD>С<EFBFBD><D0A1>
buff_size = 8192
[asr]
##<23><><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD>λByte<74><65><EFBFBD><EFBFBD>Χ(0, 1MB]<5D><>Ĭ<EFBFBD><C4AC>ֵ256KB
max_audio_size = 262144
##<23><>С<EFBFBD><D0A1>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD>λByte<74><65><EFBFBD><EFBFBD>Χ(0, max_audio_size]<5D><>Ĭ<EFBFBD><C4AC>ֵ5KB
coding_chunk_size = 5120
##<23>Ƿ<EFBFBD>ʹ<EFBFBD><CAB9>VAD<41><44><EFBFBD>ж˵<D0B6><CBB5><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD><DFBD><EFBFBD>
vad_enable = true
##<23><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3B7A8>ģʽ<C4A3><CABD>audio_coding<6E><67>coding_levelȡֵ<C8A1><D6B5>Χ<EFBFBD><CEA7><EFBFBD>±<EFBFBD><C2B1><EFBFBD>ʾ<EFBFBD><CABE>Ĭ<EFBFBD><C4AC>ֵ<EFBFBD>ֱ<EFBFBD>Ϊspeex-wb<77><62>7<EFBFBD><37>
# ----------------------------------
# | audio_coding | coding_level |
# ----------------------------------
# | speex | 0-10 |
# | speex-wb | 0-10 |
# | raw | <20><>Ч |
# ----------------------------------
audio_coding = speex-wb
coding_level = 7
[hcr]
##<23><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3>ȣ<EFBFBD><C8A3><EFBFBD>λByte<74><65><EFBFBD><EFBFBD>Χ(0, 16KB]<5D><>Ĭ<EFBFBD><C4AC>ֵ8KB
max_data_size = 8192
[isv]
##<23><><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD>λByte<74><65><EFBFBD><EFBFBD>Χ(0, 2MB]<5D><>Ĭ<EFBFBD><C4AC>ֵ512KB
max_audio_size = 524288
##<23><>С<EFBFBD><D0A1>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ȣ<EFBFBD><C8A3><EFBFBD>λByte<74><65><EFBFBD><EFBFBD>Χ(0, max_audio_size]<5D><>Ĭ<EFBFBD><C4AC>ֵ5KB
coding_chunk_size = 5120
##<23><>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3B7A8>ģʽ<C4A3><CABD>audio_coding<6E><67>coding_levelȡֵ<C8A1><D6B5>Χ<EFBFBD><CEA7><EFBFBD>Բο<D4B2>asr<73><72>
audio_coding = speex-wb
coding_level = 7
[logger]
##<23><><EFBFBD><EFBFBD>û<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>ôMSC<53><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC>־<EFBFBD><D6BE>Ϣ
file = msc.log
title = Mobile Speech Client
level = -1
output = 1
filter = -1
style = -1
flush = 0
maxsize = 104857600
overwrite = 1
maxfile =

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.iflytek.mscv5plusdemo"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:icon="@drawable/icon"
android:name="SpeechApp"
android:label="讯飞语音示例v5+">
<activity
android:name="com.iflytek.mscv5plusdemo.MainActivity"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale"
android:icon="@drawable/icon"
android:label="讯飞语音示例v5+"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.iflytek.speech.setting.TtsSettings"/>
<activity android:name="com.iflytek.speech.setting.IatSettings"/>
<activity
android:name="com.iflytek.mscv5plusdemo.IatDemo"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale"
android:screenOrientation="portrait"/>
<activity
android:name="com.iflytek.mscv5plusdemo.AsrDemo"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale"
android:screenOrientation="portrait"/>
<activity
android:name="com.iflytek.mscv5plusdemo.TtsDemo"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale"
android:screenOrientation="portrait"/>
<activity
android:name="com.iflytek.mscv5plusdemo.IvwActivity"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale"
android:screenOrientation="portrait"/>
<activity
android:name="com.iflytek.mscv5plusdemo.WakeDemo"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale"
android:screenOrientation="portrait"/>
<activity
android:name="com.iflytek.mscv5plusdemo.OneShotDemo"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|fontScale"
android:screenOrientation="portrait"/>
</application>
</manifest>

@ -0,0 +1,12 @@
#BNF+IAT 1.0 UTF-8;
!grammar call;
!slot <contact>;
!slot <callPre>;
!slot <callPhone>;
!slot <callTo>;
!start <callStart>;
<callStart>:[<callPre>][<callTo>]<contact><callPhone>|[<callPre>]<callPhone>[<callTo>]<contact>;
<contact>:张海洋;
<callPre>:我要|我想|我想要;
<callPhone>:打电话;
<callTo>:给;

@ -0,0 +1,8 @@
#ABNF 1.0 UTF-8;
language zh-CN;
mode voice;
root $main;
$main = $place1 到 $place2;
$place1 = 北京|武汉|南京|天津|东京;
$place2 = 上海|合肥;

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<ImageView
android:id="@+id/ifly_mnotice_image_container"
android:layout_width="match_parent"
android:scaleType="fitXY"
android:layout_height="match_parent"/>
</RelativeLayout>

@ -0,0 +1 @@
{"userword":[{"name":"我的常用词","words":["佳晨实业","蜀南庭苑","高兰路","复联二"]},{"name":"我的好友","words":["李馨琪","鹿晓雷","张集栋","周家莉","叶震珂","熊泽萌"]}]}

@ -0,0 +1,8 @@
#BNF+IAT 1.0 UTF-8;
!grammar wake;
!slot <callCmd>;
!slot <contact>;
!start <callStart>;
<callStart>:[<callCmd>]<callName>;
<callCmd>:讯飞语音|讯飞语点|叮咚叮咚;
<callName>:张三|李四|张海洋;

@ -0,0 +1,8 @@
#ABNF 1.0 UTF-8;
language zh-CN;
mode voice;
root $main;
$main = [$call] $name;
$call = 讯飞语音|讯飞语点|叮咚叮咚;
$name = 张三|李四|张海洋;

@ -0,0 +1,386 @@
package com.iflytek.mscv5plusdemo;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
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.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 final static String TAG = AsrDemo.class.getSimpleName();
private Toast mToast;
// 语音识别对象
private SpeechRecognizer mAsr;
// 缓存
private SharedPreferences mSharedPreferences;
// 本地语法文件
private String mLocalGrammar = null;
// 本地词典
private String mLocalLexicon = null;
// 云端语法文件
private String mCloudGrammar = null;
// 本地语法构建路径
private String grmPath;
// 返回结果格式支持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";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.isrdemo);
initLayout();
grmPath = getExternalFilesDir("msc").getAbsolutePath() + "/test";
// 初始化识别对象
mAsr = SpeechRecognizer.createRecognizer(this, mInitListener);
if (mAsr == null) {
Log.e(TAG, "masr is null");
}
// 初始化语法、命令词
mLocalLexicon = "张海羊\n刘婧\n王锋";
mLocalGrammar = FucUtil.readFile(this, "call.bnf", "utf-8");
mCloudGrammar = FucUtil.readFile(this, "grammar_sample.abnf", "utf-8");
mSharedPreferences = getSharedPreferences(getPackageName(), MODE_PRIVATE);
}
/**
* 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 + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
}
// 在线-构建语法文件生成语法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 + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
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 + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
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 + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
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 + ",请点击网址https://www.xfyun.cn/document/error-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 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());
} else {
text = 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(() -> {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT);
mToast.show();
});
}
/**
*
*
* @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权限
mAsr.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
mAsr.setParameter(SpeechConstant.ASR_AUDIO_PATH,
getExternalFilesDir("msc").getAbsolutePath() + "/asr.wav");
return result;
}
//获取识别资源路径
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() {
if (null != mAsr) {
// 退出时释放连接
mAsr.cancel();
mAsr.destroy();
}
super.onDestroy();
}
}

@ -0,0 +1,375 @@
package com.iflytek.mscv5plusdemo;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
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.Toast;
import com.iflytek.cloud.ErrorCode;
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.SpeechEvent;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.ui.RecognizerDialog;
import com.iflytek.cloud.ui.RecognizerDialogListener;
import com.iflytek.cloud.util.ResourceUtil;
import com.iflytek.speech.setting.IatSettings;
import com.iflytek.speech.util.FucUtil;
import com.iflytek.speech.util.JsonParser;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.LinkedHashMap;
public class IatDemo extends Activity implements OnClickListener {
private static String TAG = "IatDemo";
// 语音听写对象
private SpeechRecognizer mIat;
// 语音听写UI
private RecognizerDialog mIatDialog;
// 听写结果内容
private EditText mResultText;
// 用HashMap存储听写结果
private HashMap<String, String> mIatResults = new LinkedHashMap<>();
private SharedPreferences mSharedPreferences;
private Toast mToast;
private String mEngineType = "cloud";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.iatdemo);
initLayout();
// 初始化识别无UI识别对象
// 使用SpeechRecognizer对象可根据回调消息自定义界面
mIat = SpeechRecognizer.createRecognizer(this, mInitListener);
// 初始化听写Dialog如果只使用有UI听写功能无需创建SpeechRecognizer
// 使用UI听写功能请根据sdk文件目录下的notice.txt,放置布局文件和图片资源
mIatDialog = new RecognizerDialog(this, mInitListener);
mSharedPreferences = getSharedPreferences(IatSettings.PREFER_NAME, Activity.MODE_PRIVATE);
mResultText = ((EditText) findViewById(R.id.iat_text));
}
/**
* Layout
*/
private void initLayout() {
findViewById(R.id.iat_recognize).setOnClickListener(this);
findViewById(R.id.iat_recognize_stream).setOnClickListener(this);
findViewById(R.id.iat_upload_userwords).setOnClickListener(this);
findViewById(R.id.iat_stop).setOnClickListener(this);
findViewById(R.id.iat_cancel).setOnClickListener(this);
findViewById(R.id.image_iat_set).setOnClickListener(this);
//选择云端or本地
RadioGroup group = (RadioGroup) this.findViewById(R.id.iat_radioGroup);
group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.iat_radioCloud) {
findViewById(R.id.iat_upload_userwords).setEnabled(true);
mEngineType = SpeechConstant.TYPE_CLOUD;
} else if (checkedId == R.id.iat_radioLocal) {
//离线听写不支持联系人/热词上传
findViewById(R.id.iat_upload_userwords).setEnabled(false);
mEngineType = SpeechConstant.TYPE_LOCAL;
}
}
});
}
int ret = 0;// 函数调用返回值
@Override
public void onClick(View view) {
if (null == mIat) {
// 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
this.showTip("创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化");
return;
}
switch (view.getId()) {
// 进入参数设置页面
case R.id.image_iat_set:
Intent intents = new Intent(IatDemo.this, IatSettings.class);
startActivity(intents);
break;
// 开始听写
// 如何判断一次听写结束OnResult isLast=true 或者 onError
case R.id.iat_recognize:
mResultText.setText(null);// 清空显示内容
mIatResults.clear();
// 设置参数
setParam();
boolean isShowDialog = mSharedPreferences.getBoolean(getString(R.string.pref_key_iat_show), true);
if (isShowDialog) {
// 显示听写对话框
mIatDialog.setListener(mRecognizerDialogListener);
mIatDialog.show();
showTip(getString(R.string.text_begin));
} else {
// 不显示听写对话框
ret = mIat.startListening(mRecognizerListener);
if (ret != ErrorCode.SUCCESS) {
showTip("听写失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
} else {
showTip(getString(R.string.text_begin));
}
}
break;
// 音频流识别
case R.id.iat_recognize_stream:
mResultText.setText(null);// 清空显示内容
mIatResults.clear();
// 设置参数
setParam();
// 设置音频来源为外部文件
mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");
// 也可以像以下这样直接设置音频文件路径识别要求设置文件在sdcard上的全路径
// mIat.setParameter(SpeechConstant.AUDIO_SOURCE, "-2");
// mIat.setParameter(SpeechConstant.ASR_SOURCE_PATH, "sdcard/XXX/XXX.pcm");
ret = mIat.startListening(mRecognizerListener);
if (ret != ErrorCode.SUCCESS) {
showTip("识别失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
return;
}
try {
InputStream open = getAssets().open("iattest.wav");
byte[] buff = new byte[1280];
while (open.available() > 0) {
int read = open.read(buff);
mIat.writeAudio(buff, 0, read);
}
mIat.stopListening();
} catch (IOException e) {
mIat.cancel();
showTip("读取音频流失败");
}
break;
// 停止听写
case R.id.iat_stop:
mIat.stopListening();
showTip("停止听写");
break;
// 取消听写
case R.id.iat_cancel:
mIat.cancel();
showTip("取消听写");
break;
// 上传用户词表
case R.id.iat_upload_userwords:
showTip(getString(R.string.text_upload_userwords));
String contents = FucUtil.readFile(IatDemo.this, "userwords", "utf-8");
mResultText.setText(contents);
// 指定引擎类型
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
// 置编码类型
mIat.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
ret = mIat.updateLexicon("userword", contents, mLexiconListener);
if (ret != ErrorCode.SUCCESS) {
showTip("上传热词失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
break;
default:
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 + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
}
};
/**
* /
*/
private LexiconListener mLexiconListener = new LexiconListener() {
@Override
public void onLexiconUpdated(String lexiconId, SpeechError error) {
if (error != null) {
showTip(error.toString());
} else {
showTip(getString(R.string.text_upload_success));
}
}
};
/**
*
*/
private RecognizerListener mRecognizerListener = new RecognizerListener() {
@Override
public void onBeginOfSpeech() {
// 此回调表示sdk内部录音机已经准备好了用户可以开始语音输入
showTip("开始说话");
}
@Override
public void onError(SpeechError error) {
// Tips
// 错误码10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
showTip(error.getPlainDescription(true));
}
@Override
public void onEndOfSpeech() {
// 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
showTip("结束说话");
}
@Override
public void onResult(RecognizerResult results, boolean isLast) {
String text = JsonParser.parseIatResult(results.getResultString());
mResultText.append(text);
mResultText.setSelection(mResultText.length());
if (isLast) {
//TODO 最后的结果
}
}
@Override
public void onVolumeChanged(int volume, byte[] data) {
showTip("当前正在说话,音量大小:" + volume);
Log.d(TAG, "返回音频数据:" + data.length);
}
@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_AUDIO_URL);
Log.d(TAG, "session id =" + sid);
}
}
};
/**
* UI
*/
private RecognizerDialogListener mRecognizerDialogListener = new RecognizerDialogListener() {
public void onResult(RecognizerResult results, boolean isLast) {
Log.d(TAG, "recognizer result" + results.getResultString());
String text = JsonParser.parseIatResult(results.getResultString());
mResultText.append(text);
mResultText.setSelection(mResultText.length());
}
/**
* .
*/
public void onError(SpeechError error) {
showTip(error.getPlainDescription(true));
}
};
private void showTip(final String str) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT);
mToast.show();
}
});
}
/**
*
*
* @return
*/
public void setParam() {
// 清空参数
mIat.setParameter(SpeechConstant.PARAMS, null);
String lag = mSharedPreferences.getString("iat_language_preference", "mandarin");
// 设置引擎
mIat.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
// 设置返回结果格式
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
//mIat.setParameter(MscKeys.REQUEST_AUDIO_URL,"true");
// this.mTranslateEnable = mSharedPreferences.getBoolean( this.getString(R.string.pref_key_translate), false );
if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) {
// 设置本地识别资源
mIat.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
}
// 在线听写支持多种小语种若想了解请下载在线听写能力参看其speechDemo
if (lag.equals("en_us")) {
// 设置语言
mIat.setParameter(SpeechConstant.LANGUAGE, "en_us");
mIat.setParameter(SpeechConstant.ACCENT, null);
// 设置语言
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
// 设置语言区域
mIat.setParameter(SpeechConstant.ACCENT, lag);
}
// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
mIat.setParameter(SpeechConstant.VAD_BOS, mSharedPreferences.getString("iat_vadbos_preference", "4000"));
// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
mIat.setParameter(SpeechConstant.VAD_EOS, mSharedPreferences.getString("iat_vadeos_preference", "1000"));
// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
mIat.setParameter(SpeechConstant.ASR_PTT, mSharedPreferences.getString("iat_punc_preference", "1"));
// 设置音频保存路径保存音频格式支持pcm、wav设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
mIat.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
mIat.setParameter(SpeechConstant.ASR_AUDIO_PATH,
getExternalFilesDir("msc").getAbsolutePath() + "/iat.wav");
}
private String getResourcePath() {
StringBuffer tempBuffer = new StringBuffer();
//识别通用资源
tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "iat/common.jet"));
tempBuffer.append(";");
tempBuffer.append(ResourceUtil.generateResourcePath(this, ResourceUtil.RESOURCE_TYPE.assets, "iat/sms_16k.jet"));
//识别8k资源-使用8k的时候请解开注释
return tempBuffer.toString();
}
@Override
protected void onDestroy() {
if (null != mIat) {
// 退出时释放连接
mIat.cancel();
mIat.destroy();
}
super.onDestroy();
}
}

@ -0,0 +1,52 @@
package com.iflytek.mscv5plusdemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.Toast;
import com.iflytek.cloud.VoiceWakeuper;
public class IvwActivity extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.ivw_activity);
((Button) findViewById(R.id.btn_wake)).setOnClickListener(IvwActivity.this);
((Button) findViewById(R.id.btn_oneshot)).setOnClickListener(IvwActivity.this);
}
@Override
public void onClick(View v) {
if (null == VoiceWakeuper.createWakeuper(this, null)) {
// 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
Toast.makeText(this
, "创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化"
, Toast.LENGTH_LONG).show();
return;
}
Intent intent;
switch (v.getId()) {
case R.id.btn_wake:
intent = new Intent(IvwActivity.this, WakeDemo.class);
startActivity(intent);
break;
case R.id.btn_oneshot:
intent = new Intent(IvwActivity.this, OneShotDemo.class);
startActivity(intent);
break;
default:
break;
}
}
}

@ -0,0 +1,85 @@
package com.iflytek.mscv5plusdemo;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.Window;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
initView();
requestPermissions();
}
private void initView() {
TextView tipTv = (TextView) findViewById(R.id.tip);
String buf = "离线 Demo\n" +
"当前APPID为" +
getString(R.string.app_id) + "\n" +
getString(R.string.example_explain);
tipTv.setText(buf);
// 语音转写
findViewById(R.id.iatBtn).setOnClickListener(v -> {
startActivity(new Intent(MainActivity.this, IatDemo.class));
});
// 语法识别
findViewById(R.id.asrBtn).setOnClickListener(v -> {
startActivity(new Intent(MainActivity.this, AsrDemo.class));
});
// 语义理解
findViewById(R.id.nlpBtn).setOnClickListener(v -> {
showTip("请登录http://www.xfyun.cn/ 下载aiui体验吧");
});
// 语音合成
findViewById(R.id.ttsBtn).setOnClickListener(v -> {
startActivity(new Intent(MainActivity.this, TtsDemo.class));
});
// 增强版语音合成 xtts
findViewById(R.id.xttsBtn).setOnClickListener(v -> {
startActivity(new Intent(MainActivity.this, TtsDemo.class));
});
// 唤醒
findViewById(R.id.ivwBtn).setOnClickListener(v -> {
startActivity(new Intent(MainActivity.this, IvwActivity.class));
});
}
private Toast mToast;
private void showTip(final String str) {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT);
mToast.show();
}
private void requestPermissions() {
try {
if (Build.VERSION.SDK_INT >= 23) {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.RECORD_AUDIO
}, 0x0010);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

@ -0,0 +1,364 @@
package com.iflytek.mscv5plusdemo;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.GrammarListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechEvent;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.VoiceWakeuper;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.WakeuperResult;
import com.iflytek.cloud.util.ResourceUtil;
import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;
import com.iflytek.speech.util.JsonParser;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.InputStream;
public class OneShotDemo extends Activity implements OnClickListener {
private String TAG = "ivw";
private Toast mToast;
private TextView textView;
// 语音唤醒对象
private VoiceWakeuper mIvw;
// 语音识别对象
private SpeechRecognizer mAsr;
// 唤醒结果内容
private String resultString;
// 识别结果内容
private String recoString;
// 设置门限值 门限值越低越容易被唤醒
private TextView tvThresh;
private SeekBar seekbarThresh;
private final static int MAX = 3000;
private final static int MIN = 0;
private int curThresh = 1450;
private String threshStr = "门限值:";
// 云端语法文件
private String mCloudGrammar = null;
// 云端语法id
private String mCloudGrammarID;
// 本地语法id
private String mLocalGrammarID;
// 本地语法文件
private String mLocalGrammar = null;
// 本地语法构建路径
private String grmPath;
// 引擎类型
private String mEngineType = SpeechConstant.TYPE_CLOUD;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.oneshot_activity);
initUI();
grmPath = getExternalFilesDir("msc").getAbsolutePath() + "/test";
// 初始化唤醒对象
mIvw = VoiceWakeuper.createWakeuper(this, null);
// 初始化识别对象---唤醒+识别,用来构建语法
mAsr = SpeechRecognizer.createRecognizer(this, null);
// 初始化语法文件
mCloudGrammar = readFile(this, "wake_grammar_sample.abnf", "utf-8");
mLocalGrammar = readFile(this, "wake.bnf", "utf-8");
}
private void initUI() {
findViewById(R.id.btn_oneshot).setOnClickListener(OneShotDemo.this);
findViewById(R.id.btn_stop).setOnClickListener(OneShotDemo.this);
findViewById(R.id.btn_grammar).setOnClickListener(OneShotDemo.this);
textView = (TextView) findViewById(R.id.txt_show_msg);
tvThresh = (TextView) findViewById(R.id.txt_thresh);
seekbarThresh = (SeekBar) findViewById(R.id.seekBar_thresh);
seekbarThresh.setMax(MAX - MIN);
seekbarThresh.setProgress(curThresh);
tvThresh.setText(threshStr + curThresh);
seekbarThresh.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar arg0) {
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
}
@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
curThresh = seekbarThresh.getProgress() + MIN;
tvThresh.setText(threshStr + curThresh);
}
});
//选择云端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) {
mEngineType = SpeechConstant.TYPE_CLOUD;
} else if (checkedId == R.id.radioLocal) {
mEngineType = SpeechConstant.TYPE_LOCAL;
}
}
});
}
GrammarListener grammarListener = new GrammarListener() {
@Override
public void onBuildFinish(String grammarId, SpeechError error) {
if (error == null) {
if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
mCloudGrammarID = grammarId;
} else {
mLocalGrammarID = grammarId;
}
showTip("语法构建成功:" + grammarId);
} else {
showTip("语法构建失败,错误码:" + error.getErrorCode() + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
}
};
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_oneshot:
// 非空判断,防止因空指针使程序崩溃
mIvw = VoiceWakeuper.getWakeuper();
if (mIvw != null) {
resultString = "";
recoString = "";
textView.setText(resultString);
final String resPath = ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, "ivw/" + getString(R.string.app_id) + ".jet");
// 清空参数
mIvw.setParameter(SpeechConstant.PARAMS, null);
// 设置识别引擎
mIvw.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
// 设置唤醒资源路径
mIvw.setParameter(ResourceUtil.IVW_RES_PATH, resPath);
/**
* id:;id:
* demo
*/
mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:"
+ curThresh);
// 设置唤醒+识别模式
mIvw.setParameter(SpeechConstant.IVW_SST, "oneshot");
// 设置返回结果格式
mIvw.setParameter(SpeechConstant.RESULT_TYPE, "json");
//
// mIvw.setParameter(SpeechConstant.IVW_SHOT_WORD, "0");
// 设置唤醒录音保存路径,保存最近一分钟的音频
mIvw.setParameter(SpeechConstant.IVW_AUDIO_PATH,
getExternalFilesDir("msc").getAbsolutePath() + "/ivw.wav");
mIvw.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
if (!TextUtils.isEmpty(mCloudGrammarID)) {
// 设置云端识别使用的语法id
mIvw.setParameter(SpeechConstant.CLOUD_GRAMMAR,
mCloudGrammarID);
mIvw.startListening(mWakeuperListener);
} else {
showTip("请先构建语法");
}
} else {
if (!TextUtils.isEmpty(mLocalGrammarID)) {
// 设置本地识别资源
mIvw.setParameter(ResourceUtil.ASR_RES_PATH,
getResourcePath());
// 设置语法构建路径
mIvw.setParameter(ResourceUtil.GRM_BUILD_PATH, grmPath);
// 设置本地识别使用语法id
mIvw.setParameter(SpeechConstant.LOCAL_GRAMMAR,
mLocalGrammarID);
mIvw.startListening(mWakeuperListener);
} else {
showTip("请先构建语法");
}
}
} else {
showTip("唤醒未初始化");
}
break;
case R.id.btn_grammar:
int ret = 0;
if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
// 设置参数
mAsr.setParameter(SpeechConstant.ENGINE_TYPE, mEngineType);
mAsr.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
// 开始构建语法
ret = mAsr.buildGrammar("abnf", mCloudGrammar, grammarListener);
if (ret != ErrorCode.SUCCESS) {
showTip("语法构建失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
} else {
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);
// 设置资源路径
mAsr.setParameter(ResourceUtil.ASR_RES_PATH, getResourcePath());
ret = mAsr.buildGrammar("bnf", mLocalGrammar, grammarListener);
if (ret != ErrorCode.SUCCESS) {
showTip("语法构建失败,错误码:" + ret + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
}
break;
case R.id.btn_stop:
mIvw = VoiceWakeuper.getWakeuper();
if (mIvw != null) {
mIvw.stopListening();
} else {
showTip("唤醒未初始化");
}
break;
default:
break;
}
}
private WakeuperListener mWakeuperListener = new WakeuperListener() {
@Override
public void onResult(WakeuperResult result) {
try {
String text = result.getResultString();
JSONObject object;
object = new JSONObject(text);
StringBuffer buffer = new StringBuffer();
buffer.append("【RAW】 " + text);
buffer.append("\n");
buffer.append("【操作类型】" + object.optString("sst"));
buffer.append("\n");
buffer.append("【唤醒词id】" + object.optString("id"));
buffer.append("\n");
buffer.append("【得分】" + object.optString("score"));
buffer.append("\n");
buffer.append("【前端点】" + object.optString("bos"));
buffer.append("\n");
buffer.append("【尾端点】" + object.optString("eos"));
resultString = buffer.toString();
} catch (JSONException e) {
resultString = "结果解析出错";
e.printStackTrace();
}
textView.setText(resultString);
}
@Override
public void onError(SpeechError error) {
showTip(error.getPlainDescription(true));
}
@Override
public void onBeginOfSpeech() {
showTip("开始说话");
}
@Override
public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
Log.d(TAG, "eventType:" + eventType + "arg1:" + isLast + "arg2:" + arg2);
// 识别结果
if (SpeechEvent.EVENT_IVW_RESULT == eventType) {
RecognizerResult reslut = ((RecognizerResult) obj.get(SpeechEvent.KEY_EVENT_IVW_RESULT));
recoString += JsonParser.parseGrammarResult(reslut.getResultString());
textView.setText(recoString);
}
}
@Override
public void onVolumeChanged(int volume) {
// TODO Auto-generated method stub
}
};
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy OneShotDemo");
mIvw = VoiceWakeuper.getWakeuper();
if (mIvw != null) {
mIvw.destroy();
} else {
showTip("唤醒未初始化");
}
}
/**
* asset
*
* @return content
*/
public static String readFile(Context mContext, String file, String code) {
int len = 0;
byte[] buf = null;
String result = "";
try {
InputStream in = mContext.getAssets().open(file);
len = in.available();
buf = new byte[len];
in.read(buf, 0, len);
result = new String(buf, code);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
// 获取识别资源路径
private String getResourcePath() {
StringBuffer tempBuffer = new StringBuffer();
// 识别通用资源
tempBuffer.append(ResourceUtil.generateResourcePath(this,
RESOURCE_TYPE.assets, "asr/common.jet"));
return tempBuffer.toString();
}
private void showTip(final String str) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT);
mToast.show();
}
});
}
}

@ -0,0 +1,75 @@
package com.iflytek.mscv5plusdemo;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechUtility;
public class SpeechApp extends Application {
@Override
public void onCreate() {
init();
// 应用程序入口处调用,避免手机内存过小,杀死后台进程后通过历史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(SpeechApp.this, param.toString());
super.onCreate();
}
private void init() {
// 打印日志
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
Log.d("Activity Resumed ----- ", activity.getClass().getName());
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
});
}
}

@ -0,0 +1,420 @@
package com.iflytek.mscv5plusdemo;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
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.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechEvent;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
import com.iflytek.cloud.util.ResourceUtil;
import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;
import com.iflytek.speech.setting.TtsSettings;
public class TtsDemo extends Activity implements OnClickListener {
private static String TAG = TtsDemo.class.getSimpleName();
// 语音合成对象
private SpeechSynthesizer mTts;
// 默认云端发音人
public static String voicerCloud = "xiaoyan";
// 默认本地发音人
public static String voicerLocal = "xiaoyan";
public static String voicerXtts = "xiaoyan";
// 云端发音人列表
private String[] cloudVoicersEntries;
private String[] cloudVoicersValue;
// 本地发音人列表
private String[] localVoicersEntries;
private String[] localVoicersValue;
// 增强版发音人列表
private String[] xttsVoicersEntries;
private String[] xttsVoicersValue;
//缓冲进度
private int mPercentForBuffering = 0;
//播放进度
private int mPercentForPlaying = 0;
// 云端/本地选择按钮
private RadioGroup mRadioGroup;
// 引擎类型
private String mEngineType = SpeechConstant.TYPE_CLOUD;
private Toast mToast;
private SharedPreferences mSharedPreferences;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.ttsdemo);
initLayout();
// 初始化合成对象
mTts = SpeechSynthesizer.createSynthesizer(this, mTtsInitListener);
// 云端发音人名称列表
cloudVoicersEntries = getResources().getStringArray(R.array.voicer_cloud_entries);
cloudVoicersValue = getResources().getStringArray(R.array.voicer_cloud_values);
// 本地发音人名称列表
localVoicersEntries = getResources().getStringArray(R.array.voicer_local_entries);
localVoicersValue = getResources().getStringArray(R.array.voicer_local_values);
// 增强版发音人名称列表
xttsVoicersEntries = getResources().getStringArray(R.array.voicer_xtts_entries);
xttsVoicersValue = getResources().getStringArray(R.array.voicer_xtts_values);
mSharedPreferences = getSharedPreferences(TtsSettings.PREFER_NAME, Activity.MODE_PRIVATE);
}
/**
* Layout
*/
private void initLayout() {
findViewById(R.id.tts_play).setOnClickListener(this);
findViewById(R.id.tts_cancel).setOnClickListener(this);
findViewById(R.id.tts_pause).setOnClickListener(this);
findViewById(R.id.tts_resume).setOnClickListener(this);
findViewById(R.id.image_tts_set).setOnClickListener(this);
findViewById(R.id.tts_btn_person_select).setOnClickListener(this);
mRadioGroup = ((RadioGroup) findViewById(R.id.tts_rediogroup));
mRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.tts_radioCloud:
mEngineType = SpeechConstant.TYPE_CLOUD;
break;
case R.id.tts_radioLocal:
mEngineType = SpeechConstant.TYPE_LOCAL;
break;
case R.id.tts_radioXtts:
mEngineType = SpeechConstant.TYPE_XTTS;
break;
default:
break;
}
}
});
}
@Override
public void onClick(View view) {
if (null == mTts) {
// 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=9688
this.showTip("创建对象失败,请确认 libmsc.so 放置正确,\n 且有调用 createUtility 进行初始化");
return;
}
switch (view.getId()) {
case R.id.image_tts_set:
Intent intent = new Intent(TtsDemo.this, TtsSettings.class);
startActivity(intent);
break;
// 开始合成
// 收到onCompleted 回调时,合成结束、生成合成音频
// 合成的音频格式只支持pcm格式
case R.id.tts_play:
String text = ((EditText) findViewById(R.id.tts_text)).getText().toString();
// 设置参数
setParam();
Log.d(TAG, "准备点击: " + System.currentTimeMillis());
int code = mTts.startSpeaking(text, mTtsListener);
// /**
// * 只保存音频不进行播放接口,调用此接口请注释startSpeaking接口
// * text:要合成的文本uri:需要保存的音频全路径listener:回调接口
// */
// String path = getExternalFilesDir("msc").getAbsolutePath() + "/tts.pcm";
// int code = mTts.synthesizeToUri(text, path, mTtsListener);
if (code != ErrorCode.SUCCESS) {
showTip("语音合成失败,错误码: " + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
}
break;
// 取消合成
case R.id.tts_cancel:
mTts.stopSpeaking();
break;
// 暂停播放
case R.id.tts_pause:
mTts.pauseSpeaking();
break;
// 继续播放
case R.id.tts_resume:
mTts.resumeSpeaking();
break;
// 选择发音人
case R.id.tts_btn_person_select:
showPersonSelectDialog();
break;
}
}
private static int selectedNumCloud = 0;
private static int selectedNumLocal = 0;
/**
*
*/
private void showPersonSelectDialog() {
switch (mRadioGroup.getCheckedRadioButtonId()) {
// 选择在线合成
case R.id.tts_radioCloud:
new AlertDialog.Builder(this).setTitle("在线合成发音人选项")
.setSingleChoiceItems(cloudVoicersEntries, // 单选框有几项,各是什么名字
selectedNumCloud, // 默认的选项
new DialogInterface.OnClickListener() { // 点击单选框后的处理
public void onClick(DialogInterface dialog,
int which) { // 点击了哪一项
voicerCloud = cloudVoicersValue[which];
if ("catherine".equals(voicerCloud) || "henry".equals(voicerCloud) || "vimary".equals(voicerCloud)) {
((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source_en);
} else {
((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source);
}
selectedNumCloud = which;
dialog.dismiss();
}
}).show();
break;
// 选择本地合成
case R.id.tts_radioLocal:
new AlertDialog.Builder(this).setTitle("本地合成发音人选项")
.setSingleChoiceItems(localVoicersEntries, // 单选框有几项,各是什么名字
selectedNumLocal, // 默认的选项
new DialogInterface.OnClickListener() { // 点击单选框后的处理
public void onClick(DialogInterface dialog,
int which) { // 点击了哪一项
voicerLocal = localVoicersValue[which];
if ("catherine".equals(voicerLocal) || "henry".equals(voicerLocal) || "vimary".equals(voicerLocal)) {
((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source_en);
} else {
((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source);
}
selectedNumLocal = which;
dialog.dismiss();
}
}).show();
break;
case R.id.tts_radioXtts:
new AlertDialog.Builder(this).setTitle("增强版合成发音人选项")
.setSingleChoiceItems(xttsVoicersEntries, // 单选框有几项,各是什么名字
selectedNumLocal, // 默认的选项
new DialogInterface.OnClickListener() { // 点击单选框后的处理
public void onClick(DialogInterface dialog,
int which) { // 点击了哪一项
voicerXtts = xttsVoicersValue[which];
//Toast.makeText(this,voicerXtts,Toast.LENGTH_LONG);
System.out.println("sssssss:" + voicerXtts);
if ("catherine".equals(voicerXtts) || "henry".equals(voicerXtts) || "vimary".equals(voicerXtts)) {
((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source_en);
} else {
((EditText) findViewById(R.id.tts_text)).setText(R.string.text_tts_source);
}
selectedNumLocal = which;
dialog.dismiss();
}
}).show();
break;
default:
break;
}
}
/**
*
*/
private InitListener mTtsInitListener = new InitListener() {
@Override
public void onInit(int code) {
Log.d(TAG, "InitListener init() code = " + code);
if (code != ErrorCode.SUCCESS) {
showTip("初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
} else {
// 初始化成功之后可以调用startSpeaking方法
// 注有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成
// 正确的做法是将onCreate中的startSpeaking调用移至这里
}
}
};
/**
*
*/
private SynthesizerListener mTtsListener = new SynthesizerListener() {
@Override
public void onSpeakBegin() {
//showTip("开始播放");
Log.d(TtsDemo.TAG, "开始播放:" + System.currentTimeMillis());
}
@Override
public void onSpeakPaused() {
showTip("暂停播放");
}
@Override
public void onSpeakResumed() {
showTip("继续播放");
}
@Override
public void onBufferProgress(int percent, int beginPos, int endPos,
String info) {
// 合成进度
mPercentForBuffering = percent;
showTip(String.format(getString(R.string.tts_toast_format),
mPercentForBuffering, mPercentForPlaying));
}
@Override
public void onSpeakProgress(int percent, int beginPos, int endPos) {
// 播放进度
mPercentForPlaying = percent;
showTip(String.format(getString(R.string.tts_toast_format),
mPercentForBuffering, mPercentForPlaying));
}
@Override
public void onCompleted(SpeechError error) {
if (error == null) {
showTip("播放完成");
} else {
showTip(error.getPlainDescription(true));
}
}
@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_AUDIO_URL);
Log.d(TAG, "session id =" + sid);
}
//实时音频流输出参考
/*if (SpeechEvent.EVENT_TTS_BUFFER == eventType) {
byte[] buf = obj.getByteArray(SpeechEvent.KEY_EVENT_TTS_BUFFER);
Log.e("MscSpeechLog", "buf is =" + buf);
}*/
}
};
private void showTip(final String str) {
runOnUiThread(() -> {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT);
mToast.show();
});
}
/**
*
*/
private void setParam() {
// 清空参数
mTts.setParameter(SpeechConstant.PARAMS, null);
//设置合成
if (mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
//设置使用云端引擎
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, voicerCloud);
} else if (mEngineType.equals(SpeechConstant.TYPE_LOCAL)) {
//设置使用本地引擎
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
//设置发音人资源路径
mTts.setParameter(ResourceUtil.TTS_RES_PATH, getResourcePath());
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, voicerLocal);
} else {
mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_XTTS);
//设置发音人资源路径
mTts.setParameter(ResourceUtil.TTS_RES_PATH, getResourcePath());
//设置发音人
mTts.setParameter(SpeechConstant.VOICE_NAME, voicerXtts);
}
//mTts.setParameter(SpeechConstant.TTS_DATA_NOTIFY,"1");//支持实时音频流抛出仅在synthesizeToUri条件下支持
//设置合成语速
mTts.setParameter(SpeechConstant.SPEED, mSharedPreferences.getString("speed_preference", "50"));
//设置合成音调
mTts.setParameter(SpeechConstant.PITCH, mSharedPreferences.getString("pitch_preference", "50"));
//设置合成音量
mTts.setParameter(SpeechConstant.VOLUME, mSharedPreferences.getString("volume_preference", "50"));
//设置播放器音频流类型
mTts.setParameter(SpeechConstant.STREAM_TYPE, mSharedPreferences.getString("stream_preference", "3"));
// mTts.setParameter(SpeechConstant.STREAM_TYPE, AudioManager.STREAM_MUSIC+"");
// 设置播放合成音频打断音乐播放默认为true
mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");
// 设置音频保存路径保存音频格式支持pcm、wav设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH,
getExternalFilesDir("msc").getAbsolutePath() + "/tts.pcm");
}
//获取发音人资源路径
private String getResourcePath() {
StringBuffer tempBuffer = new StringBuffer();
String type = "tts";
if (mEngineType.equals(SpeechConstant.TYPE_XTTS)) {
type = "xtts";
}
//合成通用资源
tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, type + "/common.jet"));
tempBuffer.append(";");
//发音人资源
if (mEngineType.equals(SpeechConstant.TYPE_XTTS)) {
tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, type + "/" + TtsDemo.voicerXtts + ".jet"));
} else {
tempBuffer.append(ResourceUtil.generateResourcePath(this, RESOURCE_TYPE.assets, type + "/" + TtsDemo.voicerLocal + ".jet"));
}
return tempBuffer.toString();
}
@Override
protected void onDestroy() {
if (null != mTts) {
mTts.stopSpeaking();
// 退出时释放连接
mTts.destroy();
}
super.onDestroy();
}
}

@ -0,0 +1,315 @@
package com.iflytek.mscv5plusdemo;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
import com.iflytek.cloud.RequestListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechEvent;
import com.iflytek.cloud.VoiceWakeuper;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.WakeuperResult;
import com.iflytek.cloud.util.ResourceUtil;
import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
public class WakeDemo extends Activity implements OnClickListener {
private String TAG = "ivw";
private Toast mToast;
private TextView textView;
// 语音唤醒对象
private VoiceWakeuper mIvw;
// 唤醒结果内容
private String resultString;
// 设置门限值 门限值越低越容易被唤醒
private TextView tvThresh;
private SeekBar seekbarThresh;
private final static int MAX = 3000;
private final static int MIN = 0;
private int curThresh = 1450;
private String threshStr = "门限值:";
private String keep_alive = "1";
private String ivwNetMode = "0";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.wake_activity);
initUi();
// 初始化唤醒对象
mIvw = VoiceWakeuper.createWakeuper(this, null);
}
private void initUi() {
findViewById(R.id.btn_start).setOnClickListener(this);
findViewById(R.id.btn_stop).setOnClickListener(this);
textView = (TextView) findViewById(R.id.txt_show_msg);
tvThresh = (TextView) findViewById(R.id.txt_thresh);
seekbarThresh = (SeekBar) findViewById(R.id.seekBar_thresh);
seekbarThresh.setMax(MAX - MIN);
seekbarThresh.setProgress(curThresh);
tvThresh.setText(threshStr + curThresh);
seekbarThresh.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar arg0) {
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
}
@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
curThresh = seekbarThresh.getProgress() + MIN;
tvThresh.setText(threshStr + curThresh);
}
});
RadioGroup group = (RadioGroup) findViewById(R.id.ivw_net_mode);
group.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup arg0, int arg1) {
/**
*
* 0
*
* 1
* sdkAPI使
* queryResourcedownloadResource
*
* 2
* 便使02
*/
switch (arg1) {
case R.id.mode_close:
ivwNetMode = "0";
break;
case R.id.mode_open:
ivwNetMode = "1";
break;
default:
break;
}
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
//非空判断,防止因空指针使程序崩溃
mIvw = VoiceWakeuper.getWakeuper();
if (mIvw != null) {
setRadioEnable(false);
resultString = "";
textView.setText(resultString);
// 清空参数
mIvw.setParameter(SpeechConstant.PARAMS, null);
// 唤醒门限值根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入
mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + curThresh);
// 设置唤醒模式
mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");
// 设置持续进行唤醒
mIvw.setParameter(SpeechConstant.KEEP_ALIVE, keep_alive);
// 设置闭环优化网络模式
mIvw.setParameter(SpeechConstant.IVW_NET_MODE, ivwNetMode);
// 设置唤醒资源路径
mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());
// 设置唤醒录音保存路径,保存最近一分钟的音频
mIvw.setParameter(SpeechConstant.IVW_AUDIO_PATH,
getExternalFilesDir("msc").getAbsolutePath() + "/ivw.wav");
mIvw.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
// 如有需要,设置 NOTIFY_RECORD_DATA 以实时通过 onEvent 返回录音音频流字节
//mIvw.setParameter( SpeechConstant.NOTIFY_RECORD_DATA, "1" );
// 启动唤醒
/* mIvw.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");*/
mIvw.startListening(mWakeuperListener);
} else {
showTip("唤醒未初始化");
}
break;
case R.id.btn_stop:
mIvw.stopListening();
// mIvw.writeAudio();
setRadioEnable(true);
break;
default:
break;
}
}
/**
*
* 12使
*/
public void queryResource() {
int ret = mIvw.queryResource(getResource(), requestListener);
showTip("updateResource ret:" + ret);
}
// 查询资源请求回调监听
private RequestListener requestListener = new RequestListener() {
@Override
public void onEvent(int eventType, Bundle params) {
// 以下代码用于获取查询会话id当业务出错时将会话id提供给技术支持人员可用于查询会话日志定位出错原因
//if(SpeechEvent.EVENT_SESSION_ID == eventType) {
// Log.d(TAG, "sid:"+params.getString(SpeechEvent.KEY_EVENT_SESSION_ID));
//}
}
@Override
public void onCompleted(SpeechError error) {
if (error != null) {
Log.d(TAG, "error:" + error.getErrorCode());
showTip(error.getPlainDescription(true));
}
}
@Override
public void onBufferReceived(byte[] buffer) {
try {
String resultInfo = new String(buffer, "utf-8");
Log.d(TAG, "resultInfo:" + resultInfo);
JSONTokener tokener = new JSONTokener(resultInfo);
JSONObject object = new JSONObject(tokener);
int ret = object.getInt("ret");
if (ret == 0) {
String uri = object.getString("dlurl");
String md5 = object.getString("md5");
Log.d(TAG, "uri:" + uri);
Log.d(TAG, "md5:" + md5);
showTip("请求成功");
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
private WakeuperListener mWakeuperListener = new WakeuperListener() {
@Override
public void onResult(WakeuperResult result) {
Log.d(TAG, "onResult");
if (!"1".equalsIgnoreCase(keep_alive)) {
setRadioEnable(true);
}
try {
String text = result.getResultString();
JSONObject object;
object = new JSONObject(text);
StringBuffer buffer = new StringBuffer();
buffer.append("【RAW】 " + text);
buffer.append("\n");
buffer.append("【操作类型】" + object.optString("sst"));
buffer.append("\n");
buffer.append("【唤醒词id】" + object.optString("id"));
buffer.append("\n");
buffer.append("【得分】" + object.optString("score"));
buffer.append("\n");
buffer.append("【前端点】" + object.optString("bos"));
buffer.append("\n");
buffer.append("【尾端点】" + object.optString("eos"));
resultString = buffer.toString();
} catch (JSONException e) {
resultString = "结果解析出错";
e.printStackTrace();
}
textView.setText(resultString);
}
@Override
public void onError(SpeechError error) {
showTip(error.getPlainDescription(true));
setRadioEnable(true);
}
@Override
public void onBeginOfSpeech() {
}
@Override
public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
switch (eventType) {
// EVENT_RECORD_DATA 事件仅在 NOTIFY_RECORD_DATA 参数值为 真 时返回
case SpeechEvent.EVENT_RECORD_DATA:
final byte[] audio = obj.getByteArray(SpeechEvent.KEY_EVENT_RECORD_DATA);
Log.i(TAG, "ivw audio length: " + audio.length);
break;
}
}
@Override
public void onVolumeChanged(int volume) {
}
};
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy WakeDemo");
// 销毁合成对象
mIvw = VoiceWakeuper.getWakeuper();
if (mIvw != null) {
mIvw.destroy();
}
}
private String getResource() {
final String resPath = ResourceUtil.generateResourcePath(WakeDemo.this, RESOURCE_TYPE.assets, "ivw/" + getString(R.string.app_id) + ".jet");
Log.d(TAG, "resPath: " + resPath);
return resPath;
}
private void showTip(final String str) {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mToast != null) {
mToast.cancel();
}
mToast = Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT);
mToast.show();
}
});
}
private void setRadioEnable(final boolean enabled) {
runOnUiThread(new Runnable() {
@Override
public void run() {
findViewById(R.id.ivw_net_mode).setEnabled(enabled);
findViewById(R.id.btn_start).setEnabled(enabled);
findViewById(R.id.seekBar_thresh).setEnabled(enabled);
}
});
}
}

@ -0,0 +1,40 @@
package com.iflytek.speech.setting;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
import android.view.Window;
import com.iflytek.mscv5plusdemo.R;
import com.iflytek.speech.util.SettingTextWatcher;
/**
*
*/
public class IatSettings extends PreferenceActivity implements OnPreferenceChangeListener {
public static final String PREFER_NAME = "com.iflytek.setting";
private EditTextPreference mVadbosPreference;
private EditTextPreference mVadeosPreference;
@SuppressWarnings("deprecation")
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(PREFER_NAME);
addPreferencesFromResource(R.xml.iat_setting);
mVadbosPreference = (EditTextPreference) findPreference("iat_vadbos_preference");
mVadbosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this, mVadbosPreference, 0, 10000));
mVadeosPreference = (EditTextPreference) findPreference("iat_vadeos_preference");
mVadeosPreference.getEditText().addTextChangedListener(new SettingTextWatcher(IatSettings.this, mVadeosPreference, 0, 10000));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
return true;
}
}

@ -0,0 +1,49 @@
package com.iflytek.speech.setting;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
import android.view.Window;
import com.iflytek.mscv5plusdemo.R;
import com.iflytek.speech.util.SettingTextWatcher;
/**
*
*/
public class TtsSettings extends PreferenceActivity implements OnPreferenceChangeListener {
public static final String PREFER_NAME = "com.iflytek.setting";
private EditTextPreference mSpeedPreference;
private EditTextPreference mPitchPreference;
private EditTextPreference mVolumePreference;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
// 指定保存文件名字
getPreferenceManager().setSharedPreferencesName(PREFER_NAME);
addPreferencesFromResource(R.xml.tts_setting);
mSpeedPreference = (EditTextPreference) findPreference("speed_preference");
mSpeedPreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this, mSpeedPreference, 0, 200));
mPitchPreference = (EditTextPreference) findPreference("pitch_preference");
mPitchPreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this, mPitchPreference, 0, 100));
mVolumePreference = (EditTextPreference) findPreference("volume_preference");
mVolumePreference.getEditText().addTextChangedListener(new SettingTextWatcher(TtsSettings.this, mVolumePreference, 0, 100));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
return true;
}
}

@ -0,0 +1,144 @@
package com.iflytek.speech.util;
import android.content.Context;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechUtility;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
/**
*
*/
public class FucUtil {
/**
* asset
*
* @return content
*/
public static String readFile(Context mContext, String file, String code) {
int len = 0;
byte[] buf = null;
String result = "";
try {
InputStream in = mContext.getAssets().open(file);
len = in.available();
buf = new byte[len];
in.read(buf, 0, len);
result = new String(buf, code);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
*
*
* @param buffer
* @param length
* @param spsize
* @return
*/
public static ArrayList<byte[]> splitBuffer(byte[] buffer, int length, int spsize) {
ArrayList<byte[]> array = new ArrayList<byte[]>();
if (spsize <= 0 || length <= 0 || buffer == null || buffer.length < length)
return array;
int size = 0;
while (size < length) {
int left = length - size;
if (spsize < left) {
byte[] sdata = new byte[spsize];
System.arraycopy(buffer, size, sdata, 0, spsize);
array.add(sdata);
size += spsize;
} else {
byte[] sdata = new byte[left];
System.arraycopy(buffer, size, sdata, 0, left);
array.add(sdata);
size += left;
}
}
return array;
}
/**
* 线
* 1.PLUS_LOCAL_ALL:
* 2.PLUS_LOCAL_ASR:
* 3.PLUS_LOCAL_TTS:
*/
public static String checkLocalResource() {
String resource = SpeechUtility.getUtility().getParameter(SpeechConstant.PLUS_LOCAL_ASR);
try {
JSONObject result = new JSONObject(resource);
int ret = result.getInt(SpeechUtility.TAG_RESOURCE_RET);
switch (ret) {
case ErrorCode.SUCCESS:
JSONArray asrArray = result.getJSONObject("result").optJSONArray("asr");
if (asrArray != null) {
int i = 0;
// 查询否包含离线听写资源
for (; i < asrArray.length(); i++) {
if ("iat".equals(asrArray.getJSONObject(i).get(SpeechConstant.DOMAIN))) {
//asrArray中包含语言、方言字段后续会增加支持方言的本地听写。
//如:"accent": "mandarin","language": "zh_cn"
break;
}
}
if (i >= asrArray.length()) {
SpeechUtility.getUtility().openEngineSettings(SpeechConstant.ENG_ASR);
return "没有听写资源,跳转至资源下载页面";
}
} else {
SpeechUtility.getUtility().openEngineSettings(SpeechConstant.ENG_ASR);
return "没有听写资源,跳转至资源下载页面";
}
break;
case ErrorCode.ERROR_VERSION_LOWER:
return "语记版本过低,请更新后使用本地功能";
case ErrorCode.ERROR_INVALID_RESULT:
SpeechUtility.getUtility().openEngineSettings(SpeechConstant.ENG_ASR);
return "获取结果出错,跳转至资源下载页面";
case ErrorCode.ERROR_SYSTEM_PREINSTALL:
default:
break;
}
} catch (Exception e) {
SpeechUtility.getUtility().openEngineSettings(SpeechConstant.ENG_ASR);
return "获取结果出错,跳转至资源下载页面";
}
return "";
}
/**
* asset
*
* @return
*/
public static byte[] readAudioFile(Context context, String filename) {
try {
InputStream ins = context.getAssets().open(filename);
byte[] data = new byte[ins.available()];
ins.read(data);
ins.close();
return data;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}

@ -0,0 +1,173 @@
package com.iflytek.speech.util;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
/**
* Json
*/
public class JsonParser {
public static String parseIatResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
// 转写结果词,默认使用第一个结果
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
JSONObject obj = items.getJSONObject(0);
ret.append(obj.getString("w"));
// 如果需要多候选结果,解析数组其他字段
// for(int j = 0; j < items.length(); j++)
// {
// JSONObject obj = items.getJSONObject(j);
// ret.append(obj.getString("w"));
// }
}
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
public static String parseGrammarResult(String json, String engType) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
// 云端和本地结果分情况解析
if ("cloud".equals(engType)) {
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for (int j = 0; j < items.length(); j++) {
JSONObject obj = items.getJSONObject(j);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("【置信度】" + obj.getInt("sc"));
ret.append("\n");
}
}
} else if ("local".equals(engType)) {
ret.append("【结果】");
for (int i = 0; i < words.length(); i++) {
JSONObject wsItem = words.getJSONObject(i);
JSONArray items = wsItem.getJSONArray("cw");
if ("<contact>".equals(wsItem.getString("slot"))) {
// 可能会有多个联系人供选择,用中括号括起来,这些候选项具有相同的置信度
ret.append("【");
for (int j = 0; j < items.length(); j++) {
JSONObject obj = items.getJSONObject(j);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append(obj.getString("w")).append("|");
}
ret.setCharAt(ret.length() - 1, '】');
} else {
//本地多候选按照置信度高低排序,一般选取第一个结果即可
JSONObject obj = items.getJSONObject(0);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append(obj.getString("w"));
}
}
ret.append("【置信度】" + joResult.getInt("sc"));
ret.append("\n");
}
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
public static String parseGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for (int j = 0; j < items.length(); j++) {
JSONObject obj = items.getJSONObject(j);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("【置信度】" + obj.getInt("sc"));
ret.append("\n");
}
}
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
public static String parseLocalGrammarResult(String json) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
JSONArray words = joResult.getJSONArray("ws");
for (int i = 0; i < words.length(); i++) {
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
for (int j = 0; j < items.length(); j++) {
JSONObject obj = items.getJSONObject(j);
if (obj.getString("w").contains("nomatch")) {
ret.append("没有匹配结果.");
return ret.toString();
}
ret.append("【结果】" + obj.getString("w"));
ret.append("\n");
}
}
ret.append("【置信度】" + joResult.optInt("sc"));
} catch (Exception e) {
e.printStackTrace();
ret.append("没有匹配结果.");
}
return ret.toString();
}
public static String parseTransResult(String json, String key) {
StringBuffer ret = new StringBuffer();
try {
JSONTokener tokener = new JSONTokener(json);
JSONObject joResult = new JSONObject(tokener);
String errorCode = joResult.optString("ret");
if (!errorCode.equals("0")) {
return joResult.optString("errmsg");
}
JSONObject transResult = joResult.optJSONObject("trans_result");
ret.append(transResult.optString(key));
/*JSONArray words = joResult.getJSONArray("results");
for (int i = 0; i < words.length(); i++) {
JSONObject obj = words.getJSONObject(i);
ret.append(obj.getString(key));
}*/
} catch (Exception e) {
e.printStackTrace();
}
return ret.toString();
}
}

@ -0,0 +1,71 @@
package com.iflytek.speech.util;
import android.content.Context;
import android.preference.EditTextPreference;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.widget.Toast;
import java.util.regex.Pattern;
/**
*
*/
public class SettingTextWatcher implements TextWatcher {
private int editStart;
private int editCount;
private EditTextPreference mEditTextPreference;
int minValue;//最小值
int maxValue;//最大值
private Context mContext;
public SettingTextWatcher(Context context, EditTextPreference e, int min, int max) {
mContext = context;
mEditTextPreference = e;
minValue = min;
maxValue = max;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Log.e("demo", "onTextChanged start:"+start+" count:"+count+" before:"+before);
editStart = start;
editCount = count;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Log.e("demo", "beforeTextChanged start:"+start+" count:"+count+" after:"+after);
}
@Override
public void afterTextChanged(Editable s) {
if (TextUtils.isEmpty(s)) {
return;
}
String content = s.toString();
// Log.e("demo", "content:"+content);
if (isNumeric(content)) {
int num = Integer.parseInt(content);
if (num > maxValue || num < minValue) {
s.delete(editStart, editStart + editCount);
mEditTextPreference.getEditText().setText(s);
Toast.makeText(mContext, "超出有效值范围", Toast.LENGTH_SHORT).show();
}
} else {
s.delete(editStart, editStart + editCount);
mEditTextPreference.getEditText().setText(s);
Toast.makeText(mContext, "只能输入数字哦", Toast.LENGTH_SHORT).show();
}
}
/**
* -
*/
public static boolean isNumeric(String str) {
Pattern pattern = Pattern.compile("[0-9]*");
return pattern.matcher(str).matches();
}
};

@ -0,0 +1,55 @@
package com.iflytek.speech.util;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
/**
* Xml
*/
public class XmlParser {
public static String parseNluResult(String xml) {
StringBuffer buffer = new StringBuffer();
try {
// DOM builder
DocumentBuilder domBuilder = null;
// DOM doc
Document domDoc = null;
// init DOM
DocumentBuilderFactory domFact = DocumentBuilderFactory.newInstance();
domBuilder = domFact.newDocumentBuilder();
InputStream is = new ByteArrayInputStream(xml.getBytes());
domDoc = domBuilder.parse(is);
// 获取根节点
Element root = (Element) domDoc.getDocumentElement();
Element raw = (Element) root.getElementsByTagName("rawtext").item(0);
buffer.append("【识别结果】" + raw.getFirstChild().getNodeValue());
buffer.append("\n");
Element e = (Element) root.getElementsByTagName("result").item(0);
Element focus = (Element) e.getElementsByTagName("focus").item(0);
buffer.append("【FOCUS】" + focus.getFirstChild().getNodeValue());
buffer.append("\n");
Element action = (Element) e.getElementsByTagName("action").item(0);
Element operation = (Element) action.getElementsByTagName("operation").item(0);
buffer.append("【ACTION】" + operation.getFirstChild().getNodeValue());
buffer.append("\n");
} catch (Exception e) {
e.printStackTrace();
}
buffer.append("【ALL】" + xml);
return buffer.toString();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/btn_left_p" />
<item android:state_focused="true" android:drawable="@drawable/btn_left_f" />
<item android:drawable="@drawable/btn_left_n" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 945 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/btn_right_p" />
<item android:state_focused="true" android:drawable="@drawable/btn_right_f" />
<item android:drawable="@drawable/btn_right_n" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/login_p" />
<item android:state_enabled="false" android:drawable="@drawable/login" />
<item android:drawable="@drawable/login" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save