讯飞语音测评的简单demo演示

样式如下图所示:

标题

一、自定义语音动态视图SpeeceVoiceView

package com.example.speechevaluation.view;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;import com.example.speechevaluation.QZXTools;
import com.example.speechevaluation.R;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;/*** @author qzx* @time 2018/10/23 14:10*/
public class SpeechVoiceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {private Context mContext;private SurfaceHolder mSurfaceHolder;private Paint mPaint;private Canvas mCanvas;private ExecutorService executorService;private boolean isDestroy = false;private static final int INTERVER_TIME = 100;//30毫秒private boolean isRecording = false;private boolean isParsing = false;private int curVolume;private int circle_radius = 120;private static final int RectRadius = 20;private static final int RectDivide = 10;private static final int RectHeight = 40;private RectF rectF;/*** 设置解析情况*/public void setParsing(boolean parsing) {isParsing = parsing;}/*** 设置音量情况*/public void setCurVolume(int curVolume) {this.curVolume = curVolume;}public SpeechVoiceView(Context context) {this(context, null);}public SpeechVoiceView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public SpeechVoiceView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;init();}private void init() {mSurfaceHolder = getHolder();mSurfaceHolder.addCallback(this);/*消除黑色的背景*/setZOrderOnTop(true);//this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);/*消除黑色的背景*/setFocusable(true);setFocusableInTouchMode(true);mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);mPaint.setStyle(Paint.Style.FILL_AND_STROKE);mPaint.setColor(Color.TRANSPARENT);rectF = new RectF();executorService = Executors.newSingleThreadExecutor();}@Overridepublic void surfaceCreated(SurfaceHolder holder) {isDestroy = false;executorService.execute(this);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isDestroy = true;}@Overridepublic void run() {while (!isDestroy) {//            curVolume = (int) (Math.random() * 15);
//            QZXTools.logE("zbv", "curVolume=" + curVolume, null);//控制刷新的帧数long startTime = System.currentTimeMillis();draw();long endTime = System.currentTimeMillis();if ((endTime - startTime) < INTERVER_TIME) {try {Thread.sleep((INTERVER_TIME - (endTime - startTime)));} catch (InterruptedException e) {e.printStackTrace();}}}}private int count = 0;/*** 点击开始录音评测,显示录音的过程,再次点击或者超时结束评测显示等待结果,后复原*/private void draw() {try {mCanvas = mSurfaceHolder.lockCanvas();//绿色背景mPaint.setColor(0xff00ff00);mCanvas.drawCircle(circle_radius, circle_radius, circle_radius, mPaint);if (isRecording) {count++;if (count > 3) {count = 1;}mPaint.setColor(Color.WHITE);if (count == 2) {//中间的---40rectF.set(circle_radius - RectRadius, circle_radius - RectHeight - curVolume,circle_radius + RectRadius, circle_radius + RectHeight + curVolume);mCanvas.drawRoundRect(rectF, RectRadius, RectRadius, mPaint);} else {rectF.set(circle_radius - RectRadius, circle_radius - RectHeight,circle_radius + RectRadius, circle_radius + RectHeight);mCanvas.drawRoundRect(rectF, RectRadius, RectRadius, mPaint);}if (count == 1) {//左边的rectF.set(circle_radius - RectRadius - RectDivide - RectRadius * 2,circle_radius - RectHeight - curVolume,circle_radius - RectRadius - RectDivide,circle_radius + RectHeight + curVolume);mCanvas.drawRoundRect(rectF, RectRadius, RectRadius, mPaint);} else {rectF.set(circle_radius - RectRadius - RectDivide - RectRadius * 2,circle_radius - RectHeight,circle_radius - RectRadius - RectDivide,circle_radius + RectHeight);mCanvas.drawRoundRect(rectF, RectRadius, RectRadius, mPaint);}if (count == 3) {//右边的rectF.set(circle_radius + RectRadius + RectDivide, circle_radius - RectHeight - curVolume,circle_radius + RectRadius + RectDivide + RectRadius * 2,circle_radius + RectHeight + curVolume);mCanvas.drawRoundRect(rectF, RectRadius, RectRadius, mPaint);} else {//右边的rectF.set(circle_radius + RectRadius + RectDivide, circle_radius - RectHeight,circle_radius + RectRadius + RectDivide + RectRadius * 2,circle_radius + RectHeight);mCanvas.drawRoundRect(rectF, RectRadius, RectRadius, mPaint);}} else if (isParsing) {count++;if (count > 3) {count = 1;}mPaint.setColor(Color.WHITE);switch (count) {case 1://中间mCanvas.drawCircle(circle_radius, circle_radius, RectRadius, mPaint);//右边mCanvas.drawCircle(circle_radius + RectRadius + RectDivide + RectRadius,circle_radius, RectRadius, mPaint);break;case 2://左边mCanvas.drawCircle(circle_radius - RectRadius - RectDivide - RectRadius,circle_radius, RectRadius, mPaint);//右边mCanvas.drawCircle(circle_radius + RectRadius + RectDivide + RectRadius,circle_radius, RectRadius, mPaint);break;case 3://左边mCanvas.drawCircle(circle_radius - RectRadius - RectDivide - RectRadius,circle_radius, RectRadius, mPaint);//中间mCanvas.drawCircle(circle_radius, circle_radius, RectRadius, mPaint);break;}} else {Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.microphone_big);//96 X 96 BitmapmCanvas.drawBitmap(bitmap, circle_radius - bitmap.getWidth() / 2,circle_radius - bitmap.getHeight() / 2, null);}} catch (Exception e) {e.printStackTrace();} finally {if (mCanvas != null) {mSurfaceHolder.unlockCanvasAndPost(mCanvas);}}}private long firstTouchTime;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:firstTouchTime = System.currentTimeMillis();break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_UP:long upTouchTime = System.currentTimeMillis();if ((upTouchTime - firstTouchTime) <= 800) {if (!isParsing) {//有效点击if (isRecording) {isRecording = false;//录音结束,开始解析isParsing = true;count = 0;if (anInterface != null) {anInterface.stopEvaluate();}} else {isRecording = true;//开始录音测评count = 0;if (anInterface != null) {anInterface.startEvaluate();}}}}break;}return true;}private EvaluationInterface anInterface;public void setAnInterface(EvaluationInterface anInterface) {this.anInterface = anInterface;}public interface EvaluationInterface {void startEvaluate();void stopEvaluate();}
}

二、讯飞测评和语音合成TTS

//测评使用(记得以来so以及在Application中初始化引擎,需要appkey等)
//第一步:创建SpeechEvaluator对象
SpeechEvaluator mSpeechEvaluator = SpeechEvaluator.createEvaluator(this, null);
//第二步:设置参数
//必须设置的参数分别是:language、category、 encoding、 要评测的文本内容
mSpeechEvaluator.setParameter(SpeechConstant.LANGUAGE, language);
mSpeechEvaluator.setParameter(SpeechConstant.ISE_CATEGORY, category);
mSpeechEvaluator.setParameter(SpeechConstant.TEXT_ENCODING, "utf-8");
//注释的两个是VAD切割音频的时间线参数设置具体参考讯飞文档
//        mSpeechEvaluator.setParameter(SpeechConstant.VAD_BOS, vad_bos);
//        mSpeechEvaluator.setParameter(SpeechConstant.VAD_EOS, vad_eos);
mSpeechEvaluator.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT, speech_timeout);
mSpeechEvaluator.setParameter(SpeechConstant.RESULT_LEVEL, result_level);
// 设置音频保存路径,保存音频格式仅为pcm,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
curAudioPath = QZXTools.getExternalStorageForCache(this) + "/msc/"+ language + "_" + category + "_" +
QZXTools.getFormatCurrentDateToSecond() + ".pcm";
mSpeechEvaluator.setParameter(SpeechConstant.ISE_AUDIO_PATH, curAudioPath);
//第三步:开始测评开启评测监听器
mSpeechEvaluator.startEvaluating(getResources().getString(textResId[currentTextId]),null, mEvaluatorListener);
// 评测监听接口
private EvaluatorListener mEvaluatorListener = new EvaluatorListener() {@Overridepublic void onResult(EvaluatorResult result, boolean isLast) {QZXTools.logE("zbv", "evaluator result :" + isLast + "", null);if (isLast) {StringBuilder builder = new StringBuilder();builder.append(result.getResultString());QZXTools.logE("zbv", "mLastResult=" + builder.toString(), null);XmlResultParser resultParser = new XmlResultParser();Result result_final = resultParser.parse(builder.toString());//五分制float score = result_final.total_score;if (ratingBar.getVisibility() != View.VISIBLE) {ratingBar.setVisibility(View.VISIBLE);}QZXTools.logE("zbv", "score=" + score + ";result=" + result_final, null);ratingBar.setRating(score);//解析结果出来了speechVoiceView.setParsing(false);if (null != result) {tv_report.setText(result_final.toString());if (score >= 4.3 && score <= 5.0) {mTts.startSpeaking("七子笑小朋友,你真的太棒了!", mTtsListener);} else if (score >= 3 && score <= 4.2) {mTts.startSpeaking("七子笑小朋友,你做的很好!", mTtsListener);} else if (score >= 2.4 && score <= 2.9) {mTts.startSpeaking("七子笑小朋友,你还不错哟!", mTtsListener);} else {mTts.startSpeaking("七子笑小朋友,需要好好努力哦!", mTtsListener);}} else {QZXTools.popToast(SpeechEvaluationDemoActivity.this,"结析结果为空", false);}}}@Overridepublic void onError(SpeechError error) {if (error != null) {QZXTools.logE("zbv", "error:" + error.getErrorCode() + "," +error.getErrorDescription(), null);} else {QZXTools.logE("zbv", "evaluator over", null);}}@Overridepublic void onBeginOfSpeech() {QZXTools.logE("zbv", "evaluator begin", null);}@Overridepublic void onEndOfSpeech() {QZXTools.logE("zbv", "evaluator stoped", null);}@Overridepublic void onVolumeChanged(int volume, byte[] data) {speechVoiceView.setCurVolume(volume);}@Overridepublic void onEvent(int eventType, int arg1, int arg2, Bundle obj) {// TODO Auto-generated method stub}};
//停止测评if (mSpeechEvaluator.isEvaluating()) {mSpeechEvaluator.stopEvaluating();}
//最后释放评测资源及引擎if (null != mSpeechEvaluator) {mSpeechEvaluator.destroy();mSpeechEvaluator = null;}//语音合成TTS使用
//第一步:初始化TTS引擎对象
SpeechSynthesizer mTts = SpeechSynthesizer.createSynthesizer(this, mTtsInitListener);
//第二步:设置参数
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.TTS_DATA_NOTIFY, "1");// 设置在线合成发音人mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);//设置合成语速mTts.setParameter(SpeechConstant.SPEED, "50");//设置合成音调mTts.setParameter(SpeechConstant.PITCH, "50");//设置合成音量mTts.setParameter(SpeechConstant.VOLUME, "50");} else {mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);// 设置本地合成发音人 voicer为空,默认通过语记界面指定发音人。mTts.setParameter(SpeechConstant.VOICE_NAME, "");/*** TODO 本地合成不设置语速、音调、音量,默认使用语记设置* 开发者如需自定义参数,请参考在线合成参数设置*/}//设置播放器音频流类型mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");// 设置播放合成音频打断音乐播放,默认为truemTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");// 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限// 注:AUDIO_FORMAT参数语记需要更新版本才能生效mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "pcm");mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/tts.pcm");}
//第三步:开始播放ttsmTts.startSpeaking("七子笑小朋友,你真的太棒了!", mTtsListener);
//tts监听器
private SynthesizerListener mTtsListener = new SynthesizerListener() {@Overridepublic void onSpeakBegin() {QZXTools.logE("zbv", "开始播放", null);}@Overridepublic void onSpeakPaused() {QZXTools.logE("zbv", "暂停播放", null);}@Overridepublic void onSpeakResumed() {QZXTools.logE("zbv", "继续播放", null);}@Overridepublic void onBufferProgress(int percent, int beginPos, int endPos,String info) {// 合成进度}@Overridepublic void onSpeakProgress(int percent, int beginPos, int endPos) {// 播放进度}@Overridepublic void onCompleted(SpeechError error) {if (error == null) {QZXTools.logE("zbv", "播放完成", null);} else if (error != null) {QZXTools.logE("zbv", "error=" + error.getPlainDescription(true), null);}}@Overridepublic 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);// }}};//最后释放资源和引擎if (null != mTts) {mTts.stopSpeaking();// 退出时释放连接mTts.destroy();}

三、demo代码参考

测评演示demo

讯飞语音测评的简单demo演示相关推荐

  1. 讯飞语音——带你简单实现语音听写

    语音听写 de 简单实现 一.前言 如果你没有在讯飞语音平台上创建应用,请先参考讯飞语音的详细配置使用 二.功能描述 语音听写和语音合成都是较为基础也是最常使用的两个基本功能. 语音合成是将文本转化为 ...

  2. 讯飞语音转文字 PHP demo

    讯飞语音转文字PHP tp6 demo 讯飞官网没有PHP demo我是很诧异的 改成了我需要的tp6 demo 讯飞官网没有PHP demo我是很诧异的 我php天下第一就这么没牌面吗 网上找了很久 ...

  3. H5调用讯飞语音接口实现在线语音听写测评

    韩顺平老师是我的人生导师,所以,老规矩,先看效果,后讲解:下面是效果图(页面较大,分屏效果) 这是在线语音听写: 这是在线语音测评: 下面我们来看看具体的代码实现: 1.在讯飞语音平台注册,创建一个应 ...

  4. 讯飞社区android 源码,android 讯飞语音 demo

    [实例简介] android 讯飞语音 demo 博客地址:http://blog.csdn.net/chenshufei2/article/details/8496905 [实例截图] [核心代码] ...

  5. 讯飞语音--唤醒Demo

    写的第一篇博客,因为最近姐姐说起了一个段子, 一男子在地铁站手机找不到了,但是带了蓝牙耳机,耳机还有内容,男子想手机一定还在附近,随即大喊一句,悟空你在哪儿, 手机循环回答,我在这.....这时,拿手 ...

  6. 使用腾讯云实现录音语音转换文字简单DEMO

    使用腾讯云实现录音语音转换文字简单DEMO 感谢 对接腾讯云 新建springboot项目 创建一个接口(VoiceService) 创建controller层(VoiceController) 加入 ...

  7. 研究讯飞语音 demo,下载跑跑

    本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/53401000 未经博主允许不得转载. 博主地址是:http://blog.csd ...

  8. 讯飞语音的 简单实现

    此处没有注明SDK的集成,,,请小伙伴到科大的平台自行集成/** * ATTENTION: This was auto-generated to implement the App Indexing ...

  9. iOS使用讯飞语音-语音识别(最新版)

    引言 去年在一家公司实习,接触了一点人工智能.既然接触人工智能,那么语音识别.语音合成.人脸识别等等都是必不可少的. 本来已经是离开iOS开发这条路了,还剩下毕业设计要做,所以这段时间最后一次回来接触 ...

  10. Android——讯飞语音唤醒简介及实现

    前段时间写了一个关于百度语音唤醒文章,最近有做了一个讯飞语音的应用,在这里把学习的资料整理一下. 唤醒的整个过程如下: (图源自讯飞官网) 讯飞的语音唤醒功能实现起来挺方便的(相比百度,百度语音And ...

最新文章

  1. @Transactional注解在什么情况下失效?
  2. 网上书店模板asp与html,一个简单的网上书城的例子(三)_asp实例
  3. edge robert matlab,哪位熟悉matlab的大神路过瞄一眼哈
  4. 读《redis设计与实现》笔记--redis数据结构
  5. vue 树形控件可编辑_vue.js element-ui组件改iview 第一期 tree树形控件
  6. 微软将不再把 .NET Framework API 移植到 .NET Core 3.0
  7. 一次线上事故,让我对MySql的时间戳存char(10)还是int(10)有了全新的认识
  8. MFC更改环境目录可执行文件目录下继承的值
  9. linux系统双显卡切换显卡驱动,Linux 下双显卡切换
  10. postman数据保存在哪里_Postman教程——使用数据文件
  11. 前TT(前T/T)与后TT(后T/T),以及信用证(LC,L/C)付款方式比较
  12. 【OSPF外部路由-4类LSA(sum-asbr)和5类LSA(external)以及7类LSA(Nssa)】(OSPF的特殊区域)(外部路由选路特性)
  13. Eval Reset忘记重置怎么办
  14. PHP 获取当天凌晨时间戳
  15. Mybatis if test中字符串比较和Mybatis的like查询
  16. 中国石油天然气股份有限公司2008年半年度报告摘要(业绩公告)
  17. 使用达思SQL数据库修复软件导出数据库时的接收数据的数据库如何清空表数据?
  18. python1.常见基础数据结构
  19. 你不在意的HTTPS证书吊销机制
  20. Vscode ctrl+单击鼠标 无法跳转定义

热门文章

  1. 基于 STM32F412RE 的 Flappy bird 游戏机实现
  2. jQuery动画效果
  3. 三星Galaxy之父加盟网秦,网秦安全能否脱胎换骨?
  4. 计算个股CAPM模型和Fama-French五因子模型(by Stata16MP)
  5. 计算机中文档的后退键,后退快捷键ctrl加什么
  6. UE4场景流程规范-纹理压缩(美术版/程序版/太长不看版)
  7. 病毒、木马、蠕虫、rootkit和后门
  8. Kalman滤波器参数分析
  9. SDCC编译器学习旅之一
  10. 薛逸凡计算机生物学,北大的孤独专业:一人旷课全系放假,毕业照从来只有一人...