概述
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 开始编写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:softwaremingwMinGwMinGwbingcc.exe Parameters: -shared -o ./lib/$FileNameWithoutAllExtensions$.dll ./jni/$FileNameWithoutAllExtensions$.c -I "$JDKPath$include" -I "$JDKPath$includewin32" -I "./jni" ./lib/msc_x64.dll Working directory: $ProjectFileDir$
注意:
关于 jstringToChar 转换函数,在 .c 文件 和 .cpp 文件中内容有区别,十分重要
后续有时间再写Linux中使用部分
欢迎大家留言技术交流
参考资料
http://blog.csdn.net/huachao1001/article/details/53906237
最后
以上就是光亮红牛为你收集整理的JAVA JNI调用科大讯飞离线语音合成WindowsJNI调用科大讯飞离线语音合成(Windows篇)的全部内容,希望文章能够帮你解决JAVA JNI调用科大讯飞离线语音合成WindowsJNI调用科大讯飞离线语音合成(Windows篇)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复