我正在尝试使用freetts运行程序。我能够编译程序但是我无法使用 kevin 或 mbrola 的声音我最后得到了输出消息
系统属性“mbrola.base”未定义。不会使用MBROLA声音。
LINE UNAVAILABLE:格式为pcm_signed 16000.0 Hz 16位1通道大端
import javax.speech.*;
import javax.speech.synthesis.*;
import java.util.*;
class freetts {
public static void main(String[] args) {
try{
Calendar calendar = new GregorianCalendar();
String sayTime = "It is " + calendar.get(Calendar.HOUR) + " " + calendar.get(Calendar.MINUTE) + " " + (calendar.get(Calendar.AM_PM)==0 ? "AM":"PM");
Synthesizer synth = Central.createSynthesizer(null);
synth.allocate();
synth.resume();
synth.speakPlainText(sayTime, null);
synth.waitEngineState(Synthesizer.QUEUE_EMPTY);
synth.deallocate();
}
catch(Exception e){
e.printStackTrace();
}
}
}
答案 0 :(得分:2)
似乎“要为MBROLA启用FreeTTS支持,只需将mbrola / mbrola.jar复制到lib / mbrola.jar。然后,每当运行任何FreeTTS应用程序时,请将”mbrola.base“目录指定为系统属性:
java -Dmbrola.base=/home/jim/mbrola -jar bin/FreeTTSHelloWorld.jar mbrola_us1"
我发现了这个:
答案 1 :(得分:2)
http://workorhobby.blogspot.com/2011/02/java-audio-freetts-line-unavailable.html
非常感谢作者。
基于FreeTTS的程序,Java的免费文本到语音引擎,偶尔会出现错误
"LINE UNAVAILABLE: Format is ..."
原来没有Java异常或其他机制来检测FreeTTS库中发生的这个错误。你得到的只是System.out上的消息,因此没有好的方法以编程方式做出反应。
解决方法:将FreeTTS音频播放器配置为尝试多次访问音频设备,直到成功为止。在这个例子中,使用0.1秒的短暂延迟来不错过抓取音频设备的机会;我们继续尝试30秒:
System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.openFailDelayMs", "100");
System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.totalOpenFailDelayMs", "30000");
如果音频设备被其他程序永久使用,则当然无法访问。在Linux下,此命令将显示当前持有音频设备的进程的ID,因此您可以尝试删除有问题的程序:
/sbin/fuser /dev/dsp
答案 2 :(得分:1)
第二个短语与mbrola无关,但有一个可怕的java linux声音bug仍然没有修复。 在这里查看第三篇文章: https://forums.oracle.com/forums/thread.jspa?threadID=2206163
这种情况正在发生,因为freetts“信任”sourcedataline,而不是在该帖子上进行解决方法。这个bug在jdk中,但是可以通过查找正在发生的freetts中的位置并插入变通方法来解决这个问题。重新编译。
这是一个测试用例
package util.speech;
import java.util.Iterator;
import java.util.Locale;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class VoiceTest {
public VoiceTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void testDataLineAvailableAndBuggyInJDK() throws LineUnavailableException {
boolean failedSimpleGetLine = false;
AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
SourceDataLine line = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
line = (SourceDataLine) AudioSystem.getLine(info);
} catch (LineUnavailableException e) {
//ok, at least it says so
throw e;
}
try {
//if this fails the jdk is very buggy, since it just told us
//the line was available
line.open(format);
} catch (LineUnavailableException e) {
failedSimpleGetLine = true;
} finally {
if (line.isOpen()) {
line.close();
}
}
//now if this is true, test if it's possible to get a valid sourcedataline
//or the only bug is adquiring a sourcedataline doesn't throw a lineunavailable
//exception before open
Assume.assumeTrue(failedSimpleGetLine);
line = getSourceDataLine(format);
if (line == null) {
return;
}
try {
line.open(format);
} catch (LineUnavailableException e) {
//ok then it is consistent, and there is only one bug
fail("Line Unavailable after being adquired");
} finally {
if (line.isOpen()) {
line.close();
}
}
fail("line available after first test not managing to adquire it");
}
private SourceDataLine getSourceDataLine(AudioFormat format) {
try {
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
for (Mixer.Info mi : AudioSystem.getMixerInfo()) {
SourceDataLine dataline = null;
try {
Mixer mixer = AudioSystem.getMixer(mi);
dataline = (SourceDataLine) mixer.getLine(info);
dataline.open(format);
dataline.start();
return dataline;
} catch (Exception e) {
}
if (dataline != null) {
try {
dataline.close();
} catch (Exception e) {
}
}
}
} catch (Exception e) {
}
return null;
}
}
答案 3 :(得分:1)
我知道我发帖很晚,但这可能对某人有所帮助。我尝试了kevin和mbrola,它对我有用。请找到以下代码。
package com.mani.texttospeech;
import java.beans.PropertyVetoException;
import java.util.Locale;
import javax.speech.AudioException;
import javax.speech.Central;
import javax.speech.EngineException;
import javax.speech.EngineStateError;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;
/**
*
* @author Manindar
*/
public class SpeechUtils {
SynthesizerModeDesc desc;
Synthesizer synthesizer;
Voice voice;
public void init(String voiceName) throws EngineException, AudioException, EngineStateError, PropertyVetoException {
if (desc == null) {
System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
desc = new SynthesizerModeDesc(Locale.US);
Central.registerEngineCentral("com.sun.speech.freetts.jsapi.FreeTTSEngineCentral");
synthesizer = Central.createSynthesizer(desc);
synthesizer.allocate();
synthesizer.resume();
SynthesizerModeDesc smd = (SynthesizerModeDesc) synthesizer.getEngineModeDesc();
Voice[] voices = smd.getVoices();
for (Voice voice1 : voices) {
if (voice1.getName().equals(voiceName)) {
voice = voice1;
break;
}
}
synthesizer.getSynthesizerProperties().setVoice(voice);
}
}
public void terminate() throws EngineException, EngineStateError {
synthesizer.deallocate();
}
public void doSpeak(String speakText) throws EngineException, AudioException, IllegalArgumentException, InterruptedException {
synthesizer.speakPlainText(speakText, null);
synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
}
public static void main(String[] args) throws Exception {
SpeechUtils su = new SpeechUtils();
su.init("kevin16");
// su.init("kevin");
// su.init("mbrola_us1");
// su.init("mbrola_us2");
// su.init("mbrola_us3");
// high quality
su.doSpeak("Hi this is Manindar. Welcome to audio world.");
su.terminate();
}
}
并将以下依赖项添加到 pom.xml 文件中。
<dependencies>
<dependency>
<groupId>net.sf.sociaal</groupId>
<artifactId>freetts</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
希望这会有所帮助。