失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 手把手的操作——用java调用科大讯飞的离线语音识别dll实现离线识别(JNA实现)(二)

手把手的操作——用java调用科大讯飞的离线语音识别dll实现离线识别(JNA实现)(二)

时间:2019-05-29 15:26:36

相关推荐

手把手的操作——用java调用科大讯飞的离线语音识别dll实现离线识别(JNA实现)(二)

上一篇的地址手把手的操作——用java调用科大讯飞的离线语音识别dll实现离线识别(JNA实现)(一)

上一篇讲到了最难的地方,参数的转换,这里单独写出来

**

三、参数的转换(难点)

**

注:本文是以讯飞提供的C语言例子作为模板改写,语音来源于文件

1、先分析提供的例子

本人使用的是VS

下载链接链接:/s/1CZX3k6nhsbLkuzB3mocyww 提取码:6r5g

2.45G大小,需要安装一段时间,因为用JNA只用看,这个版本够了

【为了给我一样对C/C++不了解的初阶,大神轻喷】

运行之后

【文件】–【打开】–【项目/解决方案】–自己找文件位置–【asr_offline_sample.vcxproj】

同样的方法打开头文件

【文件】–【打开】–【文件】–自己找文件位置–【头文件.h结尾的】

主要看例子asr_sample.c

在java中主要就是将这个文件进行改写,所以要先看懂

我自己看了很久,讲下结构吧:

上面几个是各项功能的函数,最下面是主函数main,跟java的结构很像吧

几大主要功能

【登录】

【建立语法】

【建立词典】

【语音识别】

【退出】

看上去很简单啊,接下来就是一个一个在java中实现

我先建立了一个lib接口,里面放调用的东西

(先把动态库加载进来)

public interface VoiceLib extends Library{VoiceLib instance = (VoiceLib)Native.loadLibrary("msc_x64", VoiceLib.class);}

#1登录

这个功能在(一)中已经有例子了,这里重写一遍就好

public interface VoiceLib extends Library{VoiceLib instance = (VoiceLib)Native.loadLibrary("msc_x64", VoiceLib.class);int MSPLogin(String usr, String pwd, String params);}

新建主类xMsc

改写登录功能

