我正在从事一个项目,其中我需要文本到语音转换。我下载了这个FreeTTS 1.2,为了熟悉它的工作,我开始编写一个简单的拼写蜜蜂程序,其中的单词将由应用程序说出,您必须正确拼写它。但我在功能上遇到了问题,比如不管我做了什么改变,声音都是一样的。与最初一样,我找到的代码在Voice()构造函数中有以下参数
Voice kevin = new Voice("kevin",
Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);但后来我把它改成
Voice kevin = new Voice("Different1",
Voice.GENDER_FEMALE, Voice.AGE_MIDDLE_ADULT, null);声音仍然是一样的。FreeTTS附带了一个speech.properties文件,为了运行代码,我必须将该文件粘贴到我的主文件夹中。我已经搜索了很多链接来解决这个问题,甚至还检查了Javadoc中的JSAPI和FreeTTS。我唯一的共同点是一个叫MBrola的东西。我不知道这是什么,但当我运行代码时,控制台也会给出一条与它相关的消息。
System property "mbrola.base" is undefined. Will not use MBROLA voices.下面是完整的代码:
package game;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Locale;
import javax.speech.Central;
import javax.speech.synthesis.SpeakableAdapter;
import javax.speech.synthesis.SpeakableEvent;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;
public class MixedVoices {
private final static void usage() {
System.out.println("MixedVoices [-showEvents] [-showPropertyChanges]");
}
/**
* Returns a "no synthesizer" message, and asks
* the user to check if the "speech.properties" file is
* at <code>user.home</code> or <code>java.home/lib</code>.
*
* @return a no synthesizer message
*/
static private String noSynthesizerMessage(String synthesizer)
{
String message =
"Cannot find " + synthesizer + ".\n" +
"This may be the result of any number of problems. It's\n" +
"typically due to a missing \"speech.properties\" file that\n" +
"should be at either of these locations: \n\n";
message += "user.home : " + System.getProperty("user.home") + "\n";
message += "java.home/lib: " + System.getProperty("java.home") +
File.separator + "lib\n\n" +
"Another cause of this problem might be corrupt or missing\n" +
"voice jar files in the freetts lib directory. This problem\n" +
"also sometimes arises when the freetts.jar file is corrupt\n" +
"or missing. Sorry about that. Please check for these\n" +
"various conditions and then try again.\n";
return message;
}
public static void main(String[] argv)
{
boolean showEvents = false;
boolean showPropertyChanges = false;
for (int i = 0; i < argv.length; i++)
{
if (argv[i].equals("-showEvents")) {
showEvents = true;
} else if (argv[i].equals("-showPropertyChanges")) {
showPropertyChanges = true;
} else {
usage();
System.exit(0);
}
}
System.out.println(" ** Mixed Voices - JSAPI Demonstration program **");
/* kevin in an 8khz general domain diphone voice
*/
Voice kevin = new Voice("kevin",
Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);
/* kevin16 in a 16khz general domain diphone voice
*/
Voice kevinHQ = new Voice("kevin16",
Voice.GENDER_DONT_CARE, Voice.AGE_DONT_CARE, null);
try {
/* Find a synthesizer that has the general domain voice
* we are looking for. NOTE: this uses the Central class
* of JSAPI to find a Synthesizer. The Central class
* expects to find a speech.properties file in user.home
* or java.home/lib.
*
* If your situation doesn't allow you to set up a
* speech.properties file, you can circumvent the Central
* class and do a very non-JSAPI thing by talking to
* FreeTTSEngineCentral directly. See the WebStartClock
* demo for an example of how to do this.
*/
SynthesizerModeDesc generalDesc = new SynthesizerModeDesc(
null, // engine name
"general", // mode name
Locale.US, // locale
null, // running
null); // voice
final Synthesizer synthesizer1 =
Central.createSynthesizer(generalDesc);
if (synthesizer1 == null) {
System.err.println(
noSynthesizerMessage("general domain synthesizer"));
System.exit(1);
}
/* Find a synthesizer that has the time domain voice.
*/
SynthesizerModeDesc limitedDesc = new SynthesizerModeDesc(
null, // engine name
"time", // mode name
Locale.US, // locale
null, // running
null); // voice
final Synthesizer synthesizer2 =
Central.createSynthesizer(limitedDesc);
if (synthesizer2 == null) {
System.err.println(
noSynthesizerMessage("time domain synthesizer"));
System.exit(1);
}
System.out.print(" Allocating synthesizers...");
synthesizer1.allocate();
synthesizer2.allocate();
/* get general domain synthesizer ready to speak
*/
System.out.print("Loading voices...");
synthesizer1.getSynthesizerProperties().setVoice(kevinHQ);
synthesizer1.getSynthesizerProperties().setVoice(kevin);
if (showPropertyChanges) {
synthesizer1.getSynthesizerProperties().addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(
PropertyChangeEvent pce) {
if (pce.getNewValue() instanceof Voice) {
String newVoice =
((Voice) pce.getNewValue()).getName();
System.out.println(
" PCE Voice changed to " + newVoice);
}
else {
System.out.println(
" PCE " + pce.getPropertyName()
+ " changed from "
+ pce.getOldValue() + " to " +
pce.getNewValue() + ".");
}
}
});
}
if (showEvents) {
synthesizer1.addSpeakableListener(
new SpeakableAdapter() {
public void markerReached(SpeakableEvent e) {
dumpEvent(e);
}
public void speakableCancelled(SpeakableEvent e) {
dumpEvent(e);
}
public void speakableEnded(SpeakableEvent e) {
dumpEvent(e);
}
public void speakablePaused(SpeakableEvent e) {
dumpEvent(e);
}
public void speakableResumed(SpeakableEvent e) {
dumpEvent(e);
}
public void speakableStarted(SpeakableEvent e) {
dumpEvent(e);
}
public void topOfQueue(SpeakableEvent e) {
dumpEvent(e);
}
public void wordStarted(SpeakableEvent e) {
dumpEvent(e);
}
private void dumpEvent(SpeakableEvent e) {
System.out.println(" EVT: " + e.paramString()
+ " source: " + e.getSource());
}
});
}
System.out.println("And here we go!");
synthesizer1.resume();
synthesizer2.resume();
// speak the "Hello world" string
synthesizer1.speakPlainText("Hello! My name is Kevin.", null);
synthesizer1.speakPlainText("I am a die phone synthesizer", null);
synthesizer1.speakPlainText("I have a friend named Alan.", null);
synthesizer1.speakPlainText("Listen to him count!", null);
// get synth2 ready to speak
synthesizer2.waitEngineState(Synthesizer.ALLOCATED);
synthesizer2.resume();
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.speakPlainText("1 2 3 4 5 6 7 8 9 ten", null);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText("Now listen to me count!", null);
synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
synthesizer1.speakPlainText(
"Now, let's try that a little bit faster.", null);
synthesi zer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setSpeakingRate(240.0f);
synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
synthesizer1.speakPlainText("That's pretty fast.", null);
synthesizer1.speakPlainText("Now lets go very slow.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setSpeakingRate(80.0f);
synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 10.", null);
synthesizer1.speakPlainText("That is pretty slow.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setSpeakingRate(150.0f);
synthesizer1.speakPlainText("Now back to normal", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setPitch(200);
synthesizer1.speakPlainText("I can talk very high.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setPitch(50);
synthesizer1.speakPlainText("and I can talk very low.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setPitch(100);
synthesizer1.getSynthesizerProperties().setVolume(.8f);
synthesizer1.speakPlainText("and I can talk very softly.", null);
synt hesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setVolume(1.0f);
synthesizer1.speakPlainText(
"I can talk with a higher quality voice", null);
synthesizer1.speakPlainText(
"Here is a low quality tongue twister. "
+ "She sells seashells by the seashore.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.getSynthesizerProperties().setVoice(kevinHQ);
synthesizer1.speakPlainText("And this is high quality. "
+ "She sells seashells by the seashore.", null);
synthesizer1.speakPlainText(
"The funny thing is, I do not have a tongue.", null);
synthesizer1.speakPlainText(
"Hey Alan, what time is it where you are right now?", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.speakPlainText(
"the time is now twenty past six.", null);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText("Is that the exact time?", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.speakPlainText("Almost", null);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText(
"Is it twenty past six In the morning or the evening?", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.speakPlainText("in the morning.", null);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText(
"Alan and I can talk at the same time", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText("1 2 3 4 5 6 7 8 9 11 12", null);
synthesizer2.speakPlainText("1 2 3 4 5 6 7 8 9", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer2.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer1.speakPlainText( "That is a bit confusing.", null);
synthesizer1.speakPlainText( "Well, thanks. This was fun.", null);
synthesizer1.speakPlainText("Goodbye everyone.", null);
synthesizer1.waitEngineState(Synthesizer.QUEUE_EMPTY);
// clean up
synthesizer1.deallocate();
synthesizer2.deallocate();
}
catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
}发布于 2014-07-03 07:50:48
您可以访问的声音由VoiceManager类控制。它将通过几种不同的方法搜索安装在您系统中的语音包。默认情况下,你会安装3个声音:“阿兰”,“凯文”和"kevin16“。您需要安装其他语音包(例如CMUArctic或MBROLA),然后才能使用除3种默认语音之外的语音。
但是,一旦您安装了新的语音(查看相应的网站以获取安装说明),您还需要将该语音目录添加到正确的位置,并将其名称添加到一个文本文件中,该文本文件列出了所有已安装的语音。请看一下安装语音包下面的Programmer's Guide。作为参考,我最终将我的新语音包路径添加到了我正在使用的freetts.jar旁边的voices.txt文件中(这有点棘手-我忘记了我已经将它添加到了我的Mac上的Library/Java/Extensions文件夹中,所以你可能必须在那里添加voices.txt文件)。
您可以使用以下代码查看哪些语音可用:
VoiceManager voiceManager = VoiceManager.getInstance();
Voice[] voices = voiceManager.getVoices();
for (int i = 0; i < voices.length; i++){
System.out.print( "voice name is: " + voices[i].getName() +"\n");
}成功添加已安装语音的Voice目录后,在运行该代码时应该会看到列出的语音目录。
https://stackoverflow.com/questions/21978269
复制相似问题