1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 安卓开发之科大讯飞的语音合成和语音识别初实践

安卓开发之科大讯飞的语音合成和语音识别初实践

时间:2019-03-10 19:02:45

相关推荐

安卓开发之科大讯飞的语音合成和语音识别初实践

好久没有更新博客了,一个月又差不多过完了,公司的项目又被搁浅了,然后天天去客户公司无所事事,光看别人的代码最坑的是那套代码还没有注释,现在我是严重鄙视那些不写注释的程序狗,然后项目还跑不起来,以前也没有做过金融类的的项目,里面全都是一些报文格式,然后还没有需求文档,真的是醉了,刚好呢现在公司也不大管我们了,不注重研发的公司就是坑。。。。。。

今天呢随便来用下科大讯飞的语音功能,代码也非常的简单,然后就把它集成到一个查快递的app里,也是懒得改东西了。

首先就先来说下科大讯飞:语音技术实现了人机语音交互,使人与机器之间沟通变得像人与人沟通一样简单。语音技术主要包括语音合成和语音识别两项关键技术。让机器说话,用的是语音合成技术;让机器听懂人说话,用的是语音识别技术。此外,语音技术还包括语音编码、音色转换、口语评测、语音消噪和增强等技术,有着广阔应用空间。

讯飞的语音sdk是需要申请的,地址是:/。申请一个讯飞的开发者账号,然后申请一个appid,申请的时候需要填写开发者信息和你的应用的信息。记住这个appid是开发中必须用到的,所以搞那么麻烦就是为了这个appid和下载开发的sdk。这appid与你开启的服务有关,一般就基础服务就好了,有些是增值服务,然后每一个项目的appid都是不一样的。

由于科大讯飞的sdk的版本有所不同,然后调用的方法也有所不同,特别是Msc.jar里面的内容是不断更新的,开发的时候你可以先导入他的sample看看,去感受一下它的强大。然后我们就把libs文件夹拷贝到自己 的项目工程里,接着就是编写代码了,也不多说了。

这个文章是根据sdk写的,也参考了别人的代码,毕竟也是纯属好玩搞了一下,能够把声音转化为文字,再把文字转为声音,就能满足一些基本的功能了,里面的注释写的很详细,只要随便改改就能直接用到你的项目里面。

从图里可以看到这是运用的几个功能,但是好像Msc.jar的版本不一样所以调用的方法有所出入,然后我自己的好像就没有SpeechUtilty这个类,文中主要用到了RecognizerDialog,SpeechRecognizer,RecognizerDialogListener,SpeechListener,SynthesizerListener,SpeechSynthesizer。然后功能只能把语音转换为文字,再把文本信息本地合成语音,还有很多的地方需要完善。

简单效果:

先看布局

main_activity.xml

<RelativeLayout xmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:background="@drawable/icon_microphone"android:layout_alignParentRight="true"android:id="@+id/button1"/><EditTextandroid:id="@+id/content"android:layout_width="fill_parent"android:layout_marginRight="50dp"android:layout_height="30dp"android:layout_alignParentBottom="true"android:layout_alignParentLeft="true"/></RelativeLayout>

mainActivity.java

