概述
package com.day.iFlyInterface.commonUtil.dll.tts;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Base64;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
public class OfflineWindowsTts {
/*const char *MSPAPI QTTSSessionBegin(const char *params, int *errorCode)
开始一次语音合成,分配语音合成资源。
int MSPAPI QTTSTextPut(const char *sessionID, const char *textString, unsigned int textLen, const char *params)
写入要合成的文本。
const void *MSPAPI QTTSAudioGet(const char *sessionID, unsigned int *audioLen, int *synthStatus, int *errorCode)
获取合成音频。
int MSPAPI QTTSSessionEnd(const char *sessionID, const char *hints)
结束本次语音合成。
int MSPAPI QTTSGetParam(const char *sessionID, const char *paramName, char *paramValue, unsigned int *valueLen)
获取当前语音合成信息,如当前合成音频对应文本结束位置、上行流量、下行流量等。*/
public interface MyDllInterface extends Library {
MyDllInterface INSTANCE = (MyDllInterface)Native.loadLibrary("Tts_x64", MyDllInterface.class);
public int MSPLogin(String usr,String pwd,String params);
//文档方法写错了,耽搁一段时间 net.java.dev.jna需要这个包
//char * 对应String ;;;int *对应IntByReference
String QTTSSessionBegin(String params, IntByReference errorCode);
//char * 对应String ;;;int 对应int;;;
public int QTTSTextPut(String sessionID,String textString,int textLen,String params);
//void * 对应Pointer;;;char *对应String ;;;int * 对应IntByReference;;;
Pointer QTTSAudioGet(String sessionID, IntByReference audioLen, IntByReference synthStatus, IntByReference errorCode);
//char *对应String;;;
public int QTTSSessionEnd(String sessionID, String hints);
public int MSPLogout();
}
public static void main(String[] args) throws Exception {
doTts("[p500]浊酒一杯家万里,燕[=yan4]然未勒归无计");
}
public static void doTts(String text) throws Exception{
String login_params = "appid = 填写你自己的appid, work_dir = ./dllLib/tts";//注意资源存放路径
String session_begin_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";
String filename = "tts_sample.wav"; //合成的语音文件名称
//String text = "[p500]浊酒一杯家万里,燕[=yan4]然未勒归无计"; //合成文本
int ret = MyDllInterface.INSTANCE.MSPLogin(null, null, login_params);
if (0!= ret)
{
System.out.println("MSPLogin failed, error code: %d.n"+ret);
}
System.out.println("## 语音合成(Text To Speech,TTS)技术能够自动将任意文字实时转换为连续的 ##");
System.out.println("## 自然语音,是一种能够在任何时间、任何地点,向任何人提供语音信息服务的 ##");
System.out.println("## 高效便捷手段,非常符合信息时代海量数据、动态更新和个性化查询的需求。 ##");
System.out.println("开始合成 ...");
IntByReference retOneIntByReference = new IntByReference(-1);
String sessionID = MyDllInterface.INSTANCE.QTTSSessionBegin(session_begin_params,retOneIntByReference);
System.out.println("sessionID:"+sessionID+";;;C/C++中的文本长度"+text.getBytes().length);
//text.length()*3
ret= MyDllInterface.INSTANCE.QTTSTextPut(sessionID, text, text.getBytes().length, null);
System.out.println("正在合成 ...");
int audio_len=1280;
int synth_status=1;
File file=new File(filename);
IntByReference audioLenIntByReference = new IntByReference(0);
IntByReference synthStatusIntByReference = new IntByReference(1);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(960000000);
int totalAudioLength = 0;
int indexFlag=0;
//设置音频实时播放参数,
AudioFormat audioFormat =new AudioFormat(16000F, 16, 1,true,false);
// 设置数据输入,开启播放监听
DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class,audioFormat, AudioSystem.NOT_SPECIFIED);
SourceDataLine sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo);
sourceDataLine.open(audioFormat);
sourceDataLine.start();
while (true) {
/* 获取合成音频 */
//System.err.println("即将发生错误");
//const void *不知道怎么转换
//System.err.println(ret);
Pointer dataPoint = MyDllInterface.INSTANCE.QTTSAudioGet(sessionID,audioLenIntByReference,synthStatusIntByReference,retOneIntByReference);
if (0!= ret){
System.err.println(ret);
break;
}
//System.err.println(retOneIntByReference.getValue());
byte[] dataByteAudio;
if (dataPoint!=null ){
dataByteAudio = dataPoint.getByteArray(0, audioLenIntByReference.getValue());
try{
//System.out.println("本次获得音频长度"+audioLenIntByReference.getValue());
//System.out.println(dataByteAudio.toString());
byteArrayOutputStream.write(dataByteAudio,0,audioLenIntByReference.getValue());
//每次合成都写入到实时播放的线程中...
sourceDataLine.write(dataByteAudio, 0, audioLenIntByReference.getValue());
}catch(Exception e){
e.printStackTrace();
}
indexFlag=indexFlag+audioLenIntByReference.getValue();
totalAudioLength=totalAudioLength+audioLenIntByReference.getValue();
}
//System.err.println(synthStatusIntByReference.getValue());
if (synthStatusIntByReference.getValue()==2){
break;
}
//Thread.sleep(50);
}
// 清空数据缓冲,并关闭输入。实时播放完毕,关闭播放流
sourceDataLine.drain();
sourceDataLine.close();
byteArrayOutputStream.flush();
byteArrayOutputStream.close();
//可以把字节数组进行Base64加密打印
//然后再解密写进去
//System.err.println(Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray()));
//System.err.println(byteArrayOutputStream.toByteArray());
//直接通过FileOutputStream写字节数字到文件也是可以的~
/*File f = new File("./zMusic/pcm/Tts/在线语音合成.pcm");
FileOutputStream os = new FileOutputStream(f);
os.write(byteArrayOutputStream.toByteArray());
os.flush();*/
WaveHeader.DataSize = WaveHeader.revers(WaveHeader.intToBytes(totalAudioLength));
WaveHeader.RIFF_SIZE = WaveHeader.revers(WaveHeader.intToBytes(totalAudioLength + 36 - 8));
File wavfile = new File("./tts_sample.wav");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(wavfile);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
WaveHeader.init();
bufferedOutputStream.write(WaveHeader.RIFF);
bufferedOutputStream.write(WaveHeader.RIFF_SIZE);
bufferedOutputStream.write(WaveHeader.RIFF_TYPE);
bufferedOutputStream.write(WaveHeader.FORMAT);
bufferedOutputStream.write(WaveHeader.FORMAT_SIZE);
bufferedOutputStream.write(WaveHeader.FORMAT_TAG);
bufferedOutputStream.write(WaveHeader.CHANNELS);
bufferedOutputStream.write(WaveHeader.SamplesPerSec);
bufferedOutputStream.write(WaveHeader.AvgBytesPerSec);
bufferedOutputStream.write(WaveHeader.BlockAlign);
bufferedOutputStream.write(WaveHeader.BitsPerSample);
bufferedOutputStream.write(WaveHeader.Data);
bufferedOutputStream.write(WaveHeader.DataSize);
bufferedOutputStream.write(byteArrayOutputStream.toByteArray());
bufferedOutputStream.flush();
bufferedOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 合成完毕
retOneIntByReference.setValue(MyDllInterface.INSTANCE.QTTSSessionEnd(sessionID, "正常退出"));
if (0!= retOneIntByReference.getValue()) {
System.out.println("QTTSSessionEnd failed, error code:" + retOneIntByReference.getValue());
}
System.out.println("合成完毕");
//退出
MyDllInterface.INSTANCE.MSPLogout();
//无需使用下面的方法,实时播放
//PlayWav playWav=new PlayWav("./tts_sample.wav");
//playWav.play();
}
}
最后
以上就是不安雪糕为你收集整理的java 离线语音合成_Java通过JNA调用离线语音合成dll的全部内容,希望文章能够帮你解决java 离线语音合成_Java通过JNA调用离线语音合成dll所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复