我试着用freetts运行一个程序。我能够编译程序,但是我不能使用、kevin、或mbrola语音,我在最后得到了输出消息。
系统属性"mbrola.base“未定义。不会使用MBROLA的声音。
线不可用:格式为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();
}
}
}发布于 2010-03-21 20:11:02
似乎“要启用FreeTTS对MBROLA的支持,只需将mbrola/mbrola.jar复制到lib/mbrola.jar。然后,每当您运行任何FreeTTS应用程序时,将"mbrola.base”目录指定为系统属性:
java -Dmbrola.base=/home/jim/mbrola -jar bin/FreeTTSHelloWorld.jar mbrola_us1"我在:
http://freetts.sourceforge.net/mbrola/README.html
发布于 2011-02-17 23:12:17
http://workorhobby.blogspot.com/2011/02/java-audio-freetts-line-unavailable.html
很大程度上要感谢作者。
一个基于FreeTTS的程序,这是一种免费的文本到语音引擎,偶尔会出现错误。
"LINE UNAVAILABLE: Format is ..."结果发现,没有或其他机制来检测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发布于 2010-03-24 05:52:29
第二个短语与mbrola无关,而是与一个仍未修复的可怕的java linux声音bug有关。查看这里的第三篇文章:https://forums.oracle.com/forums/thread.jspa?threadID=2206163
这种情况之所以发生,是因为自由人“信任”原始数据,而不是在那篇文章上做解决办法。这个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;
}
}https://stackoverflow.com/questions/2486985
复制相似问题