packagecom.example.voicetoword;importandroid.app.Activity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.view.Menu;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.EditText;importcom.coderqi.publicutil.voice.VoiceToWord;importcom.example.voicetoword.R;public classMainActivityextendsActivityimplementsOnClickListener{Buttonbut=null;privateEditTextcontent; @Overrideprotected voidonCreate(BundlesavedInstanceState) {super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);but= (Button) findViewById(R.id.button1);content=(EditText) findViewById(R.id.content);but.setOnClickListener(this); }@Overridepublic booleanonCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.main, menu);return true; }@Overridepublic voidonClick(Viewv) {switch(v.getId()) {//听写按钮caseR.id.button1:VoiceToWord voice =newVoiceToWord(MainActivity.this,"54ae8c54");//你申请的appid voice.GetWordFromVoice();break; }}@Overrideprotected voidonResume() {super.onResume(); //content.setText(((MyApplicaton)getApplication()).getText()); }}

接下来的就是数据解析类:

packagezy.voice;importorg.json.JSONArray;importorg.json.JSONObject;importorg.json.JSONTokener;importandroid.text.TextUtils;//import com.iflytek.speech.ErrorCode;//import com.iflytek.speech.SpeechError;/*** 对云端返回的Json结果进行解析*@authoriFlytek*@since1211*/public classJsonParser{/** * 听写结果的Json格式解析 *@paramjson*@return*/public staticStringparseIatResult(Stringjson) {if(TextUtils.isEmpty(json))return"";StringBufferret =newStringBuffer();try{JSONTokenertokener =newJSONTokener(json);JSONObjectjoResult =newJSONObject(tokener);JSONArraywords = joResult.getJSONArray("ws");for(inti = 0; i < words.length(); i++) {// 听写结果词,默认使用第一个结果JSONArrayitems = words.getJSONObject(i).getJSONArray("cw");JSONObjectobj = 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(Exceptione) {e.printStackTrace(); }returnret.toString(); }/** * 识别结果的Json格式解析 *@paramjson*@return*/public staticStringparseGrammarResult(Stringjson) {StringBufferret =newStringBuffer();try{JSONTokenertokener =newJSONTokener(json);JSONObjectjoResult =newJSONObject(tokener);JSONArraywords = joResult.getJSONArray("ws");//识别的为词for(inti = 0; i < words.length(); i++) {JSONArrayitems = words.getJSONObject(i).getJSONArray("cw");//中文分词for(intj = 0; j < items.length(); j++){JSONObjectobj = items.getJSONObject(j);if(obj.getString("w").contains("nomatch"))//不匹配的时候 {ret.append("没有匹配结果.");returnret.toString();}ret.append("【结果】"+ obj.getString("w"));ret.append("【置信度】"+ obj.getInt("sc"));//分数 ret.append("\n");}}}catch(Exceptione) {e.printStackTrace(); ret.append("没有匹配结果."); }returnret.toString(); }/** * 语义结果的Json格式解析 *@paramjson*@return*/public staticStringparseUnderstandResult(Stringjson) {StringBufferret =newStringBuffer();try{JSONTokenertokener =newJSONTokener(json);JSONObjectjoResult =newJSONObject(tokener); ret.append("【应答码】"+ joResult.getString("rc") +"\n"); ret.append("【转写结果】"+ joResult.getString("text") +"\n"); ret.append("【服务名称】"+ joResult.getString("service") +"\n"); ret.append("【操作名称】"+ joResult.getString("operation") +"\n"); ret.append("【完整结果】"+ json); }catch(Exceptione) {e.printStackTrace(); ret.append("没有匹配结果."); }returnret.toString(); }}

这个是弹出的说话的dialog

packagezy.voice;importandroid.content.Context;importandroid.text.TextUtils;importandroid.widget.Toast;importcom.iflytek.cloud.speech.RecognizerResult;importcom.iflytek.cloud.speech.SpeechConstant;importcom.iflytek.cloud.speech.SpeechError;importcom.iflytek.cloud.speech.SpeechSynthesizer;importcom.iflytek.cloud.speech.SynthesizerListener;importcom.iflytek.cloud.ui.RecognizerDialogListener;/*** 识别回调监听器*/public classMyRecognizerDialogListerimplementsRecognizerDialogListener,SynthesizerListener{privateContextcontext; //本地合成对象privateSpeechSynthesizerspeechSynthesizer;publicMyRecognizerDialogLister(Context context) {this.context= context; setParam(); }// 自定义的结果回调函数,成功执行第一个方法,失败执行第二个方法 @Overridepublic voidonResult(RecognizerResult results,booleanisLast) {Stringtext = JsonParser.parseIatResult(results.getResultString());Toast.makeText(context, text,Toast.LENGTH_LONG).show(); //app.setText(text);if(!TextUtils.isEmpty(text)){//如果返回的内容不为空 //开始把文本信息合成语音speechSynthesizer.startSpeaking(text,this); }}/** * 识别回调错误. */ @Overridepublic voidonError(SpeechError error) {//错误码请访问/index.php/default/doccenter/doccenterInner?itemTitle=ZmFx&anchor=Y29udGl0bGU2Ng== //TODO Auto-generated method stubinterrorCoder = error.getErrorCode();switch(errorCoder) {case10118://用户没有说话,没有数据System.out.println("user don't speak anything");break;case10200://网络一般错误System.out.println("can't connect to internet");break;default:break; }}public voidsetParam(){//创建SpeechSynthesizer 对象speechSynthesizer= SpeechSynthesizer.createSynthesizer(context);speechSynthesizer.setParameter(SpeechConstant.VOICE_NAME,"xiaoyan");//默认的,发音人为小燕(青年女声),小梅为新引擎参数,效果好点speechSynthesizer.setParameter(SpeechConstant.SPEED,"50");//语速speechSynthesizer.setParameter(SpeechConstant.VOLUME,"50");//音量,范围是0---100speechSynthesizer.setParameter(SpeechConstant.PITCH,"50"); }/** * percent 缓冲进度 0-100 * beginPos 缓冲音频在文中的开始位置 * endPos 缓冲音频在文中的末位置 * info 附加信息 * */ @Overridepublic voidonBufferProgress(intpercent,intbeginPos,intendPos,Stringinfo) {}//会话结束回调接口,无错误时err为null @Overridepublic voidonCompleted(SpeechError err) {}//开始播放 @Overridepublic voidonSpeakBegin() {}//暂停播放 @Overridepublic voidonSpeakPaused() {}/** * percent 播放进度 0-100 * beginPos 播放音频在文中的开始位置 * endPos 播放音频在文中的末位置 * */ @Overridepublic voidonSpeakProgress(intpercent,intbeginPos,intendPos) {}//恢复 播放 @Overridepublic voidonSpeakResumed() {}}

最后的是把你的话转为文字

packagezy.voice;importandroid.app.Activity;importandroid.content.Context;importandroid.content.SharedPreferences;importandroid.os.Bundle;importandroid.os.Environment;importandroid.text.TextUtils;importandroid.widget.Toast;importcom.iflytek.cloud.speech.SpeechConstant;importcom.iflytek.cloud.speech.SpeechError;importcom.iflytek.cloud.speech.SpeechListener;importcom.iflytek.cloud.speech.SpeechRecognizer;importcom.iflytek.cloud.speech.SpeechUser;importcom.iflytek.cloud.ui.RecognizerDialog;importcom.iflytek.cloud.ui.RecognizerDialogListener;importcom.iflytek.sunflower.FlowerCollector;public classVoiceToWordextendsActivity {privateContextcontext;privateToastmToast; // 识别窗口privateRecognizerDialogiatDialog; // 识别对象privateSpeechRecognizeriatRecognizer; // 缓存,保存当前的引擎参数到下一次启动应用程序使用.privateSharedPreferencesmSharedPreferences;privateRecognizerDialogListenerrecognizerDialogListener=null;publicVoiceToWord(Context context,StringAPP_ID) {//TODO Auto-generated constructor stub// 用户登录this.context= context; // 初始化缓存对象.mSharedPreferences= context.getSharedPreferences(context.getPackageName(),MODE_PRIVATE); SpeechUser.getUser().login(context,null,null,"appid="+ APP_ID,listener); // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizeriatDialog=newRecognizerDialog(context);mToast=Toast.makeText(context,"",Toast.LENGTH_LONG); // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizeriatDialog=newRecognizerDialog(context);iatDialog.setCanceledOnTouchOutside(false); }publicVoiceToWord(Context context,StringAPP_ID, RecognizerDialogListener recognizerDialogListener) {this.context= context; SpeechUser.getUser().login(context,null,null,"appid="+ APP_ID,listener); // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizeriatDialog=newRecognizerDialog(context);mToast=Toast.makeText(context,"",Toast.LENGTH_LONG); // 初始化听写Dialog,如果只使用有UI听写功能,无需创建SpeechRecognizeriatDialog=newRecognizerDialog(context); // 在dialog外面不能取消iatDialog.setCanceledOnTouchOutside(false); // 初始化缓存对象.mSharedPreferences= context.getSharedPreferences(context.getPackageName(),MODE_PRIVATE);this.recognizerDialogListener= recognizerDialogListener; }public voidGetWordFromVoice() {booleanisShowDialog =mSharedPreferences.getBoolean("iat_show",true);if(isShowDialog) {// 显示语音听写Dialog.showIatDialog(); }else{if(null==iatRecognizer) {iatRecognizer= SpeechRecognizer.createRecognizer(this);// 设置返回结果格式// iatRecognizer.setParameter(SpeechConstant.RESULT_TYPE, "json");//// String lag = mSharedPreferences.getString(//"iat_language_preference", "mandarin");// if (lag.equals("en_us")) {//// 设置语言//iatRecognizer// .setParameter(SpeechConstant.LANGUAGE, "en_us");// } else {//// 设置语言//iatRecognizer// .setParameter(SpeechConstant.LANGUAGE, "zh_cn");//// 设置语言区域//iatRecognizer.setParameter(SpeechConstant.ACCENT, lag);// }// // 设置语音前端点// iatRecognizer.setParameter(SpeechConstant.VAD_BOS,//mSharedPreferences.getString("iat_vadbos_preference",// "4000"));// // 设置语音后端点// iatRecognizer.setParameter(SpeechConstant.VAD_EOS,//mSharedPreferences.getString("iat_vadeos_preference",// "1000"));// // 设置标点符号// iatRecognizer.setParameter(SpeechConstant.ASR_PTT,//mSharedPreferences// .getString("iat_punc_preference", "1"));// // 设置音频保存路径// iatRecognizer.setParameter(SpeechConstant.ASR_AUDIO_PATH,//Environment.getExternalStorageDirectory()// + "/iflytek/wavaudio.pcm");//需在清单文件里添加sd卡的权限}if(iatRecognizer.isListening()) {iatRecognizer.stopListening();// ((Button)// findViewById(android.R.id.button1)).setEnabled(false);}else{}}}/** * 显示听写对话框. * *@param*/public voidshowIatDialog() {if(null==iatDialog) {// 初始化听写DialogiatDialog=newRecognizerDialog(this); }// 获取引擎参数Stringengine =mSharedPreferences.getString("iat_engine","iat"); // 清空Grammar_ID,防止识别后进行听写时Grammar_ID的干扰iatDialog.setParameter(SpeechConstant.CLOUD_GRAMMAR,null); // 设置听写Dialog的引擎iatDialog.setParameter(SpeechConstant.DOMAIN, engine); // 设置采样率参数,支持8K和16KStringrate =mSharedPreferences.getString("sf","sf");if(rate.equals("rate8k")) {iatDialog.setParameter(SpeechConstant.SAMPLE_RATE,"8000"); }else{iatDialog.setParameter(SpeechConstant.SAMPLE_RATE,"16000"); }if(recognizerDialogListener==null) {getRecognizerDialogListener(); }// 显示听写对话框iatDialog.setListener(recognizerDialogListener);iatDialog.show(); }private voidgetRecognizerDialogListener() {/** * 识别回调监听器 */recognizerDialogListener=newMyRecognizerDialogLister(context); }/** * 用户登录回调监听器. */privateSpeechListenerlistener=newSpeechListener() {@Overridepublic voidonData(byte[] arg0) {}@Overridepublic voidonCompleted(SpeechError error) {if(error !=null) {System.out.println("user login success"); }}@Overridepublic voidonEvent(intarg0,Bundlearg1) {}};protected voidonDestroy() {// 退出时释放连接iatRecognizer.cancel();iatRecognizer.destroy(); }; @Overrideprotected voidonResume() {// 移动数据统计分析FlowerCollector.onResume(this); FlowerCollector.onPageStart("VoiceToWord");super.onResume(); }@Overrideprotected voidonPause() {// 移动数据统计分析FlowerCollector.onPageEnd("VoiceToWord"); FlowerCollector.onPause(this);super.onPause(); }}

最后别忘了添加权限

写博客真的是一个辛苦的过程,以后要多努力,更希望技术会有所提高

源码的下载地:》》》》》》》》》》》》》》》》》》》》》》/detail/u013278099/8377787

下下来可以玩玩,呵呵,不要积分的额

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。