FreeTTS没有音频linux ubuntu – 没有错误

我使用Java 6运行Ubuntu 10.10并且无法获取FreeTTS来输出任何音频。 我现在已经在3台不同的计算机上试过它,甚至要求我的好友在他的Ubuntu PC上试用它并且他遇到了同样的问题。 绝对没有显示错误,在获得MBROLA之后我甚至不再收到关于没有检测到MBROLA声音的警告。 等等等等等等..

使用同一台计算机我运行了一个虚拟盒并启动了Windows XP,我实际上能够在运行HelloWorld.jar和TTSHelloWorld.jar时获得音频,但是当我尝试输入我自己的文本时,freetts.jar仍然是静默的。

我使用的命令。

java -jar lib / freetts.jar -text你好

当我点击进入它启动并用来给我丢失MBROLA警告消息,但现在它只是坐在那里直到我CTRL-C停止它。

我不明白我做错了什么以及为什么没有其他人遇到这个问题,当我在每台计算机上展示它时,它在Windows上有所作为。 谁能帮我?

谢谢,

约翰

我不确定你是否已经设法解决了这个问题,但我遇到了同样的问题(Ubuntu 10.10 / JavaSE6)。 在对FreeTTS源进行一些调查之后,我在com.sun.speech.freetts.audio.JavaStreamingAudioPlayer中找到了罪魁祸首,一个死锁。 当Line打开并且Line的类型为org.classpath.icedtea.pulseaudio.PulseAudioSourceDataLine时(这可能是Ubuntu 10.10 w JavaSE6中的默认值),会发生此死锁。 由于您总是希望打开一行来获取音频,因此将始终发生此死锁。

造成这种死锁的原因在于,在JavaStreamingAudioPlayer中有一个关于Line的假设,即所有LineListener都会被调用一个类型为Line的LineEvent,它与调用Line.open()的线程相同,或者在Line之后已打开(并且可以返回对Line.open()的调用)。 PulseAudioSourceDataLine不是这种情况; 它首先从PulseAudio事件Thread调用所有LineListener,等待所有LineListeners返回,然后从open调用返回。 随着JavaStreamingAudioPlayer围绕Line.open()调用强制同步以及处理特定的LineListener,该任务是查看Line是否实际打开,发生死锁。

我选择解决此问题的解决方法是实现没有此问题的AudioPlayer。 我基本上复制了JavaStreamingAudioPlayer并更改了第196行和第646行的同步块(完整的参考资料来源: http : //www.javadocexamples.com/java_source/com/sun/speech/freetts/audio/JavaStreamingAudioPlayer.java.html )。

___: // This is the actual JavaStreamAudioPlayer source, not the fix 195: ... 196: synchronized (openLock) { 197: line.open(format, AUDIO_BUFFER_SIZE); // Blocks due to line 646 198: try { 199: openLock.wait(); 200: } catch (InterruptedException ie) { 201: ie.printStackTrace(); 202: } 203: ... 643: ... 644: public void update(LineEvent event) { 645: if (event.getType().equals(LineEvent.Type.OPEN)) { 646: synchronized (openLock) { // Blocks due to line 196 647: openLock.notifyAll(); 648: } 649: } 650: } 651: ... 

我删除了两个同步块,而不是确保两个部分相互排除,我使用信号量来表示Line实际上是打开的。 当然,这并不是必需的,因为PulseAudioSourceDataLine已经保证在返回时打开,但是当在另一个平台上测试相同的代码时,它更有可能发挥得很好。 我没有深入研究代码,足以说明当你通过多个Thread同时打开/关闭/打开行时会发生什么。 如果您要这样做,您可能正在考虑更大的JavaStreamingAudioPlayer重写;)。

最后,在创建新的AudioPlayer之后,您必须指示FreeTTS使用您的实现而不是默认的JavaStreamingAudioPlayer。 这可以通过使用来完成

 System.setProperty("com.sun.speech.freetts.voice.defaultAudioPlayer", "classpath.to.your.AudioPlayer"); 

在代码的早期某个地方。

希望这一切都适合你。

我是一名学生,他一直试图让FreeTTS在Ubuntu上工作一周。 最后我在这里找到答案:非常感谢hakvroot!

你的答案很完美,但是你没有实现你的实现,这花了我一个小时的时间来理解JavaStreamingAudioPlayer类中发生了什么。 为了帮助像我这样没有用于潜水的其他人在一个完全未知的Java代码(我还是学生),我会把我的代码放在这里,并希望它能帮助其他人:)。

首先,更详细的解释:在第152行附近,JavaStreamingAudioPlayer打开一个Line。 但是,此操作可能需要一些时间,因此在使用之前,它需要检查它是否已打开。 在当前实现中,使用的解决方案是创建一个LineListener,监听此行,然后进入hibernate状态(使用线程的wait()方法)。

LineListener将使用notifyAll()“唤醒”主线程,并且只有在收到类型为“OPEN”的LineEvent时才会这样做,这将保证线路已被打开。

但是正如hakvroot在这里解释的那样,问题是由于Ubuntu使用的DataLine的特定行为,因此永远不会发送通知。

所以我删除了代码的synchronized,wait()和notifyAll()部分但是作为hakvroot,那么你的JavaStreamingAudioPlayer可能会在打开它之前尝试使用你的Line:你需要等待使用新机制的确认来停止JavaStreamingAudioPlayer并在确认到达时将其唤醒。

所以我使用了havkroot使用的Semaphore(参见Javadoc对这个锁系统的解释)以1个堆栈启动:

  • 当线被打开时,它获得一个堆栈(因此0保持不变)

  • 当它想要使用它试图获取另一条线时(所以它被停止)

  • 当侦听器获取我们正在寻找的事件时,它会释放信号量

  • 这将释放出可以用于下一部分的JavaStreamingAudioPlayer

  • 不要忘记再次释放信号量,这样它又有1个堆栈,可以打开下一行

这是我的代码:

声明一个Semaphore变量:

 private Semaphore hackSemaphore; 

在构造函数中启动它:

 hackSemaphore = new Semaphore(1); 

然后第一部分要更换(参见hakvroot看看它放在哪里):

  line = (SourceDataLine) AudioSystem.getLine(info); line.addLineListener(new JavaStreamLineListener()); line.open(format, AUDIO_BUFFER_SIZE); hackSemaphore.acquire(); hackSemaphore.acquire(); opened = true; hackSemaphore.release(); 

第二部分:

  public void update(LineEvent event) { if (event.getType().equals(LineEvent.Type.OPEN)) { hackSemaphore.release(); } } 

我想在Ubuntu 12.04 / OpenJDK-6上有同样的问题,执行卡在Voice.allocate()中没有错误,也没有响应。 我尝试使用Oracle / Sun JDK-6而不是OpenJDK,它运行良好。

PS很好的指南,可以在Ubuntu上安装SunJDK并配置为默认值http://www.devsniper.com/ubuntu-12-04-install-sun-jdk-6-7/