Hand-to-Hand Operation --- Offline Recognition (JNA Implementation) by calling Kodaxinfei's Offline Speech Recognition dll with java (2)

Keywords: network Java C

Address of last article Hand-to-Hand Operation --- Offline Recognition (JNA Implementation) by calling Kodaxinfei's Offline Speech Recognition dll with java (1)

The last one dealt with the hardest part, the conversion of parameters, which is written here separately
**

3. Conversion of parameters (difficult points)

**
Note: This article uses the C language example provided by Xinfei as a template rewrite, the voice comes from the file
1. Analyse the examples provided first
I am using VS2010
Download link: https://pan.baidu.com/s/1CZX3k6nhsbLkuzB3mocyww Extraction code: 6r5g
2.45G size, needs to be installed for some time, because this version is enough for JNA only
[In order to give me the same elementary level that I don't know about C/C++, Dashenqiao]

After running
[File] ([Open]) - [Project/Solution] ([asr_offline_sample.vcxproj]) - Find your own file location ([asr_offline_sample.vcxproj]

Open the header file the same way
[File] [Open] [File] [Find File Location yourself] [Header File End.h]

The main example is asr_sample.c.
The main thing in java is to overwrite this file, so read it first
I've been watching for a long time myself. Let's talk about the structure:
The first few are functions of each function, and the last one is the main function, which is very similar to the structure of java.
Key features
[Login]
[Establish Grammar]
[Build a dictionary]
[Speech Recognition]
[Exit]

Looks like it's easy, so here's one implemented in java
I first set up a lib interface, which contains the calls
(Load dynamic libraries first)

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

#1 Login
This function has already been exemplified in (1). Just rewrite it here

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

New Main Class xMsc
Override login function

	public static void main(String[] args) {
		String login_config = "appid=5ba4bc08"; //Logon parameters
		UserData asr_data=null ;
		int ret             = 0;
		ret = VoiceLib.instance.MSPLogin(null, null, login_config); 
		//The first parameter is the user name, the second parameter is the password, pass null, and the third parameter is the login parameter
		if (MSP_SUCCESS!= ret) {
			System.out.println("Login failed!");
			exit();
		}
		}

First override a few constants:

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;
	private 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= 0x04;
	private static int		 MSP_REC_STATUS_COMPLETE				= 5;

	public static final String ASR_RES_PATH    = "./source/common.jet";    //Offline Syntax Recognition Resource Path
	public static final String GRM_BUILD_PATH  = "./GrmBuilld_x64";       //Build Offline Syntax Identify Network Generate Data Save Path
	public static final String GRM_FILE        = "./source/call.bnf";    //Grammar files used to build offline recognition grammar networks
	public static final String LEX_NAME        = "contact"; 			//Update the contact slot for the offline recognition grammar (the grammar file is the call.bnf used in this example)
	

	public static class UserData {
		public static	boolean     build_fini;     //Identity grammar construction complete
		public static 	boolean     update_fini;   //Identify if updating dictionary is complete
		public static  	int    	    errcode; 	  //Record grammar build or update dictionary callback error codes
		public static 	String      grammar_id;  //Save the grammar ID returned by grammar building		
	};

The modifiers inside need to be studied again.
There are several files to copy, grammar files and so on. I set up a source folder and put it in it
Present structure

[Rewrite all of the main in one breath first!]

public static void main(String[] args) {
		String login_config = "appid=5ba4bc08"; //Logon parameters
		UserData asr_data=null ;
		int ret             = 0;
		ret = VoiceLib.instance.MSPLogin(null, null, login_config); //The first parameter is the user name, the second parameter is the password, pass null, and the third parameter is the login parameter
		if (MSP_SUCCESS!= ret) {
			System.out.println("Login failed!");
			exit();
		}
		System.out.println("Login successful!");
		/*memset(&asr_data, 0, sizeof(UserData));*/
		System.out.println("Building offline recognition grammar network...\n"); 
		ret = build_grammar(asr_data);  //The first time you use a grammar for recognition, you need to build a grammar network, get the grammar ID, and then use this grammar for recognition without rebuilding it
		if (MSP_SUCCESS != ret) {
			System.out.println("Build grammar call failed!\n");
			exit();
		}
		while (false != asr_data.build_fini)
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		if (MSP_SUCCESS != asr_data.errcode)
			exit();
		System.out.println("Offline recognition grammar network built, start recognition...\n");	
		ret = run_asr(asr_data);
		if (MSP_SUCCESS!= ret) {
			System.out.println("Offline grammar recognition error: %d \n");//+ret
			exit();
		}

		System.out.println("Press any key to continue\n");
		//_getch();
		System.out.println("Update offline Grammar Dictionary...\n");
		ret = update_lexicon(asr_data);  //When the entries in the grammar dictionary slot need to be updated, call the QISRUpdateLexicon interface to complete the update
		if (MSP_SUCCESS!= ret) {
			System.out.println("Update dictionary call failed!\n");
			exit();
		}
		while (false != asr_data.update_fini)
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		if (MSP_SUCCESS != asr_data.errcode)
			exit();
		System.out.println("Update offline Grammar Dictionary complete, start recognition...\n");
		ret = run_asr(asr_data);
		if (MSP_SUCCESS!= ret) {
			System.out.println("Offline grammar recognition error: %d \n");
			exit();
		}

}

[Note] Some functions have not been written yet and need to be modified. The final version will be put in a unified resource. It is only the first draft.

Quit with packaged first

public static void exit(){
		VoiceLib.instance.MSPLogout();
		System.out.println("Press any key to exit...\n");
	//	_getch();
		
	}

[Take a breath again] Encapsulate all the functions you want to use in VoiceLib and call them directly later

package com.xinzhi;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.xinzhi.Util.GrammarCallBack;
import com.xinzhi.Util.LexiconCallBack;


public interface VoiceLib extends Library{
	VoiceLib instance = (VoiceLib)Native.loadLibrary("msc_x64", VoiceLib.class);
	
	int MSPLogin(String usr, String pwd, String params);
	
    int QISRBuildGrammar (String grammarType, String grammarContent,  int grammarLength, String params, GrammarCallBack callback, Pointer userData);
    
    int QISRUpdateLexicon(String lexiconName, String lexiconContent,  int lexiconLength, String params, LexiconCallBack callback, Pointer userData);
    
    String QISRSessionBegin(String grammarList, String params, IntByReference errorCode);
    
    int QISRAudioWrite(String sessionID, Object waveData, int waveLen, int audioStatus, IntByReference ep_status1, IntByReference rec_status1);
    
	String QISRGetResult(String sessionID, int rsltStatus, int waitTime, int errorCode);
	
	boolean  QISRSessionEnd(String sessionID, String hints);
	
	boolean  MSPLogout();
}

[I've changed all the parameters here, so I'll explain them later on]

Then write grammatical

//Important Split Line*****************************************//
In the example provided by Xuenfei, there is a callback function and a construction grammar function, which should be rewritten. What should I do?
Callback function I encapsulated in a Util (later dictionary callbacks together)

package com.xinzhi;


import com.sun.jna.Pointer;

import com.sun.jna.win32.StdCallLibrary.StdCallCallback;


public class Util {

	//Interface for grammar callback functions
	 public interface GrammarCallBack extends StdCallCallback{
	    	int build_grm_cb(int ecode, String info, Pointer udata);
	    }
	 //Implementation of Grammar Callback Function
	 public static class GrammarCallBack_Realize implements GrammarCallBack{

		@Override
		public int build_grm_cb(int ecode, String info, Pointer udata) {
			Pointer grm_data =  udata;
			if (null != grm_data) {
				com.xinzhi.xMsc.UserData.build_fini = false;
				com.xinzhi.xMsc.UserData.errcode = ecode;
			} 
			if (com.xinzhi.xMsc.MSP_SUCCESS == ecode && null != info) {
				System.out.println("Build grammar successfully!grammar ID:"+ info);
				if (null != grm_data)
					//_snprintf(grm_data->grammar_id, MAX_GRAMMARID_LEN - 1, info);
					com.xinzhi.xMsc.UserData.grammar_id=info;
			}
			else {
				System.out.println("Failed to build grammar!%d"+ ecode);
			}
			
			return 0;
		}
		 
	 }
	 
	 //Interface for Dictionary Callback Function
	 public interface LexiconCallBack extends StdCallCallback{
		int update_lex_cb(int ecode, String info, Pointer udata);
	 }
	 //Implementation of Dictionary Callback Function
	 public static class LexiconCallBack_Realize implements LexiconCallBack{

		@Override
		public int update_lex_cb(int ecode, String info, Pointer udata) {
			Pointer lex_data = udata;

			if (null != lex_data) {
				com.xinzhi.xMsc.UserData.update_fini = false;
				com.xinzhi.xMsc.UserData.errcode = ecode;
			}

			if (com.xinzhi.xMsc.MSP_SUCCESS == ecode)
				System.out.println("Dictionary update successful!\n");
			else
				System.out.println("Failed to update dictionary!%d\n"+ ecode);

			
			return 0;
		}
		 
	 }

}

There are still errors in it. Go back and correct them!

Where void, I use Pointer to simulate*

Write grammatical again

//Building offline recognition grammar network
	public static int build_grammar(UserData udata){
		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("Failed to open grammar file!");
			return MSP_FAILED; 
		}

		grm_cnt_len = (int) grm_file.length();
		//Read grammar files by character and add characters to grm_content
		FileInputStream in;
		try {
			in = new FileInputStream(grm_file);
			BufferedReader buf=new BufferedReader(new InputStreamReader(new FileInputStream(grm_file)));
			StringBuilder builder=new StringBuilder();
			String data;
			while((data=buf.readLine())!=null) {	
				builder.append(data+"\n");
			}
			grm_content=builder.toString();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		//Initialize build syntax parameters 
		grm_build_params="engine_type = local,asr_res_path = "+ASR_RES_PATH+
				", sample_rate = "+SAMPLE_RATE_16K+", grm_build_path = "+GRM_BUILD_PATH;
		//Instantiate callback function object
		Util.GrammarCallBack callback=new Util.GrammarCallBack_Realize();
		//Create an untyped null pointer
		Pointer udata1=Pointer.NULL;

		//Pass in parameters, build syntax
		ret =VoiceLib.instance.QISRBuildGrammar("bnf", grm_content, grm_cnt_len, grm_build_params, callback, udata1);
		grm_content = null;
		return ret;
	}

QISRBuildGrammar("bnf", grm_content, grm_cnt_len, grm_build_params, callback, udata1);
The main thing is to assign parameters to this function, which is not yet measurable. Let me know if there is a measurable one!
Explanation:
The first is the file type, not to mention fixed
The second is the grammar content, I used file buffer to read characters, read characters by line, pay attention to the StringBuilder, because to stitch, you use the String card directly to die, don't look for me.
The third is the file length, length is fine
The fourth is the parameter, where initialization of direct assignment is good, note the quotation problem with string credentials
The fifth is the callback function
The sixth is the undirected pointer
Now the report parameter is invalid, error code 23002, it is estimated that the latter two are still not possible, need to continue adjusting, know the guidance, I continue to debug!

Posted by deniscyriac on Sat, 11 May 2019 01:33:10 -0700