接口调用-【2】讯飞离线唤醒Windows/Linux

1、写调用主函数

package com.iflytek;
import com.iflytek.util.Step3_ivw_thread;
import com.iflytek.util.Step4_audioFormat;
import java.util.Scanner;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;

/**
 * 请注意!!!
 * 1.首选到控制台https://console.xfyun.cn/services/awaken下载唤醒的Windows MSC。
 * 2.下载的唤醒Windows MSC解压后,把bin目录下msc文件夹与dll文件拷贝到res目录下。
 * 3.最后请替换Step3_ivw_thread中的appid值,appid值在下载页面控制台可以看到。
 */

public class OfflineIvwMain {
	//录音相关参数
	public static AudioFormat audioFormat;
	public static TargetDataLine targetDataLine;
	public static void main(String[] args) throws Exception {
		System.out.println("y开始体验唤醒,n结束唤醒");
		Scanner input = new Scanner(System.in);
		String inputContent = input.next();
		long startTime = System.currentTimeMillis();
		if(inputContent.equals("y")){
			audioFormat = Step4_audioFormat.getAudioFormat(audioFormat);//构造具有线性 PCM 编码和给定参数的 AudioFormat。
			DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
			targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
			Step3_ivw_thread myThread=new Step3_ivw_thread();
			myThread.start();
			Scanner input_2 = new Scanner(System.in);
			String inputContent_2 = input_2.next();
			if(inputContent_2.equals("n")){
				targetDataLine.stop();
				targetDataLine.close();
			}
			System.out.println("唤醒操作持续:"+(System.currentTimeMillis()-startTime)/1000+"秒!");
			System.exit(0);
		}
	}
}

2、 根据文档用JAVA重写方法

package com.iflytek.service;
import com.iflytek.util.Step2_ivw_ntf_handler;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;

public interface Step1_ivw_dll extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  Pointer或byte[]
     * 4.int      对应  int
     * 5.无参     对应  无参
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback
     */
    //加载dll动态库并实例化,从而使用其内部的方法
    Step1_ivw_dll INSTANCE = (Step1_ivw_dll) Native.loadLibrary
                             ("res/msc_x64.dll", Step1_ivw_dll.class);

    //定义登录方法    MSPLogin(const char *usr, const char *pwd, const char *params)
    public int MSPLogin(String usr, String pwd, String params);

    //定义开始方法    QIVWSessionbegin(const char *grammarList, const char *params, int *errorCode)
    public String QIVWSessionBegin(String grammarList, String params, IntByReference errorCode);

    //定义写音频方法  QIVWAudioWrite(const char *sessionID, const void *audioData, unsigned int audioLen, int audioStatus)
    public int QIVWAudioWrite(String sessionID, byte[] audioData, int audioLen, int audioStatus);

    //定义结束方法    QIVWSessionEnd(const char *sessionID, const char *hints)
    public int QIVWSessionEnd(String sessionID, String hints);

    //定义获取结果方法 QIVWRegisterNotify(const char *sessionID, ivw_ntf_handler msgProcCb, void *userData)
    public int QIVWRegisterNotify(String sessionID, Step2_ivw_ntf_handler msgProcCb, byte[] userData);

    //定义退出方法     MSPLogout()
    public int MSPLogout();
}

 3、根据文档写回调函数

package com.iflytek.util;
import com.sun.jna.Callback;

public class Step2_ivw_ntf_handler implements Callback {
    //根据文档写回调方法
    public int cb_ivw_msg_proc(String sessionID, int msg, int param1, int param2,
                               String info, String userData) {
        System.out.println("..............................................");
        System.out.println("回调函数返回的唤醒结果:"+info);
        return 0;
    }
}

 4、把调用步骤依次写到线程类

package com.iflytek.util;
import com.iflytek.OfflineIvwMain;
import com.iflytek.service.Step1_ivw_dll;
import com.sun.jna.ptr.IntByReference;
import javax.sound.sampled.AudioInputStream;

