JAVA JNI调用科大讯飞离线语音合成Windows

JNI调用科大讯飞离线语音合成(Windows篇)

背景:
本文旨在介绍如何使用 JNI调用科大讯飞离线语音合成;如果你注册过科大讯飞开发者平台,你就会发现,科大讯飞并没有提供 java 的库,下载 windows 和 Linux版本都是C调用例子;直接使用 JNI调用咯,网上查阅一遍,基本上都是 JNA 调用科大讯飞的例子;无奈,自己写呗;我使用 IntelliJ IDEA 编译器,使用 eclipse 需要自己百度一下配置。
感谢:
感谢以下这位博友的文章:
链接:http://blog.csdn.net/huachao1001/article/details/53906237

IntelliJ IDEA平台下JNI编程(一)—HelloWorld篇
【huachao1001的专栏:http://blog.csdn.net/huachao1001/article/details/53906237】

  1. 开始编码
    1.1 开始编写Java文件
public class KeDaXunFei {
 static {
  	System.loadLibrary("msc_x64");
  	System.loadLibrary("KeDaXunFei");
  }
 public native void text2Speech(String textContent, String fileName);
 
 public native void text2Speech(String textContent, String fileName, String params);
 
 public static void main(String[] args) {
  	KeDaXunFei keDaXunFei = new KeDaXunFei();
  	String textContent = "君不见,黄河之水天上来,奔流到海不复回“;
    	String params = "engine_type = local, voice_name = xiaoyan, text_encoding = UTF8, tts_res_path = fo|D:\\java\\kedaxunfei\\msc\\res\\tts\\xiaoyan.jet;fo|D:\\java\\kedaxunfei\\msc\\res\\tts\\common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";
  	keDaXunFei.text2Speech(textContent, "abcd.wav");
 	}
}

注意:
①这里的 msc_x64.dll 必须加载,KeDaXunFei是我最后通过 .c 生成的 dll 文件
②在 params 中关于xiaoyan.jet、common.jet资源文件,可以使用绝对路径,也可以使用相对路径;如果相对路径不正确,加载不到语音资源,出现如下错误信息并且合成语音文件文件损坏,无法播放:
QTTSAudioGet failed, error code: 10102.
text_to_speech failed, error code: 10102.
并自动项目中新建一个 msc 文件夹(包含错误日志信息),这个文件夹就是用于放置xiaoyan.jet、common.jet资源文件,将你下载文件中的 /bin/msc/目录下内容,拷贝到 msc 中。

1.2 生成C语音的 KeDaXunFei.h 头文件,参考

IntelliJ IDEA平台下JNI编程(一)—HelloWorld篇
【huachao1001的专栏:http://blog.csdn.net/huachao1001/article/details/53906237】

1.3 编写 .c 文件,主要参考科大讯飞官方示例编写

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#include "KeDaXunFei.h"
#include "qtts.h"
#include "msp_cmn.h"
#include "msp_errors.h"

char* jstringToChar(JNIEnv* env, jstring jstr) {
 char*   rtn = NULL;
 jclass   clsstring = (*env)->FindClass(env, "java/lang/String");
 jstring   strencode = (*env)->NewStringUTF(env, "UTF-8");
 jmethodID   mid = (*env)->GetMethodID(env, clsstring, "getBytes", "(Ljava/lang/String;)[B");
 jbyteArray   barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid, strencode);
 jsize   alen = (*env)->GetArrayLength(env, barr);
 jbyte*   ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
 if (alen > 0)
 {
  rtn = (char*)malloc(alen + 1);         //new   char[alen+1];
  memcpy(rtn, ba, alen);
  rtn[alen] = 0;
 }
 (*env)->ReleaseByteArrayElements(env, barr, ba, 0);
 return rtn;
}

typedef struct _wave_pcm_hdr {
与科大讯飞中例子相同,这里就不再赘述
} wave_pcm_hdr;

/* 默认wav音频头部数据 */
wave_pcm_hdr default_wav_hdr =
{
 与科大讯飞中例子相同,这里就不再赘述
};
/* 文本合成 */
int text_to_speech(const char* src_text, const char* des_path, const char* params)
{
 与科大讯飞中例子相同,这里就不再赘述
}

/*
Java_KeDaXunFei_text2Speech__Ljava_lang_String_2Ljava_lang_String_2 与 KeDaXunFei.h 头文件中生成对于java中方法名相同 */
JNIEXPORT void JNICALL Java_KeDaXunFei_text2Speech__Ljava_lang_String_2Ljava_lang_String_2
  (JNIEnv *env, jobject job, jstring textContent, jstring jfileName) {
    	char* src_text = jstringToChar(env, textContent);
    	char* fileName = jstringToChar(env, jfileName);
    	const char* params = "engine_type = local, voice_name = xiaoyan, text_encoding = UTF8, tts_res_path = fo|res\\tts\\xiaoyan.jet;fo|res\\tts\\common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";
    	int         ret                  = MSP_SUCCESS;
      	const char* login_params         = "***(填写你自己申请的)";//登录参数,appid与msc库绑定,请勿随意改动
      	ret = MSPLogin(NULL, NULL, login_params);// 登录验证
	    if (MSP_SUCCESS != ret)
	   {
		  printf("MSPLogin failed, error code: %d.\n", ret);
		  goto exit ;
	    }
    	/* 文本合成 */	
	printf("开始合成 ...\n");
       	ret = text_to_speech(src_text, fileName, params);
       	if (MSP_SUCCESS != ret)
	{
        	printf("text_to_speech failed, error code: %d.\n", ret);
       	}
       printf("合成完毕\n");
     exit:
       MSPLogout(); //退出登录
   	return ;
}

注意:如果大家在通过 *.o文件转成 *.dll文件时发生错误,可以尝试在idea中配置如下命令:
在idea中配置External Tools Program: D:\software\mingw\MinGw\MinGw\bin\gcc.exe Parameters: -shared -o ./lib/$FileNameWithoutAllExtensions$.dll ./jni/$FileNameWithoutAllExtensions$.c -I "$JDKPath$\include" -I "$JDKPath$\include\win32" -I "./jni" ./lib/msc_x64.dll Working directory: $ProjectFileDir$

注意:
关于 jstringToChar 转换函数,在 .c 文件 和 .cpp 文件中内容有区别,十分重要

后续有时间再写Linux中使用部分

欢迎大家留言技术交流

参考资料

http://blog.csdn.net/huachao1001/article/details/53906237

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值