当前位置:   article > 正文

接口调用-【2】讯飞离线唤醒Windows/Linux_window讯飞离线语音唤醒怎么实现

window讯飞离线语音唤醒怎么实现

1、写调用主函数

  1. package com.iflytek;
  2. import com.iflytek.util.Step3_ivw_thread;
  3. import com.iflytek.util.Step4_audioFormat;
  4. import java.util.Scanner;
  5. import javax.sound.sampled.AudioFormat;
  6. import javax.sound.sampled.AudioSystem;
  7. import javax.sound.sampled.DataLine;
  8. import javax.sound.sampled.TargetDataLine;
  9. /**
  10. * 请注意!!!
  11. * 1.首选到控制台https://console.xfyun.cn/services/awaken下载唤醒的Windows MSC。
  12. * 2.下载的唤醒Windows MSC解压后,把bin目录下msc文件夹与dll文件拷贝到res目录下。
  13. * 3.最后请替换Step3_ivw_thread中的appid值,appid值在下载页面控制台可以看到。
  14. */
  15. public class OfflineIvwMain {
  16. //录音相关参数
  17. public static AudioFormat audioFormat;
  18. public static TargetDataLine targetDataLine;
  19. public static void main(String[] args) throws Exception {
  20. System.out.println("y开始体验唤醒,n结束唤醒");
  21. Scanner input = new Scanner(System.in);
  22. String inputContent = input.next();
  23. long startTime = System.currentTimeMillis();
  24. if(inputContent.equals("y")){
  25. audioFormat = Step4_audioFormat.getAudioFormat(audioFormat);//构造具有线性 PCM 编码和给定参数的 AudioFormat。
  26. DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
  27. targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
  28. Step3_ivw_thread myThread=new Step3_ivw_thread();
  29. myThread.start();
  30. Scanner input_2 = new Scanner(System.in);
  31. String inputContent_2 = input_2.next();
  32. if(inputContent_2.equals("n")){
  33. targetDataLine.stop();
  34. targetDataLine.close();
  35. }
  36. System.out.println("唤醒操作持续:"+(System.currentTimeMillis()-startTime)/1000+"秒!");
  37. System.exit(0);
  38. }
  39. }
  40. }

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

  1. package com.iflytek.service;
  2. import com.iflytek.util.Step2_ivw_ntf_handler;
  3. import com.sun.jna.Library;
  4. import com.sun.jna.Native;
  5. import com.sun.jna.ptr.IntByReference;
  6. public interface Step1_ivw_dll extends Library {
  7. /**
  8. * 重点:
  9. * 1.char * 对应 String
  10. * 2.int * 对应 IntByReference
  11. * 3.void * 对应 Pointer或byte[]
  12. * 4.int 对应 int
  13. * 5.无参 对应 无参
  14. * 6.回调函数 对应 根据文档自定义回调函数,实现接口Callback
  15. */
  16. //加载dll动态库并实例化,从而使用其内部的方法
  17. Step1_ivw_dll INSTANCE = (Step1_ivw_dll) Native.loadLibrary
  18. ("res/msc_x64.dll", Step1_ivw_dll.class);
  19. //定义登录方法 MSPLogin(const char *usr, const char *pwd, const char *params)
  20. public int MSPLogin(String usr, String pwd, String params);
  21. //定义开始方法 QIVWSessionbegin(const char *grammarList, const char *params, int *errorCode)
  22. public String QIVWSessionBegin(String grammarList, String params, IntByReference errorCode);
  23. //定义写音频方法 QIVWAudioWrite(const char *sessionID, const void *audioData, unsigned int audioLen, int audioStatus)
  24. public int QIVWAudioWrite(String sessionID, byte[] audioData, int audioLen, int audioStatus);
  25. //定义结束方法 QIVWSessionEnd(const char *sessionID, const char *hints)
  26. public int QIVWSessionEnd(String sessionID, String hints);
  27. //定义获取结果方法 QIVWRegisterNotify(const char *sessionID, ivw_ntf_handler msgProcCb, void *userData)
  28. public int QIVWRegisterNotify(String sessionID, Step2_ivw_ntf_handler msgProcCb, byte[] userData);
  29. //定义退出方法 MSPLogout()
  30. public int MSPLogout();
  31. }

 3、根据文档写回调函数

  1. package com.iflytek.util;
  2. import com.sun.jna.Callback;
  3. public class Step2_ivw_ntf_handler implements Callback {
  4. //根据文档写回调方法
  5. public int cb_ivw_msg_proc(String sessionID, int msg, int param1, int param2,
  6. String info, String userData) {
  7. System.out.println("..............................................");
  8. System.out.println("回调函数返回的唤醒结果:"+info);
  9. return 0;
  10. }
  11. }

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

  1. package com.iflytek.util;
  2. import com.iflytek.OfflineIvwMain;
  3. import com.iflytek.service.Step1_ivw_dll;
  4. import com.sun.jna.ptr.IntByReference;
  5. import javax.sound.sampled.AudioInputStream;
  6. public class Step3_ivw_thread extends Thread{
  7. public void run() {
  8. //登录参数
  9. String lgi_param = "appid = 替换你的appid, work_dir = ./res";
  10. String ssb_param = "ivw_threshold=0:1450,sst=wakeup,ivw_shot_word=1,ivw_res_path =fo|res/ivw/wakeupresource.jet";
  11. int ret = Step1_ivw_dll.INSTANCE.MSPLogin(null, null, lgi_param);
  12. if (ret != 0) {//登录成功标志ret为0
  13. System.out.println("登录失败...请检查");
  14. System.exit(1);
  15. } else {
  16. System.out.println("请注意,唤醒语音需要根据控制台定义的唤醒词来进行唤醒...");
  17. }
  18. //开启会话
  19. IntByReference intByReference = new IntByReference(-100);
  20. String sessionId = Step1_ivw_dll.INSTANCE.QIVWSessionBegin(null, ssb_param, intByReference);
  21. if (intByReference.getValue() == 0) {//只有返回0为函数调用成功
  22. System.out.println("本次会话开启成功...,会话id为:" + sessionId);
  23. }
  24. int frameSize = 6400; //一帧的大小为6400B,其他的可能导致无法长时间唤醒
  25. int audioStatus = 1;//用来告知MSC音频发送是否完成
  26. //注册回调
  27. Step2_ivw_ntf_handler msgProcCb = new Step2_ivw_ntf_handler();//回调函数实例
  28. ret = Step1_ivw_dll.INSTANCE.QIVWRegisterNotify(sessionId, msgProcCb, null);
  29. if (ret == 0) {//返回为0则代表成功
  30. System.out.println("注册回调函数成功...");
  31. } else {
  32. System.out.println("注册函数返回的错误码" + ret);
  33. }
  34. //反复调用QIVWAudioWrite写音频方法,直到音频写完为止
  35. //long startTime=System.currentTimeMillis();
  36. try {
  37. while (true) {
  38. byte[] audioDataByteArray = new byte[frameSize];
  39. OfflineIvwMain.targetDataLine.open(OfflineIvwMain.audioFormat);
  40. OfflineIvwMain.targetDataLine.start();
  41. int len = new AudioInputStream(OfflineIvwMain.targetDataLine).read(audioDataByteArray);
  42. //long endTime=System.currentTimeMillis();
  43. if (len == -1) {//调用麦克风时候,这段将不会被执行...
  44. //||(endTime-startTime>60*1000)
  45. audioStatus = 4;//最后帧
  46. ret = Step1_ivw_dll.INSTANCE.QIVWAudioWrite(sessionId, "".getBytes(), 0, audioStatus);
  47. System.out.println("最后一帧返回的错误码:" + ret + ",即将执行退出...");
  48. break; //文件读完,跳出循环
  49. } else {
  50. //反复调用
  51. ret = Step1_ivw_dll.INSTANCE.QIVWAudioWrite(sessionId, audioDataByteArray, len, audioStatus);
  52. }
  53. audioStatus = 2;//中间帧
  54. if (ret != 0) {
  55. System.err.println("出错了:" + ret);
  56. }
  57. Thread.sleep(200); //模拟人说话时间间隙
  58. }
  59. } catch (Exception e) {
  60. e.printStackTrace();
  61. }
  62. //终止会话
  63. ret = Step1_ivw_dll.INSTANCE.QIVWSessionEnd(sessionId, "正常终止");
  64. if (ret == 0) {
  65. System.out.println("本次会话正常终止...");
  66. }
  67. //执行退出
  68. ret = Step1_ivw_dll.INSTANCE.MSPLogout();
  69. if (ret == 0) {
  70. System.out.println("正常退出...");
  71. }else{
  72. System.out.println("异常退出...");
  73. }
  74. }
  75. }

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

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

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

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

  1. package com.iflytek.service;
  2. import com.iflytek.OfflineIvwMain;
  3. import com.iflytek.util.Step2_ivw_ntf_handler;
  4. import com.sun.jna.Library;
  5. import com.sun.jna.Native;
  6. import com.sun.jna.Pointer;
  7. import com.sun.jna.ptr.IntByReference;
  8. public interface Step1_ivw_so extends Library {
  9. /**
  10. * 重点:
  11. * 1.char * 对应 String
  12. * 2.int * 对应 IntByReference
  13. * 3.void * 对应 Pointer
  14. * 4.int 对应 int
  15. * 5.无参 对应 无参
  16. * 6.回调函数 对应 根据文档自定义回调函数,实现接口Callback
  17. * 7.Linux设置程序共享库位置,否则会话时会报错25000
  18. * export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/SoIvw/res
  19. * 注意:每个版本都有两个so库,libmsc.so、libw_ivw.so
  20. */
  21. //加载so动态库并实例化,从而使用其内部的方法
  22. Step1_ivw_so INSTANCE = (Step1_ivw_so) Native.loadLibrary
  23. (OfflineIvwMain.userPath+"res/libmsc.so", Step1_ivw_so.class);
  24. //定义登录方法 MSPLogin(const char *usr, const char *pwd, const char *params)
  25. public int MSPLogin(String usr, String pwd, String params);
  26. //定义开始方法 QIVWSessionbegin(const char *grammarList, const char *params, int *errorCode)
  27. public String QIVWSessionBegin(String grammarList, String params, IntByReference errorCode);
  28. //定义写音频方法 QIVWAudioWrite(const char *sessionID, const void *audioData, unsigned int audioLen, int audioStatus)
  29. public int QIVWAudioWrite(String sessionID, byte[] audioData, int audioLen, int audioStatus);
  30. //定义获取结果方法 QIVWRegisterNotify(const char *sessionID, ivw_ntf_handler msgProcCb, void *userData)
  31. public int QIVWRegisterNotify(String sessionID, Step2_ivw_ntf_handler msgProcCb, Pointer userData);
  32. //定义结束方法 QIVWSessionEnd(const char *sessionID, const char *hints)
  33. public int QIVWSessionEnd(String sessionID, String hints);
  34. //定义退出方法 MSPLogout()
  35. public int MSPLogout();
  36. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/225396
推荐阅读
相关标签
  

闽ICP备14008679号