public static void main(String[] args) {String login_config = "appid=5ba4***"; //登录参数UserData asr_data=null ;int ret = 0;ret = VoiceLib.instance.MSPLogin(null, null, login_config); //第一个参数为用户名,第二个参数为密码,传null即可,第三个参数是登录参数if (MSP_SUCCESS!= ret) {System.out.println("登录失败!");exit();}}

上面先改写下几个常量:

public class xMsc {public static final int SAMPLE_RATE_16K = 16000;public static final int SAMPLE_RATE_8K = 8000;public static final int MAX_GRAMMARID_LEN = 32;public static final int MAX_PARAMS_LEN = 1024;public static final int MSP_SUCCESS = 0;public static final int MSP_FAILED = 1;private static int MSP_AUDIO_SAMPLE_FIRS = 1;private static int MSP_AUDIO_SAMPLE_CONTINUE = 2;private static int MSP_EP_LOOKING_FOR_SPEECH = 0;private static int MSP_REC_STATUS_INCOMPLETE = 2;private static int MSP_EP_AFTER_SPEECH = 3;private static int MSP_AUDIO_SAMPLE_LAST = 4;private static int MSP_REC_STATUS_COMPLETE = 5;private static File f_pcm = null;private static byte[] pcm_data =null;private static int errcode = -1;private static String session_id = "";private static IntByReference ep_status = new IntByReference(MSP_EP_LOOKING_FOR_SPEECH);private static IntByReference rec_status = new IntByReference(MSP_REC_STATUS_INCOMPLETE);private static IntByReference rss_status1 = new IntByReference(MSP_AUDIO_SAMPLE_FIRS);private static IntByReference err = new IntByReference(errcode);public static final String ASR_RES_PATH = "fo|common.jet"; // 离线语法识别资源路径public static final String GRM_BUILD_PATH = "./msc/GrmBuilld_x64"; // 构建离线语法识别网络生成数据保存路径public static final String GRM_FILE = "./source/szx.bnf"; // 构建离线识别语法网络所用的语法文件public static final String LEX_NAME = "contact"; // 更新离线识别语法的contact槽(语法文件为此示例中使用的call.bnf)

里面的路径必须要跟我一样,尤其是 ASR_RES_PATH ,前面必须加"fo|"

有几个文件要拷贝过来啊,语法文件之类,我建立了一个source文件夹,都放里面了

现在的结构

【先一口气把main里面的全部改写完吧!】

public static void main(String[] args) {String login_config = "appid=5ba4*****"; //登录参数,要改成自己的asr_data = new UserData();int ret = 0;ret = VoiceLib.instance.MSPLogin(null, null, login_config); // 第一个参数为用户名,第二个参数为密码,传null即可,第三个参数是登录参数if (MSP_SUCCESS != ret) {System.out.println("登录失败!");exit();}System.out.println("登录成功!");System.out.println("构建离线识别语法网络...\n");ret = build_grammar(asr_data); // 第一次使用某语法进行识别,需要先构建语法网络,获取语法ID,之后使用此语法进行识别,无需再次构建if (MSP_SUCCESS != ret) {System.out.println("构建语法调用失败!\n");exit();}while (MSP_FAILED != asr_data.build_fini) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}if (MSP_SUCCESS != asr_data.errcode) {exit();}System.out.println("离线识别语法网络构建完成,开始识别...\n");ret = run_asr(asr_data);if (MSP_SUCCESS != ret) {System.out.println("离线语法识别出错: \n");exit();}}

【注】词典我删掉了,和构建语法一样,需要的自己写喽

¥¥¥¥¥退出功能先封装一下¥¥¥¥¥¥

public static void exit(){VoiceLib.instance.MSPLogout();System.out.println("请按任意键退出...\n");}

【再来一口气】把要用的函数全部封装到VoiceLib中,等下直接调用

import com.sun.jna.Library;import com.sun.jna.Native;import com.sun.jna.Pointer;import com.sun.jna.ptr.IntByReference;import com.szxinfo.recognizer.CallbackUtil.GrammarCallBack;public interface VoiceLib extends Library{String filePath = "mscx64";VoiceLib instance = (VoiceLib)Native.loadLibrary(filePath, VoiceLib.class);int MSPLogin(String usr, String pwd, String params);int QISRBuildGrammar (String cs2, String grm_content, int grm_cnt_len, String grm_build_params, GrammarCallBack grammarCallBack, Pointer pointer);String QISRSessionBegin(String grammarList, String asr_params, IntByReference errcode);int QISRAudioWrite(String session_id, byte[] every, int waveLen, int audioStatus, IntByReference ep_status1, IntByReference rec_status1);String QISRGetResult(String session_id, IntByReference rss_status1, int waitTime, IntByReference err);int QISRSessionEnd(String sessionID, String hints);// int GrammarCallBack(int ecode, String info, UserData udata);int MSPLogout();}

【这里的参数我都已经改好啦,等下到具体功能再解释】

然后写语法的

//重要分割线*********************************//

在讯飞提供的例子中,有一个回调函数和一个构建语法函数,都要改写,怎么办呢?

回调函数我封装到一个Util中(后面的词典回调一起了)

package com.xinzhi;import com.sun.jna.Callback;import com.sun.jna.Pointer;public class CallbackUtil {//语法回调函数的接口public static interface GrammarCallBack extends Callback{int build_grm_cb(int ecode, String info, Pointer udata);}//语法回调函数的实现public static class GrammarCallBack_Realize implements GrammarCallBack{@Overridepublic int build_grm_cb(int ecode, String info,Pointer udata) {UserData g_udata=Util.fromPointer(udata, 0);if (null != g_udata) {xMsc.asr_data.build_fini = com.szxinfo.recognizer.xMsc.MSP_FAILED;xMsc.asr_data.errcode = ecode;} if (com.szxinfo.recognizer.xMsc.MSP_SUCCESS == ecode && null != info) {System.out.println("构建语法成功! 语法ID:"+info);if (null != g_udata) {xMsc.asr_data.grammar_id=info;}}else {System.out.println("构建语法失败!错误代码:"+ ecode);}return 0;}}}

里面还有错误啊,回头来改!

【终板ps】这里面的错误已经全部修改完成

其中void,我使用Pointer来模拟*

再来写语法的

//构建离线识别语法网络@SuppressWarnings("finally")public static int build_grammar(UserData asr_data2) {File grm_file = null;String grm_content = null;int grm_cnt_len = 0;String grm_build_params = null;int ret = MSP_SUCCESS;grm_file = new File(GRM_FILE);if (!grm_file.exists()) {System.out.println("打开语法文件失败!");return MSP_FAILED;}// 按照字节读取语法文件,并将字节添加到grm_content中try {FileInputStream in = new FileInputStream(grm_file);InputStreamReader input = new InputStreamReader(in);char[] cbuf = new char[(int) grm_file.length()];@SuppressWarnings("unused")int data=0;data = input.read(cbuf);// 构建语法的内容传的是字符串,将char[]转成StringStringBuilder builder = new StringBuilder();for (char c : cbuf) {builder.append(c);}grm_content = builder.toString();// 释放资源in.close();input.close();grm_file = null;// 初始化构建语法参数grm_build_params = "engine_type=local,asr_res_path=" + ASR_RES_PATH + ",sample_rate=" + SAMPLE_RATE_16K+ ",grm_build_path=" + GRM_BUILD_PATH + ",";// 实例化回调函数对象CallbackUtil.GrammarCallBack callback = new CallbackUtil.GrammarCallBack_Realize();// 语法长度为内容的长度grm_cnt_len = grm_content.length();// 传入参数,构建语法ret = VoiceLib.instance.QISRBuildGrammar("bnf", grm_content, grm_cnt_len, grm_build_params, callback,asr_data2.getPointer());} catch (Exception e) {e.printStackTrace();} finally {return ret;}}

QISRBuildGrammar(“bnf”, grm_content, grm_cnt_len, grm_build_params, callback, udata1);

主要是给这个函数配参数,现在还没有测通,有测通的告诉我一声!

【终板ps】已经全部测通!这里得到的语法id必须是call,如果你是一串字符串,说明读的不对!

解释:

第一个是文件类型,不用说固定的

第二个是语法内容,我用了文件缓冲读字符,按行读取字符,注意用的是StringBuilder,因为要拼接,你直接用String卡死了不要找我哈。

第三个是文件长度,length一下就好

第四个是参数,这里初始化直接赋值就好,注意字符串凭借的引号问题

第五个就是回调函数

第六个是那个无定向指针

现在报参数无效,错误码23002,估计是后面两个还不行,需要继续调整,知道的指导一下,我继续调试了!

【终板PS】没有正确的读call.bnf,终板更新已解决

最后是识别,这里坑太多,不会的下面留言

// 进行离线语法识别public static int run_asr(UserData udata) {String asr_params;String rec_rslt = null;String asr_audiof = null;long pcm_count = 0;long pcm_size;@SuppressWarnings("unused")int last_audio = 0;int aud_stat = 1;asr_audiof = get_audio_file();f_pcm = new File(asr_audiof);if (!f_pcm.exists()) {System.out.println("打开语音文件失败!\n");run_error();}pcm_size = f_pcm.length();try {@SuppressWarnings("resource")InputStream in = new FileInputStream(f_pcm);pcm_data = new byte[(int) pcm_size];@SuppressWarnings("unused")int n = 0;n = in.read(pcm_data);} catch (Exception e1) {e1.printStackTrace();}// 离线语法识别参数设置asr_params = "engine_type=local,asr_res_path=" + ASR_RES_PATH + ",sample_rate=" + SAMPLE_RATE_16K+ ",grm_build_path=" + GRM_BUILD_PATH + ",local_grammar=" + udata.grammar_id+ ",result_type=plain,result_encoding=GB2312,";session_id = VoiceLib.instance.QISRSessionBegin(null, asr_params, err);if (null == session_id) {run_error();}System.out.println("开始识别...\n");while (true) {int len = 6400;if (pcm_size < 12800) {len = (int) pcm_size;last_audio = 1;}aud_stat = MSP_AUDIO_SAMPLE_CONTINUE;// 0x02if (0 == pcm_count) {aud_stat = MSP_AUDIO_SAMPLE_FIRS;// 0x01}if (len <= 0) {break;}System.out.print(">");errcode = VoiceLib.instance.QISRAudioWrite(session_id, pcm_data, len, aud_stat, ep_status, rec_status);try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}if (MSP_SUCCESS != errcode) {run_error();break;}pcm_count += (long) len;pcm_size -= (long) len;// 检测到音频结束if (MSP_EP_AFTER_SPEECH == ep_status.getValue()) {break;}}// 主动点击音频结束VoiceLib.instance.QISRAudioWrite(session_id, null, 0, MSP_AUDIO_SAMPLE_LAST, ep_status, rec_status);pcm_data = null;// 获取识别结果while (MSP_REC_STATUS_COMPLETE != rss_status1.getValue() && MSP_SUCCESS == err.getValue()) {rec_rslt = VoiceLib.instance.QISRGetResult(session_id, rss_status1, 0, err);}System.out.println("\n识别结束:\n");System.out.println("=============================================================\n");if (null != rec_rslt) {String str = rec_rslt.substring(rec_rslt.indexOf("input=") + 6);System.out.println("识别结果为:\n" + str);} else {System.out.println("没有识别结果!");System.out.println("=============================================================\n");run_exit();}return MSP_SUCCESS;}

附加几个小方法:

public static void run_error() {if (null != pcm_data) {pcm_data = null;}if (null != f_pcm) {f_pcm = null;}}public static int run_exit() {VoiceLib.instance.QISRSessionEnd(session_id, null);return errcode;}

至此,全部完工!

识别结果如下:

**

代码是plain解析的,截图是xml的,改下参数就好,编码别动,GB2312,不要utf-8

**

觉得不错的就点个赞吧!

--------------------------------12月19日补充-------------Util中的内容

import com.sun.jna.Pointer;public class Util {public static UserData fromPointer(Pointer pointer, int offset) {UserData inst = new UserData();inst.build_fini = pointer.getInt(offset);offset += 4;inst.update_fini = pointer.getInt(offset);offset += 4;inst.errcode = pointer.getInt(offset);offset+=4;inst.grammar_id=pointer.getString(offset);return inst;}}

--------12月20日补充-------------UserData中的内容

package com.xinzhi;import com.sun.jna.Structure;public class UserData extends Structure{public intbuild_fini;//标识语法构建是否完成 public intupdate_fini; //标识更新词典是否完成public interrcode; //记录语法构建或更新词典回调错误码public String grammar_id; //保存语法构建返回的语法ID}*************************************

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥主要识别类¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

package com.xinzhi;import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FileReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.RandomAccessFile;import java.lang.reflect.Array;import java.nio.ByteBuffer;import java.nio.CharBuffer;import java.nio.charset.Charset;import java.sql.Ref;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Scanner;import com.sun.jna.Memory;import com.sun.jna.Pointer;import com.sun.jna.StringArray;import com.sun.jna.ptr.ByteByReference;import com.sun.jna.ptr.IntByReference;import com.sun.jna.ptr.PointerByReference;import com.xinzhi.CallbackUtil.GrammarCallBack;public class xMsc {public static final int SAMPLE_RATE_16K = 16000;public static final int SAMPLE_RATE_8K = 8000;public static final int MAX_GRAMMARID_LEN = 32;public static final int MAX_PARAMS_LEN = 1024;public static final int MSP_SUCCESS = 0;public static final int MSP_FAILED = 1;private static int MSP_AUDIO_SAMPLE_FIRS = 0x01;private static int MSP_AUDIO_SAMPLE_CONTINUE =0x02;private static int MSP_EP_LOOKING_FOR_SPEECH = 0;private static int MSP_REC_STATUS_INCOMPLETE = 2;private static int MSP_EP_AFTER_SPEECH = 3;private static int MSP_AUDIO_SAMPLE_LAST = 4;private static int MSP_REC_STATUS_COMPLETE = 5;public static final String ASR_RES_PATH = "fo|D:\\msc\\common.jet"; // 离线语法识别资源路径public static final String GRM_BUILD_PATH = "D:\\msc\\GrmBuilld_x64"; // 构建离线语法识别网络生成数据保存路径public static final String GRM_FILE = xMsc.class.getClassLoader().getResource("call.bnf").getPath(); // 构建离线识别语法网络所用的语法文件public static final String LEX_NAME = "contact"; // 更新离线识别语法的contact槽(语法文件为此示例中使用的call.bnf)// 选择进行离线语法识别的语音文件public static String get_audio_file() {int key = 0;// while(key != 27) //按Esc则退出// {System.out.println("请选择音频文件:\n");System.out.println("1.打电话给丁伟\n");System.out.println("2.打电话给黄辣椒\n");/*Scanner scan = new Scanner(System.in);key = scan.nextInt();switch (key) {case 1:System.out.println("\n1.打电话给丁伟\n");return "./source/ddhgdw.pcm";case 2:System.out.println("\n2.打电话给黄辣椒\n");return "./source/ddhghlj.pcm";// default:// continue;}*/// }// exit(0);return "source/ddhgdw.pcm";}// 构建离线识别语法网络public static int build_grammar(UserData asr_data2) {File grm_file = null;String grm_content = null;int grm_cnt_len = 0;String grm_build_params = null;int ret = MSP_SUCCESS;grm_file = new File(GRM_FILE);if (!grm_file.exists()) {System.out.println("打开语法文件失败!");return MSP_FAILED;}grm_cnt_len = (int) grm_file.length();// 按照字节读取语法文件,并将字节添加到grm_content中try {FileInputStreamin = new FileInputStream(grm_file);/*BufferedInputStream bis = new BufferedInputStream(in);byte[] buf = new byte[grm_cnt_len];bis.read(buf, 0, grm_cnt_len);*///buf[grm_cnt_len]='\0';/*Charset cs = Charset.forName ("UTF-8");ByteBuffer bb = ByteBuffer.allocate (buf.length); bb.put (buf); bb.flip (); CharBuffer cb = cs.decode (bb);char[] getChars = cb.array();*///BufferedReader buf2 = new BufferedReader(new FileReader(grm_file));InputStreamReader input=new InputStreamReader(in);//StringBuilder builder = new StringBuilder();int data;char[] cbuf=new char[(int) grm_file.length()];data = input.read(cbuf);System.out.println("data="+data);StringBuilder builder=new StringBuilder();for(char c:cbuf) {builder.append(c);}grm_content = builder.toString();in.close();//grm_file = null;// 初始化构建语法参数grm_build_params = "engine_type=local,asr_res_path="+ASR_RES_PATH +",sample_rate="+SAMPLE_RATE_16K+ ",grm_build_path=" +GRM_BUILD_PATH+",";// 实例化回调函数对象CallbackUtil.GrammarCallBack callback=new CallbackUtil.GrammarCallBack_Realize();grm_cnt_len=grm_content.length();System.out.println(grm_cnt_len+"wwwww");System.out.println("grm_content:\n"+grm_content);System.out.println("grm_build_params"+grm_build_params);System.out.println("callback:" + callback);// 传入参数,构建语法System.out.println("识别之前的userData"+asr_data2);ret = VoiceLib.instance.QISRBuildGrammar("bnf",grm_content,grm_cnt_len,grm_build_params,callback,asr_data2.getPointer());//asr_data2.grammar_id="call";//System.out.println("grammar_id="+asr_data2.getClass().getName());// grm_content = null;System.out.println("ret:" + ret);return ret;} catch (Exception e) {e.printStackTrace();return ret;}}// 更新离线识别语法词典public static int update_lexicon(UserData udata) {String lex_content = "丁伟\n黄辣椒";int lex_cnt_len = lex_content.length();String update_lex_params = null;update_lex_params = "engine_type = local, text_encoding = GB2312, asr_res_path =" + ASR_RES_PATH+ ", sample_rate = " + SAMPLE_RATE_16K + ",grm_build_path =" + GRM_BUILD_PATH + ", grammar_list ="+ udata.grammar_id;CallbackUtil.LexiconCallBack callback = new CallbackUtil.LexiconCallBack_Realize();String udata1 = "";System.out.println(LEX_NAME);System.out.println(lex_content);System.out.println(lex_cnt_len);System.out.println(update_lex_params);System.out.println(callback);System.out.println(udata1);return VoiceLib.instance.QISRUpdateLexicon(LEX_NAME.toCharArray(), lex_content.toCharArray(), lex_cnt_len,update_lex_params.toCharArray(), callback, udata1.toCharArray());}static File f_pcm = null;static byte[] pcm_data;static int errcode =-1;static String session_id ="";static byte[] buf ;static IntByReference ep_status1=new IntByReference(0);static IntByReference rec_status1=new IntByReference(2);static IntByReference rss_status1=new IntByReference(1);static Pointer pointer;static String pcm_data_s;// static ByteByReference b;static ByteByReference b=new ByteByReference();static IntByReference i=new IntByReference();static PointerByReference p=new PointerByReference(Pointer.NULL);// 进行离线语法识别public static int run_asr(UserData udata) {String asr_params ;String rec_rslt =null;String asr_audiof = null;long pcm_count = 0;long pcm_size;int last_audio = 0;int aud_stat = 1;asr_audiof = get_audio_file();System.out.println("asr_audiof:" + asr_audiof);f_pcm = new File(asr_audiof);if (!f_pcm.exists()) {System.out.println("打开语音文件失败!\n");run_error();}pcm_size = f_pcm.length();System.out.println("f_pcm_size"+pcm_size);try {InputStream in=new FileInputStream(f_pcm);//ByteArrayOutputStream bos=new ByteArrayOutputStream();pcm_data=new byte[(int) pcm_size];int n=0;//while((n=in.read(pcm_data))!=-1) {//bos.write(pcm_data,0,n);//}//pcm_data=bos.toByteArray();n=in.read(pcm_data);System.out.println("n="+n);System.out.println("pcm_size="+pcm_size);System.out.printf("%x\n",pcm_data[0]);System.out.printf("%x\n",pcm_data[1]);System.out.printf("%x\n",pcm_data[2]);System.out.printf("%x\n",pcm_data[3]);System.out.println("*I*********");System.out.printf("%x\n",pcm_data[(int) (pcm_size-4)]);System.out.printf("%x\n",pcm_data[(int) (pcm_size-3)]);System.out.printf("%x\n",pcm_data[(int) (pcm_size-2)]);System.out.printf("%x\n",pcm_data[(int) (pcm_size-1)]);//InputStreamReader input=new InputStreamReader(in);//StringBuilder builder = new StringBuilder();/*int data;char[] cbuf=new char[(int) pcm_size];data = input.read(cbuf);System.out.println("data="+data);System.out.printf("char%x",(int)cbuf[0]);*//*pointer=new Pointer(135662L);for(int i=0;i<135662;i++) {pointer.setByte(i, pcm_data[i]);}*//*pointer=new Memory(pcm_size);pointer.read(0, pcm_data, 0,(int) pcm_size);System.out.println("SIZE"+pointer.SIZE);*///int offset = 0;//int numRead = 0;/*while (offset < pcm_data.length&& (numRead = in.read(pcm_data, offset, pcm_data.length - offset)) >= 0) {offset += numRead;}*///offset=in.read(pcm_data);} catch (Exception e1) {e1.printStackTrace();}// 离线语法识别参数设置asr_params = "engine_type=local,asr_res_path=" + ASR_RES_PATH + ",sample_rate=" + SAMPLE_RATE_16K+ ",grm_build_path=" + GRM_BUILD_PATH + ",local_grammar=" +udata.grammar_id+ ",result_type=plain,result_encoding=GB2312,";/*asr_params="engine_type = local,asr_res_path = fo|res/asr/common.jet, sample_rate = 16000," + "grm_build_path = res/asr/GrmBuilld_x64, local_grammar = call, result_type =plain, result_encoding =GB2312, ";*/System.out.println("asr_param="+asr_params);IntByReference err=new IntByReference(errcode);//int[] errcode2= {0};session_id= VoiceLib.instance.QISRSessionBegin(null, asr_params, err);System.out.println("session_err="+err.getValue());System.out.println("session_id:"+session_id);System.out.println("session_id_length:"+session_id.length());if (null == session_id) {run_error();}System.out.println("开始识别...\n");while (true) {int len =6400;if (pcm_size < 12800) {len = (int) pcm_size;last_audio = 1;}aud_stat = MSP_AUDIO_SAMPLE_CONTINUE;//0x02if (0 == pcm_count) {aud_stat =MSP_AUDIO_SAMPLE_FIRS;//0x01}if (len <= 0) {break;}System.out.print(">");byte[] every=new byte[len];System.arraycopy(pcm_data, (int) pcm_count, every, 0, len);errcode = VoiceLib.instance.QISRAudioWrite(session_id,every,len, aud_stat,ep_status1,rec_status1);try {Thread.sleep(15);} catch (InterruptedException e) {e.printStackTrace();}/*System.out.print("pcmsize====="+pcm_size);System.out.print(" errcode="+errcode);System.out.print(" aut_stat="+aud_stat);System.out.print(" len="+len);System.out.print(" pcm_count="+pcm_count);System.out.print(" ep_status1="+ep_status1.getValue());System.out.println(" rec_status="+rec_status1.getValue());*/if (MSP_SUCCESS != errcode) {run_error();break;}pcm_count += (long) len;pcm_size -= (long) len;// 检测到音频结束if (MSP_EP_AFTER_SPEECH == ep_status1.getValue()) {break;}try {Thread.sleep(150);} catch (InterruptedException e) {e.printStackTrace();} // 模拟人说话时间间隙}// 主动点击音频结束VoiceLib.instance.QISRAudioWrite(session_id, null, 0, MSP_AUDIO_SAMPLE_LAST, ep_status1,rec_status1);pcm_data = null;//MSP_REC_STATUS_COMPLETE = 5//rss_status = MSP_REC_STATUS_INCOMPLETE;//2//System.out.println("rss_status="+rss_status);// 获取识别结果while (MSP_REC_STATUS_COMPLETE != rss_status1.getValue() && MSP_SUCCESS==err.getValue()) {/*System.out.println("rss_status="+rss_status1.getValue());System.out.println("errValue1="+err.getValue());*/rec_rslt = VoiceLib.instance.QISRGetResult(session_id, rss_status1,0, err);try {Thread.sleep(150);} catch (InterruptedException e) {e.printStackTrace();}//System.out.println("session_id_result="+session_id);//System.out.println("rss_status="+rss_status1.getValue());//System.out.println("errValue="+err.getValue());//System.out.println("rec_rslt="+rec_rslt);}System.out.println("\n识别结束:\n");System.out.println("=============================================================\n");if (null != rec_rslt) {System.out.println("识别结果为:\n" + rec_rslt);} else {System.out.println("没有识别结果!");System.out.println("=============================================================\n");run_exit();}return MSP_SUCCESS;}public static void run_error() {if (null != pcm_data) {pcm_data = null;}if (null != f_pcm) {f_pcm = null;}}public static int run_exit() {VoiceLib.instance.QISRSessionEnd(session_id, null);return errcode;}static UserData asr_data;public static void main(String[] args) {String login_config = "appid=5ba********"; // 登录参数换成你的asr_data = new UserData();asr_data.build_fini=2;//asr_data.grammar_id ="12345678901234567890123456789012";/*Integer zero=new Integer(0);Arrays.fill(asr_data.toArray(asr_data.size()), zero);*/int ret = 0;ret = VoiceLib.instance.MSPLogin(null, null, login_config); // 第一个参数为用户名,第二个参数为密码,传null即可,第三个参数是登录参数if (MSP_SUCCESS != ret) {System.out.println("登录失败!");exit();}System.out.println("登录成功!");System.out.println("构建离线识别语法网络...\n");ret = build_grammar(asr_data); // 第一次使用某语法进行识别,需要先构建语法网络,获取语法ID,之后使用此语法进行识别,无需再次构建System.out.println("RET============================================" + ret);if (MSP_SUCCESS != ret) {System.out.println("构建语法调用失败!\n");exit();}while (MSP_FAILED!= asr_data.build_fini) {try {Thread.sleep(1); } catch(InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace(); }}if (MSP_SUCCESS != asr_data.errcode) {exit();}System.out.println("离线识别语法网络构建完成,开始识别...\n");ret = run_asr(asr_data);if (MSP_SUCCESS != ret) {System.out.println("离线语法识别出错: %d \n");// +retexit();}System.out.println("请按任意键继续\n");/*// _getch();System.out.println("更新离线语法词典...\n");ret = update_lexicon(asr_data); // 当语法词典槽中的词条需要更新时,调用QISRUpdateLexicon接口完成更新if (MSP_SUCCESS != ret) {System.out.println("更新词典调用失败!\n");exit();}while (MSP_FAILED != asr_data.update_fini)try {Thread.sleep(300);} catch (InterruptedException e) {// TODO Auto xinzhi-generated catch blocke.printStackTrace();}if (MSP_SUCCESS != asr_data.errcode)exit();System.out.println("更新离线语法词典完成,开始识别...\n");ret = run_asr(asr_data);if (MSP_SUCCESS != ret) {System.out.println("离线语法识别出错: %d \n");exit();}*/}public static void exit() {VoiceLib.instance.MSPLogout();System.out.println("请按任意键退出...\n");// _getch();}}

配套源码地址:/download/weixin_43112746/10908947

记得更换成自己的资源

帮助有需要的人。觉得有用,记得给我个赞!

如果觉得《手把手的操作——用java调用科大讯飞的离线语音识别dll实现离线识别(JNA实现)(二)》对你有帮助,请点赞、收藏,并留下你的观点哦!

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