public class Step3_ivw_thread extends Thread{
	public void run() {
			//登录参数
			String lgi_param = "appid = 替换你的appid, work_dir = ./res";
			String ssb_param = "ivw_threshold=0:1450,sst=wakeup,ivw_shot_word=1,ivw_res_path =fo|res/ivw/wakeupresource.jet";
			int ret = Step1_ivw_dll.INSTANCE.MSPLogin(null, null, lgi_param);
			if (ret != 0) {//登录成功标志ret为0
				System.out.println("登录失败...请检查");
				System.exit(1);
			} else {
				System.out.println("请注意,唤醒语音需要根据控制台定义的唤醒词来进行唤醒...");
			}

			//开启会话
			IntByReference intByReference = new IntByReference(-100);
			String sessionId = Step1_ivw_dll.INSTANCE.QIVWSessionBegin(null, ssb_param, intByReference);
			if (intByReference.getValue() == 0) {//只有返回0为函数调用成功
				System.out.println("本次会话开启成功...,会话id为:" + sessionId);
			}

			int frameSize = 6400; //一帧的大小为6400B,其他的可能导致无法长时间唤醒
			int audioStatus = 1;//用来告知MSC音频发送是否完成

			//注册回调
			Step2_ivw_ntf_handler msgProcCb = new Step2_ivw_ntf_handler();//回调函数实例
			ret = Step1_ivw_dll.INSTANCE.QIVWRegisterNotify(sessionId, msgProcCb, null);
			if (ret == 0) {//返回为0则代表成功
				System.out.println("注册回调函数成功...");
			} else {
				System.out.println("注册函数返回的错误码" + ret);
			}

			//反复调用QIVWAudioWrite写音频方法,直到音频写完为止
			//long startTime=System.currentTimeMillis();
			try {
				while (true) {
					byte[] audioDataByteArray = new byte[frameSize];
					OfflineIvwMain.targetDataLine.open(OfflineIvwMain.audioFormat);
					OfflineIvwMain.targetDataLine.start();
					int len = new AudioInputStream(OfflineIvwMain.targetDataLine).read(audioDataByteArray);
					//long endTime=System.currentTimeMillis();
					if (len == -1) {//调用麦克风时候,这段将不会被执行...
						//||(endTime-startTime>60*1000)
						audioStatus = 4;//最后帧
						ret = Step1_ivw_dll.INSTANCE.QIVWAudioWrite(sessionId, "".getBytes(), 0, audioStatus);
						System.out.println("最后一帧返回的错误码:" + ret + ",即将执行退出...");
						break;  //文件读完,跳出循环
					} else {
						//反复调用
						ret = Step1_ivw_dll.INSTANCE.QIVWAudioWrite(sessionId, audioDataByteArray, len, audioStatus);
					}
					audioStatus = 2;//中间帧
					if (ret != 0) {
						System.err.println("出错了:" + ret);
					}
					Thread.sleep(200); //模拟人说话时间间隙
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			//终止会话
			ret = Step1_ivw_dll.INSTANCE.QIVWSessionEnd(sessionId, "正常终止");
			if (ret == 0) {
				System.out.println("本次会话正常终止...");
			}

			//执行退出
			ret = Step1_ivw_dll.INSTANCE.MSPLogout();
			if (ret == 0) {
				System.out.println("正常退出...");
			}else{
				System.out.println("异常退出...");
			}
		}
}

5、 录音生成16K、16BIT单声道的音频流

package com.iflytek.util;
import javax.sound.sampled.AudioFormat;

public class Step4_audioFormat {
    //构造线程参数
    //16k采样率的16bit音频,一帧的大小为640B, 时长20ms
    /**
     sampleRate - 每秒样品数
     sampleSizeInBits - 每个样本中的位数
     channels - 通道数(1为mono,2为立体声等)
     signed - 表示数据是签名还是无符号
     bigEndian - 指示单个样本的数据是否以大字节顺序存储( false表示小端)
     */
    public static AudioFormat getAudioFormat(AudioFormat audioFormat) {
        audioFormat=new AudioFormat(16000F, 16, 1,true,false);
        // true,false 指示是以 big-endian 顺序还是以 little-endian 顺序存储音频数据。
        return audioFormat;//构造具有线性 PCM 编码和给定参数的 AudioFormat。
    }
}



6、放置讯飞开放平台下载Linux/Windows中所带的资源

7、 Linux代码基本类似,注意加载SO库就行和放置资源

package com.iflytek.service;
import com.iflytek.OfflineIvwMain;
import com.iflytek.util.Step2_ivw_ntf_handler;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

public interface Step1_ivw_so extends Library {
    /**
     * 重点:
     * 1.char *   对应  String
     * 2.int *    对应  IntByReference
     * 3.void *   对应  Pointer
     * 4.int      对应  int
     * 5.无参     对应  无参
     * 6.回调函数  对应  根据文档自定义回调函数,实现接口Callback
     * 7.Linux设置程序共享库位置,否则会话时会报错25000
     *   export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/SoIvw/res
     *   注意:每个版本都有两个so库,libmsc.so、libw_ivw.so
     */
    //加载so动态库并实例化,从而使用其内部的方法
    Step1_ivw_so INSTANCE = (Step1_ivw_so) Native.loadLibrary
            (OfflineIvwMain.userPath+"res/libmsc.so", Step1_ivw_so.class);

    //定义登录方法    MSPLogin(const char *usr, const char *pwd, const char *params)
    public int MSPLogin(String usr, String pwd, String params);

    //定义开始方法    QIVWSessionbegin(const char *grammarList, const char *params, int *errorCode)
    public String QIVWSessionBegin(String grammarList, String params, IntByReference errorCode);

    //定义写音频方法  QIVWAudioWrite(const char *sessionID, const void *audioData, unsigned int audioLen, int audioStatus)
    public int QIVWAudioWrite(String sessionID, byte[] audioData, int audioLen, int audioStatus);

    //定义获取结果方法 QIVWRegisterNotify(const char *sessionID, ivw_ntf_handler msgProcCb, void *userData)
    public int QIVWRegisterNotify(String sessionID, Step2_ivw_ntf_handler msgProcCb, Pointer userData);

    //定义结束方法    QIVWSessionEnd(const char *sessionID, const char *hints)
    public int QIVWSessionEnd(String sessionID, String hints);

    //定义退出方法     MSPLogout()
    public int MSPLogout();
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值