我是靠谱客的博主 不安雪糕,最近开发中收集的这篇文章主要介绍java 离线语音合成_Java通过JNA调用离线语音合成dll,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部