1. 程式人生 > >手把手的操作——用java呼叫科大訊飛的離線語音識別dll實現離線識別(JNA實現)(一)

手把手的操作——用java呼叫科大訊飛的離線語音識別dll實現離線識別(JNA實現)(一)

#用java呼叫科大訊飛的離線語音識別dll實現離線識別(JNA實現)(一)

本人接的任務,做離線語音識別,用的是科大訊飛的離線識別,java不支援離線了,所以下載了windows的離線包,用JNA進行呼叫。之前用的是jni,但是一直沒有測試通過,本人又不會C++,研究了一個星期終究放棄。轉而使用JNA,JNA使用只要匯入一個jar包即可,JNA實際上是對JNI的一種封裝。

【線上語音識別的實現看我的另一篇】科大訊飛 線上語音識別 音訊來源為【檔案】的java接入實現, 適用於初學者

說明

本人一邊做一邊寫,記錄問題和解決辦法,留給自己思考和大家交流。如有不對的地方,歡迎批評指正!
【ps】現在已經做完,參考第二篇

一、註冊使用者,下載dll這個先略過,很簡單,可以參考其他的……【待】
1、先進入訊飛開放平臺,先註冊【地址】https://www.xfyun.cn/
2、建立應用,記得平臺選windows,因為java不支援離線
在這裡插入圖片描述

3、建立完成之後,在 我的應用 中
在這裡插入圖片描述

選擇【離線命令詞識別】
就完成建立了!

4、下載需要的SDK,這個SDK包含了動態庫dll,靜態庫lib,標頭檔案.h,以及非常重要的例子!
在這裡插入圖片描述
【點亮需要的功能,下載相應的SDK】
在這裡插入圖片描述
下載好之後,找出其中的dll檔案,兩個版本,上面是32位系統,下面是64位系統,本人是64位的
在這裡插入圖片描述

二、呼叫JNA
1下載jna的jar包
【JNA包下載地址】:

https://download.csdn.net/download/weixin_43112746/10690193

2匯入java工程中
在這裡插入圖片描述
jar包的位置,可以放在根目錄,也可以像我一樣創立一個lib資料夾來放置
然後
右鍵工程–properties—java Build Path----libraries—add jars
在這裡插入圖片描述
【找到相應的JNA包的位置,新增之後點選Apply and Close】就完成JNA包的匯入
【JNA包下載地址】:https://download.csdn.net/download/weixin_43112746/10690193

沒有做過的,先載入個例子試試!
在這裡插入圖片描述

建立一個class,一個interface,下面的是訊飛的dll檔案放在根目錄下
【介面】這裡只測試登入的函式

package test;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;

public interface VoiceLib extends Library {
	  int MSPLogin(String usr, String pwd, String params);
	  VoiceLib instance = (VoiceLib)Native.loadLibrary("msc_x64", VoiceLib.class);//介面直接對動態庫檔案進行呼叫,
	  //省去JNI的繁瑣步驟
		

}

【類】
package test;

import com.sun.jna.Native;

public class Voice {
		public static void main(String[] args) {
		String usr=null;
		String pwd=null;
		String params="appid=5ba4bc08";//這裡填寫自己的appid,從訊飛的我的應用裡面貼上過來
		int a;
		a=VoiceLib.instance.MSPLogin(usr, pwd, params);//呼叫介面的方法傳引數
		System.out.println(“a=”+a);
		
		
	}
}




輸出結果a=0
很明顯測試成功了!
能夠繼續往下寫了。

又遇到問題,引數的轉換!
普通的倒是還好,轉換關係如下:
在這裡插入圖片描述
來源:https://github.com/java-native-access/jna/blob/master/www/Mappings.md
可是問題來了,訊飛中有指標,控制代碼,回撥函式等等各種亂七八糟的引數,這可怎麼轉換?頭頂一直烏鴉飛過……

三、引數的轉換(難點)
登入做完了,再做構建語法,其中用到的函式是

int MSPAPI QISRBuildGrammar(const char *grammarType, const char *grammarContent, unsigned int grammarLength,
 const char *params, GrammarCallBack callback, void *userData);

除了無符號int那個,其他都沒有!又一隻烏鴉飛過……
竟然還有語法回撥函式!這是什麼!又一隻烏鴉飛過……
查一下回調函式
【百度】這是個連結哈

回撥函式就是一個通過函式指標呼叫的函式。如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標被用來呼叫其所指向的函式時,我們就說這是回撥函式。回撥函式不是由該函式的實現方直接呼叫,而是在特定的事件或條件發生時由另外的一方呼叫的,用於對該事件或條件進行響應。

找個資源帖參考下:
https://blog.csdn.net/l527719041/article/details/77461328

哦!原來可以這麼操作!

先把const char *解決,這是要轉換成String 【待】

再來解決回撥函式的引數問題!
【先做這麼多,下回分解】
第二篇的連結:手把手的操作——用java呼叫科大訊飛的離線語音識別dll實現離線識別(JNA實現)(二)