diff --git a/doc/02_小米便签开源代码阅读-精读报告_何苗.docx b/doc/02_小米便签开源代码阅读-精读报告_何苗.docx new file mode 100644 index 0000000..46e31d3 Binary files /dev/null and b/doc/02_小米便签开源代码阅读-精读报告_何苗.docx differ diff --git a/doc/02_小米便签开源代码阅读-精读报告_孙慧敏.docx b/doc/02_小米便签开源代码阅读-精读报告_孙慧敏.docx new file mode 100644 index 0000000..a0d7159 Binary files /dev/null and b/doc/02_小米便签开源代码阅读-精读报告_孙慧敏.docx differ diff --git a/doc/02_小米便签开源代码阅读-精读报告_袁爱文.docx b/doc/02_小米便签开源代码阅读-精读报告_袁爱文.docx new file mode 100644 index 0000000..1e94f0d Binary files /dev/null and b/doc/02_小米便签开源代码阅读-精读报告_袁爱文.docx differ diff --git a/doc/02_小米便签开源代码阅读-精读报告_赵丽利.docx b/doc/02_小米便签开源代码阅读-精读报告_赵丽利.docx new file mode 100644 index 0000000..414089e Binary files /dev/null and b/doc/02_小米便签开源代码阅读-精读报告_赵丽利.docx differ diff --git a/doc/02_小米便签开源代码阅读-精读报告_陈恩茹.docx b/doc/02_小米便签开源代码阅读-精读报告_陈恩茹.docx new file mode 100644 index 0000000..2369182 Binary files /dev/null and b/doc/02_小米便签开源代码阅读-精读报告_陈恩茹.docx differ diff --git a/doc/03_小米便签开源代码-质量分析报告_何苗.docx b/doc/03_小米便签开源代码-质量分析报告_何苗.docx new file mode 100644 index 0000000..a22a604 Binary files /dev/null and b/doc/03_小米便签开源代码-质量分析报告_何苗.docx differ diff --git a/doc/04_小米便签维护-需求与设计方案_何苗.docx b/doc/04_小米便签维护-需求与设计方案_何苗.docx new file mode 100644 index 0000000..869f1d6 Binary files /dev/null and b/doc/04_小米便签维护-需求与设计方案_何苗.docx differ diff --git a/doc/05_小米便签阅读与维护-汇报_何苗.pptx b/doc/05_小米便签阅读与维护-汇报_何苗.pptx new file mode 100644 index 0000000..b6cb529 Binary files /dev/null and b/doc/05_小米便签阅读与维护-汇报_何苗.pptx differ diff --git a/doc/06_小米便签阅读与维护-总结报告_何苗.docx b/doc/06_小米便签阅读与维护-总结报告_何苗.docx new file mode 100644 index 0000000..b02cc24 Binary files /dev/null and b/doc/06_小米便签阅读与维护-总结报告_何苗.docx differ diff --git a/doc/06_小米便签阅读与维护-总结报告_孙慧敏.docx b/doc/06_小米便签阅读与维护-总结报告_孙慧敏.docx new file mode 100644 index 0000000..d152092 Binary files /dev/null and b/doc/06_小米便签阅读与维护-总结报告_孙慧敏.docx differ diff --git a/doc/06_小米便签阅读与维护-总结报告_袁爱文.docx b/doc/06_小米便签阅读与维护-总结报告_袁爱文.docx new file mode 100644 index 0000000..68a906d Binary files /dev/null and b/doc/06_小米便签阅读与维护-总结报告_袁爱文.docx differ diff --git a/doc/06_小米便签阅读与维护-总结报告_赵丽利.docx b/doc/06_小米便签阅读与维护-总结报告_赵丽利.docx new file mode 100644 index 0000000..2a9eff8 Binary files /dev/null and b/doc/06_小米便签阅读与维护-总结报告_赵丽利.docx differ diff --git a/doc/06_小米便签阅读与维护-总结报告_陈恩茹.docx b/doc/06_小米便签阅读与维护-总结报告_陈恩茹.docx new file mode 100644 index 0000000..ca0a128 Binary files /dev/null and b/doc/06_小米便签阅读与维护-总结报告_陈恩茹.docx differ diff --git a/doc/07_小米便签维护_演示录频_何苗.mp4 b/doc/07_小米便签维护_演示录频_何苗.mp4 new file mode 100644 index 0000000..a3f6ab4 Binary files /dev/null and b/doc/07_小米便签维护_演示录频_何苗.mp4 differ diff --git a/doc/1.txt b/doc/1.txt deleted file mode 100644 index 8839157..0000000 --- a/doc/1.txt +++ /dev/null @@ -1,2 +0,0 @@ -yaw_branch -shm_branch \ No newline at end of file diff --git a/model/README.txt b/model/README.txt new file mode 100644 index 0000000..a76010f --- /dev/null +++ b/model/README.txt @@ -0,0 +1 @@ +由于我组使用的绘图软件功能限制,只有以下UML模型能够导出。 \ No newline at end of file diff --git a/model/删除便签功能设计类图.eddx b/model/删除便签功能设计类图.eddx new file mode 100644 index 0000000..8ee26bc Binary files /dev/null and b/model/删除便签功能设计类图.eddx differ diff --git a/model/删除便签功能设计顺序图.eddx b/model/删除便签功能设计顺序图.eddx new file mode 100644 index 0000000..495bcab Binary files /dev/null and b/model/删除便签功能设计顺序图.eddx differ diff --git a/model/小米便签新建文件夹设计顺序图和设计类图.vsdx b/model/小米便签新建文件夹设计顺序图和设计类图.vsdx new file mode 100644 index 0000000..638a8a5 Binary files /dev/null and b/model/小米便签新建文件夹设计顺序图和设计类图.vsdx differ diff --git a/model/新增回收站功能设计类图.eddx b/model/新增回收站功能设计类图.eddx new file mode 100644 index 0000000..23da1d3 Binary files /dev/null and b/model/新增回收站功能设计类图.eddx differ diff --git a/model/语音功能体系结构图,回收站功能用例图,新建便签精读设计类图设计顺序图.eddx b/model/语音功能体系结构图,回收站功能用例图,新建便签精读设计类图设计顺序图.eddx new file mode 100644 index 0000000..88b8104 Binary files /dev/null and b/model/语音功能体系结构图,回收站功能用例图,新建便签精读设计类图设计顺序图.eddx differ diff --git a/src/Notes b/src/Notes new file mode 160000 index 0000000..013c5b7 --- /dev/null +++ b/src/Notes @@ -0,0 +1 @@ +Subproject commit 013c5b7b86275a1f98bcd9e1ab0412c78b36a3e7 diff --git a/src/讯飞SDK/assets/iflytek/recognize.xml b/src/讯飞SDK/assets/iflytek/recognize.xml new file mode 100644 index 0000000..78300c1 Binary files /dev/null and b/src/讯飞SDK/assets/iflytek/recognize.xml differ diff --git a/src/讯飞SDK/assets/iflytek/voice_bg.9.png b/src/讯飞SDK/assets/iflytek/voice_bg.9.png new file mode 100644 index 0000000..217f9dc Binary files /dev/null and b/src/讯飞SDK/assets/iflytek/voice_bg.9.png differ diff --git a/src/讯飞SDK/assets/iflytek/voice_empty.png b/src/讯飞SDK/assets/iflytek/voice_empty.png new file mode 100644 index 0000000..08ffc43 Binary files /dev/null and b/src/讯飞SDK/assets/iflytek/voice_empty.png differ diff --git a/src/讯飞SDK/assets/iflytek/voice_full.png b/src/讯飞SDK/assets/iflytek/voice_full.png new file mode 100644 index 0000000..4bf5bbc Binary files /dev/null and b/src/讯飞SDK/assets/iflytek/voice_full.png differ diff --git a/src/讯飞SDK/assets/iflytek/waiting.png b/src/讯飞SDK/assets/iflytek/waiting.png new file mode 100644 index 0000000..d13bb33 Binary files /dev/null and b/src/讯飞SDK/assets/iflytek/waiting.png differ diff --git a/src/讯飞SDK/assets/iflytek/warning.png b/src/讯飞SDK/assets/iflytek/warning.png new file mode 100644 index 0000000..48150ff Binary files /dev/null and b/src/讯飞SDK/assets/iflytek/warning.png differ diff --git a/src/讯飞SDK/libs/Msc.jar b/src/讯飞SDK/libs/Msc.jar new file mode 100644 index 0000000..fe502fb Binary files /dev/null and b/src/讯飞SDK/libs/Msc.jar differ diff --git a/src/讯飞SDK/libs/arm64-v8a/libmsc.so b/src/讯飞SDK/libs/arm64-v8a/libmsc.so new file mode 100644 index 0000000..85df4a7 Binary files /dev/null and b/src/讯飞SDK/libs/arm64-v8a/libmsc.so differ diff --git a/src/讯飞SDK/libs/armeabi-v7a/libmsc.so b/src/讯飞SDK/libs/armeabi-v7a/libmsc.so new file mode 100644 index 0000000..07a39ab Binary files /dev/null and b/src/讯飞SDK/libs/armeabi-v7a/libmsc.so differ diff --git a/src/讯飞SDK/readme.txt b/src/讯飞SDK/readme.txt new file mode 100644 index 0000000..8a1d572 --- /dev/null +++ b/src/讯飞SDK/readme.txt @@ -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/ diff --git a/src/讯飞SDK/release.txt b/src/讯飞SDK/release.txt new file mode 100644 index 0000000..8b8bfee --- /dev/null +++ b/src/讯飞SDK/release.txt @@ -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 值正常,但返回为空的问题; + 2,AIMIC: 修正在唤醒会话结束偶现崩溃的问题; + 3,权限:修正没有 android.permission.ACCESS_NETWORK_STATE 时无法使用的问题; + 4,录音:加入录音时使用蓝牙的选项(SpeechConstant.BLUETOOTH); + 5,合成:修改合成进度中 spellinfo 的返回,以JSON格式,并增加音频长度信息(需设置 "audio_info" 参数为真); + 6,识别:增加在会话开始时,通过参数设置获取设备信息(SpeechConstant.DVC_INFO 参数需设置为真); + +已知问题: + 1,AIMIC:唤醒一定次数时,报 27019 问题,为唤醒引擎返回结果 EOS 值错误引起; + 2,合成:部份手机设备上,在蓝牙播放回调 onComplete 时,若马上开始录音,合成播放末尾漏字(安卓系统蓝牙播放延迟原因,暂不解决); +-------------------------------------------------------------------- +1.1119版本更新信息 + 1,翻译:增加翻译示例和文档说明; + 2,合成:1) 增加淡入淡出参数 TTS_FADING(默认不启用);2) 加长音频结束播放时加播的空白音频,优化蓝牙合成播放末尾漏字问题; + 3,AIMIC: 修正偶现写音频失败问题;(自测通过) + +已知问题: + 1,AIMIC:唤醒一定次数时,报 27019 问题,为唤醒引擎返回结果EOS值错误引起; + 2,合成:厂商反馈蓝牙播放回调 onComplete 时,若马上开始录音,合成播放末尾漏字; +-------------------------------------------------------------------- +1.1118版本更新信息 + 1,语义理解:增加 SCENE 语义情景参数; + 2,AIMIC:修正 27018 问题; + 3,DEMO:a) 语义理解DEMO,去掉不支持的语义说法提示,修正网址链接;b) 加入语义情景设置代码示例; + +已知问题: + 1,AIMIC:唤醒一定次数时,报 27019 问题,为唤醒引擎返回结果EOS值错误引起; +--------------------------------------------------------------------- +1.1116版本更新信息 + 1,语义理解:默认语义使用 3.0 版本; + 2,文档:新手指南文档,不能功能用同一个PDF文档;修改默认语义版本说明; + +已知问题: + 1,AIMIC:唤醒一定次数时,报 27019 问题,为唤醒引擎返回结果EOS值错误引起; +--------------------------------------------------------------------- +1.1116版本更新信息 + 1,语义理解:默认语义使用 3.0 版本; + 2,文档:新手指南文档,不能功能用同一个PDF文档;修改默认语义版本说明; + 3,DEMO:a) 语义理解DEMO,去掉不支持的语义说法提示,修正网址链接;b) 加入语义情景设置代码示例; + +已知问题: + 1,AIMIC:唤醒一定次数时,报 27019 问题,为唤醒引擎返回结果EOS值错误引起; +--------------------------------------------------------------------- +1.1116版本更新信息 + 1,语义理解:默认语义使用 3.0 版本; + 2,文档:新手指南文档,不能功能用同一个PDF文档;修改默认语义版本说明; + 3,AIMIC: a) 增加获取几麦和AIMIC版本的参数( aimic_on_channel, aimic_on_version ),增加设置 REAL BEAM 参数 ( aimic_on_real_beam ); + b) 修改清空缓存的处理,增加三个线程同步;减少缓存空间大小,减少由于缓存多时,唤醒结果返回与 CAE frame count 相差较大,使 CAE 不回调结果,而报 27019 的情况; + 4,DEMO: 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)里面还没放置文档; + 3,AIMIC:唤醒一定次数时,报 27019 问题,为唤醒引擎返回结果EOS值错误引起; +--------------------------------------------------------------------- +1.1115版本更新信息 + 1,资源目录:删除不要的 IVW 40 的资源;删除 1.0 版本的 ASR 资源,并把原 asr_two 文件夹改名 asr;IVW 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)支持windows,linux,Android平台; + 3)5.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,避免可能不及时获取音频而缓存满丢失的问题; + 5,AIMIC: 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,合成:在暂停,恢复,停止时,增加淡入淡出的效果,优化播放体验; + 3,demo: 修正人脸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不可用的问题; + 3,DEMO: 听写 DEMO 提示中,去掉河南话; + 4,文档: a) VAD 检测功能加入未支持说明; b) 去掉 ISE_ENT,以 LANGUAGE 代替; + 5,IVW: 增加保存最近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版本更新信息 +1,asr: a) 删除没有使用到的 MscRecognizerAIMic.java 及其引用; + b) 修改前端点消除时的音频处理从独立的线程转回 MscHandler 线程中,并修改可能重复返回同一音频的问题; +2,文档:开放语义文档更新至语义官网上最新的版本; + +MSC 5.0.28.1150 更新信息: +1. 回退到1148的代码版本; +2. 基于1148代码上,解决sessinfo没有传入正确的sid的问题; +--------------------------------------------------------------------- +1.1110版本更新信息 + +1,ivw:a) 修正 SDK 设置的 IVW_NETVAL 覆盖外面设置值的问题; +2,aimic: 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的问题; +6,asr: a) 修改获取默BOS, EOS的方式; + b) 在消除前端点静音时,禁用 libmsc.so 中的VAD,直接使用模型VAD检测整个过程; + +aimic jni 更新信息: +1,增加禁止写入IVW音频的参数 ivw_auw_disable,用于测试,默认为 FALSE; +2,char 转 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,录音:当录音时返回负值状态时,直接抛出异常; +2,JNI:添加AIUI相关的接口(仅 Native 定义); +3,有数数据采集:a) 包由 com.iflytek.thirdparty 移动到 com.iflytek.cloud.thirdparty; b) 捕获异常的 Exception 改为 Throwable; +4,AIMIC:a) 主版本与 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裁剪;默认包含闭环优化,目前裁剪只支持windows,linux,android; + 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参数; +5,VAD:增加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.def(windows)和msc.map(linux); +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; +7,src 目录新增 AimicTest 测试工具,以及AIMIC模块的源码:AIMicLibsrc,AIMIC_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、处理器支持 diff --git a/src/讯飞SDK/res/layout/ifly_layout_mnotice_image.xml b/src/讯飞SDK/res/layout/ifly_layout_mnotice_image.xml new file mode 100644 index 0000000..bd920b0 --- /dev/null +++ b/src/讯飞SDK/res/layout/ifly_layout_mnotice_image.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/res/tts/common.jet b/src/讯飞SDK/res/tts/common.jet new file mode 100644 index 0000000..7dd14f0 Binary files /dev/null and b/src/讯飞SDK/res/tts/common.jet differ diff --git a/src/讯飞SDK/res/tts/xiaofeng.jet b/src/讯飞SDK/res/tts/xiaofeng.jet new file mode 100644 index 0000000..cb49be5 Binary files /dev/null and b/src/讯飞SDK/res/tts/xiaofeng.jet differ diff --git a/src/讯飞SDK/res/tts/xiaoyan.jet b/src/讯飞SDK/res/tts/xiaoyan.jet new file mode 100644 index 0000000..c1acca7 Binary files /dev/null and b/src/讯飞SDK/res/tts/xiaoyan.jet differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/build.gradle b/src/讯飞SDK/sample/mscV5PlusDemo/build.gradle new file mode 100644 index 0000000..c82d138 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/build.gradle @@ -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' +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/libs/Msc.jar b/src/讯飞SDK/sample/mscV5PlusDemo/libs/Msc.jar new file mode 100644 index 0000000..fe502fb Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/libs/Msc.jar differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/libs/arm64-v8a/libmsc.so b/src/讯飞SDK/sample/mscV5PlusDemo/libs/arm64-v8a/libmsc.so new file mode 100644 index 0000000..85df4a7 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/libs/arm64-v8a/libmsc.so differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/libs/armeabi-v7a/libmsc.so b/src/讯飞SDK/sample/mscV5PlusDemo/libs/armeabi-v7a/libmsc.so new file mode 100644 index 0000000..07a39ab Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/libs/armeabi-v7a/libmsc.so differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/lint.xml b/src/讯飞SDK/sample/mscV5PlusDemo/lint.xml new file mode 100644 index 0000000..c70207f --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/lint.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/msc.cfg b/src/讯飞SDK/sample/mscV5PlusDemo/msc.cfg new file mode 100644 index 0000000..1772d84 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/msc.cfg @@ -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 + +##���� +#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 +##���Ի��� +#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��־ +#no_sessinfodata = 1 +sessinfodata = sessinfo.txt +##�����ʱʱ�� +rslt_timeout = 5000 +##��ȡchid��ʱ +chid_timeout = 3000 +##��ȡpushnode��ʱ +pushnode_timeout = 3000 +##������������û���յ���������Ӧ������ʱ�� +down_stream_timeout = 20000 +##��������һ��ʱ��û��������Ͽ����� +up_stream_req_timeout = 50000 +##��������һ��ʱ��û���յ���Ӧ�����������ӵ���Ϣ�����л�����Ϣ�ڵȴ���Ӧ���ؽ����� +up_stream_resp_timeout = 3000 +##����������ʱ��һ��ʱ��û�����ݣ�����һ�������� +heart_beat_timeout = 15000 +##׼����ʱ����������һ��ʱ��֮�ڣ���ʹ�Ѿ�׼�����ˣ�Ҳ��ҵ�����Ϊû��׼���ã����ڲ����װ���ѹ���� +ready_delay_timeout = 1 +##��ȡchid�쳣ʱ����ʱһ��ʱ���ٴ����� +chid_delay_reset_timeout = 3000 +##��ȡpushnode�쳣ʱ����ʱһ��ʱ���ٴ����� +pushnode_delay_reset_timeout = 3000 +##��������һ��ʱ��û�����������»�ȡchid��pushnode��Ĭ��ֵ42000000��11Сʱ40���ӣ� +reset_chid_pushnode_timeout = 42000000 +##stmid_q�е�Ԫ�س�����ֵʱ����ǰ�濪ʼɾ�������������ô�����ͬ��stmidͬʱ������Ĭ��ֵ20 +stmid_q_max = 20 + +[tts] +##�ϳ����������ı����ȣ���Χ(0, 4096]��Ĭ��ֵ1024�� +max_text_size = 1024 +##��Ƶ��������С�����ڱ��غϳ�ʱ��Ч��Ϊÿ�η��ص���Ƶ���ݴ�С�� +buff_size = 8192 + +[asr] +##�����Ƶ���ȣ���λByte����Χ(0, 1MB]��Ĭ��ֵ256KB +max_audio_size = 262144 +##��С��Ƶ���볤�ȣ���λByte����Χ(0, max_audio_size]��Ĭ��ֵ5KB +coding_chunk_size = 5120 +##�Ƿ�ʹ��VAD���ж˵�����߽��� +vad_enable = true +##��Ƶ�����㷨��ģʽ��audio_coding��coding_levelȡֵ��Χ���±���ʾ��Ĭ��ֵ�ֱ�Ϊspeex-wb��7�� +# ---------------------------------- +# | audio_coding | coding_level | +# ---------------------------------- +# | speex | 0-10 | +# | speex-wb | 0-10 | +# | raw | ��Ч | +# ---------------------------------- +audio_coding = speex-wb +coding_level = 7 + +[hcr] +##������ݳ��ȣ���λByte����Χ(0, 16KB]��Ĭ��ֵ8KB +max_data_size = 8192 + +[isv] +##�����Ƶ���ȣ���λByte����Χ(0, 2MB]��Ĭ��ֵ512KB +max_audio_size = 524288 +##��С��Ƶ���볤�ȣ���λByte����Χ(0, max_audio_size]��Ĭ��ֵ5KB +coding_chunk_size = 5120 +##��Ƶ�����㷨��ģʽ��audio_coding��coding_levelȡֵ��Χ���Բο�asr�� +audio_coding = speex-wb +coding_level = 7 + +[logger] +##����û�ָ������־�ļ�·����Ч����ôMSC�������н������¼��־��Ϣ +file = msc.log +title = Mobile Speech Client +level = -1 +output = 1 +filter = -1 +style = -1 +flush = 0 +maxsize = 104857600 +overwrite = 1 +maxfile = diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/AndroidManifest.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3361f00 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/AndroidManifest.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/call.bnf b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/call.bnf new file mode 100644 index 0000000..acc217f --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/call.bnf @@ -0,0 +1,12 @@ +#BNF+IAT 1.0 UTF-8; +!grammar call; +!slot ; +!slot ; +!slot ; +!slot ; +!start ; +:[][]|[][]; +:张海洋; +:我要|我想|我想要; +:打电话; +:给; \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/grammar_sample.abnf b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/grammar_sample.abnf new file mode 100644 index 0000000..993856d --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/grammar_sample.abnf @@ -0,0 +1,8 @@ +#ABNF 1.0 UTF-8; +language zh-CN; +mode voice; + +root $main; +$main = $place1 到 $place2; +$place1 = 北京|武汉|南京|天津|东京; +$place2 = 上海|合肥; \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iattest.wav b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iattest.wav new file mode 100644 index 0000000..fcee567 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iattest.wav differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/recognize.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/recognize.xml new file mode 100644 index 0000000..78300c1 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/recognize.xml differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_bg.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_bg.9.png new file mode 100644 index 0000000..217f9dc Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_bg.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_empty.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_empty.png new file mode 100644 index 0000000..08ffc43 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_empty.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_full.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_full.png new file mode 100644 index 0000000..4bf5bbc Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/voice_full.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/waiting.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/waiting.png new file mode 100644 index 0000000..d13bb33 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/waiting.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/warning.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/warning.png new file mode 100644 index 0000000..48150ff Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/iflytek/warning.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/layout/ifly_layout_mnotice_image.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/layout/ifly_layout_mnotice_image.xml new file mode 100644 index 0000000..bd920b0 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/layout/ifly_layout_mnotice_image.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/userwords b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/userwords new file mode 100644 index 0000000..7c107cc --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/userwords @@ -0,0 +1 @@ +{"userword":[{"name":"我的常用词","words":["佳晨实业","蜀南庭苑","高兰路","复联二"]},{"name":"我的好友","words":["李馨琪","鹿晓雷","张集栋","周家莉","叶震珂","熊泽萌"]}]} \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/wake.bnf b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/wake.bnf new file mode 100644 index 0000000..6a20304 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/wake.bnf @@ -0,0 +1,8 @@ +#BNF+IAT 1.0 UTF-8; +!grammar wake; +!slot ; +!slot ; +!start ; +:[]; +:讯飞语音|讯飞语点|叮咚叮咚; +:张三|李四|张海洋; \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/wake_grammar_sample.abnf b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/wake_grammar_sample.abnf new file mode 100644 index 0000000..55c07d6 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/assets/wake_grammar_sample.abnf @@ -0,0 +1,8 @@ +#ABNF 1.0 UTF-8; +language zh-CN; +mode voice; + +root $main; +$main = [$call] $name; +$call = 讯飞语音|讯飞语点|叮咚叮咚; +$name = 张三|李四|张海洋; \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/AsrDemo.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/AsrDemo.java new file mode 100644 index 0000000..fce56d3 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/AsrDemo.java @@ -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(); + } + +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/IatDemo.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/IatDemo.java new file mode 100644 index 0000000..c95708f --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/IatDemo.java @@ -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 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(); + } +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/IvwActivity.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/IvwActivity.java new file mode 100644 index 0000000..5c0b378 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/IvwActivity.java @@ -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; + } + } +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/MainActivity.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/MainActivity.java new file mode 100644 index 0000000..95978b8 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/MainActivity.java @@ -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); + } + +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/OneShotDemo.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/OneShotDemo.java new file mode 100644 index 0000000..39d931f --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/OneShotDemo.java @@ -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(); + } + }); + } + +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/SpeechApp.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/SpeechApp.java new file mode 100644 index 0000000..6e429c2 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/SpeechApp.java @@ -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) { + + } + }); + } +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/TtsDemo.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/TtsDemo.java new file mode 100644 index 0000000..b673318 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/TtsDemo.java @@ -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(); + } +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/WakeDemo.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/WakeDemo.java new file mode 100644 index 0000000..32bc73c --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/mscv5plusdemo/WakeDemo.java @@ -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:开启闭环优化功能,允许上传优化数据。需开发者自行管理优化资源。 + * sdk提供相应的查询和下载接口,请开发者参考API文档,具体使用请参考本示例 + * queryResource及downloadResource方法; + * + * 模式2:开启闭环优化功能,允许上传优化数据及启动唤醒时进行资源查询下载; + * 本示例为方便开发者使用仅展示模式0和模式2; + */ + 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; + } + } + + /** + * 查询闭环优化唤醒资源 + * 请在闭环优化网络模式1或者模式2使用 + */ + 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); + } + }); + } + +} \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/setting/IatSettings.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/setting/IatSettings.java new file mode 100644 index 0000000..dd9e5db --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/setting/IatSettings.java @@ -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; + } +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/setting/TtsSettings.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/setting/TtsSettings.java new file mode 100644 index 0000000..4ca9c5a --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/setting/TtsSettings.java @@ -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; + } + + +} \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/FucUtil.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/FucUtil.java new file mode 100644 index 0000000..0c0fb60 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/FucUtil.java @@ -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 splitBuffer(byte[] buffer, int length, int spsize) { + ArrayList array = new ArrayList(); + 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; + } + +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/JsonParser.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/JsonParser.java new file mode 100644 index 0000000..ac73c80 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/JsonParser.java @@ -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 ("".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(); + } +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/SettingTextWatcher.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/SettingTextWatcher.java new file mode 100644 index 0000000..a1c1c62 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/SettingTextWatcher.java @@ -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(); + } + +}; diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/XmlParser.java b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/XmlParser.java new file mode 100644 index 0000000..f87f09e --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/java/com/iflytek/speech/util/XmlParser.java @@ -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(); + } +} diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/bg.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/bg.png new file mode 100644 index 0000000..ebcc253 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/bg.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left.xml new file mode 100644 index 0000000..3941b90 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_f.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_f.9.png new file mode 100644 index 0000000..7350c23 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_f.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_n.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_n.9.png new file mode 100644 index 0000000..af63253 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_n.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_p.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_p.9.png new file mode 100644 index 0000000..ae6e24c Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_left_p.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right.xml new file mode 100644 index 0000000..537faa9 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_f.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_f.9.png new file mode 100644 index 0000000..ad645cf Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_f.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_n.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_n.9.png new file mode 100644 index 0000000..dd73748 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_n.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_p.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_p.9.png new file mode 100644 index 0000000..63a14ee Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/btn_right_p.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/button_login.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/button_login.xml new file mode 100644 index 0000000..0f17e53 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/button_login.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/cancel.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/cancel.9.png new file mode 100644 index 0000000..e5bf5b8 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/cancel.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/cancel_p.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/cancel_p.9.png new file mode 100644 index 0000000..277f33d Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/cancel_p.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/editbox.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/editbox.9.png new file mode 100644 index 0000000..4321a7c Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/editbox.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/edittext_name.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/edittext_name.9.png new file mode 100644 index 0000000..50b010b Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/edittext_name.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/head.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/head.png new file mode 100644 index 0000000..db4a8a1 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/head.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/icon.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..cf0cb01 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/icon.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/login.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/login.png new file mode 100644 index 0000000..c7bbfa3 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/login.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/login_p.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/login_p.png new file mode 100644 index 0000000..315eac9 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/login_p.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_0.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_0.png new file mode 100644 index 0000000..69073f9 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_0.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_1.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_1.png new file mode 100644 index 0000000..130d340 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_1.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_2.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_2.png new file mode 100644 index 0000000..3d22d49 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_2.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_3.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_3.png new file mode 100644 index 0000000..fea462c Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/mic_3.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/name_left.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/name_left.png new file mode 100644 index 0000000..6916dad Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/name_left.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/name_right.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/name_right.png new file mode 100644 index 0000000..c7f2be8 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/name_right.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok.9.png new file mode 100644 index 0000000..e53f2be Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok_d.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok_d.9.png new file mode 100644 index 0000000..a94d1f6 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok_d.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok_p.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok_p.9.png new file mode 100644 index 0000000..f1b6579 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/ok_p.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/pane_bg.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/pane_bg.9.png new file mode 100644 index 0000000..8eefa0a Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/pane_bg.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/superman.9.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/superman.9.png new file mode 100644 index 0000000..be4a3c1 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-hdpi/superman.9.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-ldpi/icon.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..d2dfdc6 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-ldpi/icon.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-mdpi/icon.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..6a5697e Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable-mdpi/icon.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/cancel_button.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/cancel_button.xml new file mode 100644 index 0000000..47229bb --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/cancel_button.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/list_bg_color.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/list_bg_color.xml new file mode 100644 index 0000000..d8dc1f0 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/list_bg_color.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/main_setting_btn_np.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/main_setting_btn_np.xml new file mode 100644 index 0000000..369d824 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/main_setting_btn_np.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/ok_button.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/ok_button.xml new file mode 100644 index 0000000..547451e --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/ok_button.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/setting.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/setting.png new file mode 100644 index 0000000..437bc51 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/setting.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/setting_p.png b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/setting_p.png new file mode 100644 index 0000000..0da80e4 Binary files /dev/null and b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/drawable/setting_p.png differ diff --git a/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/layout/iatdemo.xml b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/layout/iatdemo.xml new file mode 100644 index 0000000..0890117 --- /dev/null +++ b/src/讯飞SDK/sample/mscV5PlusDemo/src/main/res/layout/iatdemo.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + +