前言:
语音评测(SpeechEvaluator):
通过智能语音技术自动对发音水平进行评价、发音错误、缺陷进行定位和问题分析。目前评音评测提供汉语、英语两种语言的评测,支持单字(汉语专有)、词语 和句子朗读三种题型。
效果图:
1、IseActivity.java
public class IseActivity extends AppCompatActivity implements VIEw.OnClickListener { private static final String TAG = "IseActivity"; private EditText mEvaTextEditText; private EditText mResultEditText; private button mIseStartbutton; private button iseLanguages, isetopic, iseResultLevel; private EditText iseStartTime, iseEndTime, iseTime; private String mLastResult; private SpeechEvaluator mIse; //切换(汉语、句子、等级) private String languageType = "zh_cn", topicType = "read_sentence", resultLevelType = "complete"; @OverrIDe public voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_ise); mIse = SpeechEvaluator.createEvaluator(this, null); initUI(); setEvaText(); } private voID initUI() { mEvaTextEditText = this.findVIEwByID(R.ID.ise_eva_text); mResultEditText = this.findVIEwByID(R.ID.ise_result_text); mIseStartbutton = this.findVIEwByID(R.ID.ise_start); iseLanguages = this.findVIEwByID(R.ID.ise_languages); isetopic = this.findVIEwByID(R.ID.ise_topic); iseResultLevel = this.findVIEwByID(R.ID.ise_result_level); iseStartTime = this.findVIEwByID(R.ID.ise_start_time); iseEndTime = this.findVIEwByID(R.ID.ise_end_time); iseTime = this.findVIEwByID(R.ID.ise_time); mIseStartbutton.setonClickListener(this); iseLanguages.setonClickListener(this); isetopic.setonClickListener(this); iseResultLevel.setonClickListener(this); findVIEwByID(R.ID.ise_parse).setonClickListener(this); findVIEwByID(R.ID.ise_stop).setonClickListener(this); findVIEwByID(R.ID.ise_cancel).setonClickListener(this); } @OverrIDe public voID onClick(VIEw vIEw) { if (null == mIse) { // 创建单例失败,与 21001 错误为同样原因,参考 http://bbs.xfyun.cn/forum.PHP?mod=vIEwthread&tID=9688 showToast("创建对象失败,请确认 libmsc.so 放置正确,且有调用 createUtility 进行初始化"); return; } switch (vIEw.getID()) { case R.ID.ise_start: if (mIse == null) { return; } String evaText = mEvaTextEditText.getText().toString(); mLastResult = null; mResultEditText.setText(""); mResultEditText.setHint("请朗读以上内容"); mIseStartbutton.setEnabled(false); setParams(); int ret = mIse.startEvaluating(evaText, null, mEvaluatorListener); //以下方法为通过直接写入音频的方式进行评测业务 /*if (ret != ErrorCode.SUCCESS) { showTip("识别失败,错误码:" + ret); } else { showTip(getString(R.string.text_begin_ise)); byte[] audioData = FucUtil.readAudiofile(IseDemo.this,"isetest.wav"); if(audioData != null) { //防止写入音频过早导致失败 try{ new Thread().sleep(100); }catch (InterruptedException e) { Log.d(TAG,"InterruptedException :"+e); } mIse.writeAudio(audioData,0,audioData.length); mIse.stopEvaluating(); } }*/ break; case R.ID.ise_parse: // 解析最终结果 if (!TextUtils.isEmpty(mLastResult)) { XmlResultParser resultParser = new XmlResultParser(); Result result = resultParser.parse(mLastResult); if (null != result) { mResultEditText.setText(result.toString()); } else { showToast("解析结果为空"); } } break; case R.ID.ise_stop: if (mIse.isEvaluating()) { mResultEditText.setHint("评测已停止,等待结果中..."); mIse.stopEvaluating(); } break; case R.ID.ise_cancel: mIse.cancel(); mIseStartbutton.setEnabled(true); mResultEditText.setText(""); mResultEditText.setHint("请点击“开始评测”按钮"); mLastResult = null; break; case R.ID.ise_languages: if (languageType.equals("zh_cn")) { languageType = "en_us"; iseLanguages.setText("语种:英语"); } else { languageType = "zh_cn"; iseLanguages.setText("语种:汉语"); } setEvaText(); break; case R.ID.ise_topic: if (topicType.equals("read_sentence")) { topicType = "read_word"; isetopic.setText("题型:词语"); } else if (topicType.equals("read_word")) { topicType = "read_syllable"; isetopic.setText("题型:单词"); } else { topicType = "read_sentence"; isetopic.setText("题型:句子"); } setEvaText(); break; case R.ID.ise_result_level: if (resultLevelType.equals("complete")) { resultLevelType = "plain"; iseResultLevel.setText("等级:plain"); } else { resultLevelType = "complete"; iseResultLevel.setText("等级:complete"); } setEvaText(); break; default: } } // 设置评测试题 private voID setEvaText() { String text = ""; if ("en_us".equals(languageType)) { if ("read_word".equals(topicType)) { text = getString(R.string.text_en_word); } else if ("read_sentence".equals(topicType)) { text = getString(R.string.text_en_sentence); } } else { // 中文评测 if ("read_syllable".equals(topicType)) { text = getString(R.string.text_cn_syllable); } else if ("read_word".equals(topicType)) { text = getString(R.string.text_cn_word); } else if ("read_sentence".equals(topicType)) { text = getString(R.string.text_cn_sentence); } } mEvaTextEditText.setText(text); mResultEditText.setText(""); mLastResult = null; mResultEditText.setHint("请点击“开始评测”按钮"); } private voID setParams() { // 设置评测语言 mIse.setParameter(SpeechConstant.LANGUAGE, languageType); // 设置需要评测的类型 mIse.setParameter(SpeechConstant.ISE_category, topicType); // 设置结果等级(中文仅支持complete) mIse.setParameter(SpeechConstant.RESulT_LEVEL, resultLevelType); mIse.setParameter(SpeechConstant.TEXT_ENCoding, "utf-8"); // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理 mIse.setParameter(SpeechConstant.VAD_BOS, iseStartTime.getText().toString()); // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音 mIse.setParameter(SpeechConstant.VAD_EOS, iseEndTime.getText().toString()); // 语音输入超时时间,即用户最多可以连续说多长时间;(-1无超时) mIse.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT, iseTime.getText().toString()); mIse.setParameter(SpeechConstant.AUdio_FORMAT_AUE, "opus"); // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限 mIse.setParameter(SpeechConstant.AUdio_FORMAT, "wav"); mIse.setParameter(SpeechConstant.ISE_AUdio_PATH, Environment.getExternalStorageDirectory().getabsolutePath() + "/msc/helloword_ise.wav"); //通过writeaudio方式直接写入音频时才需要此设置 //mIse.setParameter(SpeechConstant.AUdio_SOURCE,"-1"); } // 评测监听接口 private EvaluatorListener mEvaluatorListener = new EvaluatorListener() { @OverrIDe public voID onResult(EvaluatorResult result, boolean isLast) { Log.e(TAG, "evaluator result :" + isLast); if (isLast) { StringBuilder builder = new StringBuilder(); builder.append(result.getResultString()); if (!TextUtils.isEmpty(builder)) { mResultEditText.setText(builder.toString()); } mIseStartbutton.setEnabled(true); mLastResult = builder.toString(); showToast("评测结束"); } } @OverrIDe public voID one rror(SpeechError error) { mIseStartbutton.setEnabled(true); if (error != null) { showToast("error:" + error.getErrorCode() + "," + error.getErrorDescription()); mResultEditText.setText(""); mResultEditText.setHint("请点击“开始评测”按钮"); } else { Log.e(TAG, "evaluator over"); } } @OverrIDe public voID onBeginofSpeech() { // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入 Log.e(TAG, "onBeginofSpeech: evaluator begin"); } @OverrIDe public voID onEndOfSpeech() { // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入 Log.e(TAG, "onEndOfSpeech: evaluator stoped"); } @OverrIDe public voID onVolumeChanged(int volume, byte[] data) { showToast("当前音量:" + volume); Log.e(TAG, "onVolumeChanged: 返回音频数据" + data.length); } @OverrIDe public voID onEvent(int eventType, int arg1, int arg2, Bundle obj) { // 以下代码用于获取与云端的会话ID,当业务出错时将会话ID提供给技术支持人员,可用于查询会话日志,定位出错原因 // if (SpeechEvent.EVENT_SESSION_ID == eventType) { // String sID = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID); // Log.d(TAG, "session ID =" + sID); // } } }; /** * 展示吐司 */ private voID showToast(final String str) { Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); } @OverrIDe protected voID onResume() { // 开放统计 移动数据统计分析 //FlowerCollector.onResume(IseDemo.this); //FlowerCollector.onPageStart(TAG); super.onResume(); } @OverrIDe protected voID onPause() { // 开放统计 移动数据统计分析 //FlowerCollector.onPageEnd(TAG); //FlowerCollector.onPause(IseDemo.this); super.onPause(); } @OverrIDe protected voID onDestroy() { super.onDestroy(); if (null != mIse) { mIse.destroy(); mIse = null; } }}
布局文件activity_ise.xml:
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:gravity="center_horizontal" androID:orIEntation="vertical" androID:paddingleft="10dp" androID:paddingRight="10dp"> <TextVIEw androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_centerInParent="true" androID:text="讯飞评测示例" androID:textSize="30sp" /> <EditText androID:ID="@+ID/ise_eva_text" androID:layout_wIDth="match_parent" androID:layout_height="120dp" androID:layout_marginBottom="5dp" androID:gravity="top|left" androID:textSize="20sp" /> <EditText androID:ID="@+ID/ise_result_text" androID:layout_wIDth="match_parent" androID:layout_height="0dp" androID:layout_weight="1" androID:gravity="top|left" androID:hint="请点击“开始评测”按钮" androID:textSize="16sp" /> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:layout_margintop="10dp" androID:gravity="center_vertical" androID:orIEntation="horizontal"> <button androID:ID="@+ID/ise_languages" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="语种:汉语" androID:textSize="16sp" /> <button androID:ID="@+ID/ise_topic" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="题型:句子" androID:textSize="16sp" /> <button androID:ID="@+ID/ise_result_level" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="等级:complete" androID:textSize="16sp" /> </linearLayout> <EditText androID:ID="@+ID/ise_start_time" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:hint="前端超时:(默认:5000ms)" androID:inputType="number" androID:padding="10dp" androID:textSize="20sp" /> <EditText androID:ID="@+ID/ise_end_time" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:hint="后端超时:(默认:1800ms)" androID:inputType="number" androID:padding="10dp" androID:textSize="20sp" /> <EditText androID:ID="@+ID/ise_time" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:hint="评测超时:(默认:-1无超时,单位同上)" androID:inputType="number" androID:padding="10dp" androID:textSize="20sp" /> <TextVIEw androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:text="修改数值后需重新开始评测" androID:textSize="15sp" /> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:layout_margintop="5dp" androID:layout_marginBottom="2dp" androID:gravity="center_horizontal" androID:orIEntation="horizontal"> <button androID:ID="@+ID/ise_start" androID:layout_wIDth="0dp" androID:layout_height="wrap_content" androID:layout_weight="1" androID:text="开始评测" androID:textSize="20sp" /> <button androID:ID="@+ID/ise_stop" androID:layout_wIDth="0dp" androID:layout_height="wrap_content" androID:layout_weight="1" androID:text="停止评测" androID:textSize="20sp" /> </linearLayout> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:layout_margintop="10dp" androID:layout_marginBottom="2dp" androID:gravity="center_horizontal" androID:orIEntation="horizontal"> <button androID:ID="@+ID/ise_cancel" androID:layout_wIDth="0dp" androID:layout_height="wrap_content" androID:layout_weight="1" androID:text="取消评测" androID:textSize="20sp" /> <button androID:ID="@+ID/ise_parse" androID:layout_wIDth="0dp" androID:layout_height="wrap_content" androID:layout_weight="1" androID:text="结果解析" androID:textSize="20sp" /> </linearLayout></linearLayout>
2、工具类XmlResultParser.java(Demo中也有):
public class XmlResultParser { public Result parse(String xml) { if (TextUtils.isEmpty(xml)) { return null; } XmlPullParser pullParser = Xml.newPullParser(); try { inputStream ins = new ByteArrayinputStream(xml.getBytes()); pullParser.setinput(ins, "utf-8"); FinalResult finalResult = null; int eventType = pullParser.getEventType(); while (XmlPullParser.END_document != eventType) { switch (eventType) { case XmlPullParser.START_TAG: if ("FinalResult".equals(pullParser.getname())) { // 只有一个总分的结果 finalResult = new FinalResult(); } else if ("ret".equals(pullParser.getname())) { finalResult.ret = getInt(pullParser, "value"); } else if ("total_score".equals(pullParser.getname())) { finalResult.total_score = getfloat(pullParser, "value"); } else if ("xml_result".equals(pullParser.getname())) { // 详细结果 return parseResult(pullParser); } break; case XmlPullParser.END_TAG: if ("FinalResult".equals(pullParser.getname())) { return finalResult; } break; default: break; } eventType = pullParser.next(); } } catch (XmlPullParserException e) { e.printstacktrace(); } catch (IOException e) { e.printstacktrace(); } return null; } private Result parseResult(XmlPullParser pullParser) { Result result = null; // <rec_paper>标签是否已扫描到 boolean rec_paperPassed = false; Sentence sentence = null; Word word = null; Syll syll = null; Phone phone = null; int eventType; try { eventType = pullParser.getEventType(); while (XmlPullParser.END_document != eventType) { switch (eventType) { case XmlPullParser.START_TAG: if ("rec_paper".equals(pullParser.getname())) { rec_paperPassed = true; } else if ("read_syllable".equals(pullParser.getname())) { if (!rec_paperPassed) { result = new ReadSyllableResult(); } else { readTotalResult(result, pullParser); } } else if ("read_word".equals(pullParser.getname())) { if (!rec_paperPassed) { result = new ReaDWordResult(); String lan = getLanguage(pullParser); result.language = (null == lan) ? "cn" : lan; } else { readTotalResult(result, pullParser); } } else if ("read_sentence".equals(pullParser.getname()) || "read_chapter".equals(pullParser.getname())) { if (!rec_paperPassed) { result = new ReadSentenceResult(); String lan = getLanguage(pullParser); result.language = (null == lan) ? "cn" : lan; } else { readTotalResult(result, pullParser); } } else if ("sentence".equals(pullParser.getname())) { if (null == result.sentences) { result.sentences = new ArrayList<Sentence>(); } sentence = createSentence(pullParser); } else if ("word".equals(pullParser.getname())) { if (null != sentence && null == sentence.words) { sentence.words = new ArrayList<Word>(); } word = createWord(pullParser); } else if ("syll".equals(pullParser.getname())) { if (null != word && null == word.sylls) { word.sylls = new ArrayList<Syll>(); } syll = createSyll(pullParser); } else if ("phone".equals(pullParser.getname())) { if (null != syll && null == syll.phones) { syll.phones = new ArrayList<Phone>(); } phone = createPhone(pullParser); } break; case XmlPullParser.END_TAG: if ("phone".equals(pullParser.getname())) { syll.phones.add(phone); } else if ("syll".equals(pullParser.getname())) { word.sylls.add(syll); } else if ("word".equals(pullParser.getname())) { sentence.words.add(word); } else if ("sentence".equals(pullParser.getname())) { result.sentences.add(sentence); } else if ("read_syllable".equals(pullParser.getname()) || "read_word".equals(pullParser.getname()) || "read_sentence".equals(pullParser.getname())) { return result; } break; default: break; } eventType = pullParser.next(); } } catch (XmlPullParserException e) { e.printstacktrace(); } catch (IOException e) { e.printstacktrace(); } return result; } private voID readTotalResult(Result result, XmlPullParser pullParser) { result.beg_pos = getInt(pullParser, "beg_pos"); result.end_pos = getInt(pullParser, "end_pos"); result.content = getContent(pullParser); result.total_score = getfloat(pullParser, "total_score"); result.time_len = getInt(pullParser, "time_len"); result.except_info = getExceptInfo(pullParser); result.is_rejected = getIsRejected(pullParser); } private Phone createPhone(XmlPullParser pullParser) { Phone phone; phone = new Phone(); phone.beg_pos = getInt(pullParser, "beg_pos"); phone.end_pos = getInt(pullParser, "end_pos"); phone.content = getContent(pullParser); phone.dp_message = getInt(pullParser, "dp_message"); phone.time_len = getInt(pullParser, "time_len"); return phone; } private Syll createSyll(XmlPullParser pullParser) { Syll syll; syll = new Syll(); syll.beg_pos = getInt(pullParser, "beg_pos"); syll.end_pos = getInt(pullParser, "end_pos"); syll.content = getContent(pullParser); syll.symbol = getSymbol(pullParser); syll.dp_message = getInt(pullParser, "dp_message"); syll.time_len = getInt(pullParser, "time_len"); return syll; } private Word createWord(XmlPullParser pullParser) { Word word; word = new Word(); word.beg_pos = getInt(pullParser, "beg_pos"); word.end_pos = getInt(pullParser, "end_pos"); word.content = getContent(pullParser); word.symbol = getSymbol(pullParser); word.time_len = getInt(pullParser, "time_len"); word.dp_message = getInt(pullParser, "dp_message"); word.total_score = getfloat(pullParser, "total_score"); word.global_index = getInt(pullParser, "global_index"); word.index = getInt(pullParser, "index"); return word; } private Sentence createSentence(XmlPullParser pullParser) { Sentence sentence; sentence = new Sentence(); sentence.beg_pos = getInt(pullParser, "beg_pos"); sentence.end_pos = getInt(pullParser, "end_pos"); sentence.content = getContent(pullParser); sentence.time_len = getInt(pullParser, "time_len"); sentence.index = getInt(pullParser, "index"); sentence.word_count = getInt(pullParser, "word_count"); return sentence; } private String getLanguage(XmlPullParser pullParser) { return pullParser.getAttributeValue(null, "lan"); } private String getExceptInfo(XmlPullParser pullParser) { return pullParser.getAttributeValue(null, "except_info"); } private boolean getIsRejected(XmlPullParser pullParser) { String isRejected = pullParser.getAttributeValue(null, "is_rejected"); if (null == isRejected) { return false; } return Boolean.parseBoolean(isRejected); } private String getSymbol(XmlPullParser pullParser) { return pullParser.getAttributeValue(null, "symbol"); } private float getfloat(XmlPullParser pullParser, String attrname) { String val = pullParser.getAttributeValue(null, attrname); if (null == val) { return 0f; } return float.parsefloat(val); } private String getContent(XmlPullParser pullParser) { return pullParser.getAttributeValue(null, "content"); } private int getInt(XmlPullParser pullParser, String attrname) { String val = pullParser.getAttributeValue(null, attrname); if (null == val) { return 0; } return Integer.parseInt(val); }}
将Demo中result文件夹拷贝至项目中,如下图所示:
3、使用到的strings.xml:
<string name="text_en_word">"[word]\napple\nbanana\norange"</string><string name="text_en_sentence">"The quick brown fox jumps over the lazy dog."</string><string name="text_cn_syllable">"知,痴,是"</string><string name="text_cn_word">"磁铁,率领,脆弱,动手,古筝"</string><string name="text_cn_sentence">"一座座雪峰插入云霄,峰顶银光闪闪,大大小小的湖泊,像颗颗宝石镶嵌在彩带般的沟谷中。"</string>
总结 以上是内存溢出为你收集整理的Android讯飞语音集成【语音评测3】全部内容,希望文章能够帮你解决Android讯飞语音集成【语音评测3】所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)