有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java FreeTTS无音频linux ubuntu无错误

我正在使用Java6运行Ubuntu10.10,无法让FreeTTS输出任何音频。我已经在三台不同的电脑上试过了,甚至让我的一个朋友在他的Ubuntu电脑上试过,他也遇到了同样的问题。绝对没有显示错误,在获得MBROLA后,我甚至不再收到关于未检测到MBROLA声音的警告。诸如此类

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

我使用的命令

java -jar lib/freetts.jar -text Hello

当我点击回车键时,它会启动,并曾给我丢失的MBROLA警告消息,但现在它只是坐在那里,直到我按下CTRL-C键停止它

我不明白我做错了什么,为什么没有其他人有这个问题,当我在每台计算机上体验它时,它在Windows上运行得有些好。有人能帮我吗

谢谢

约翰


共 (1) 个答案

  1. # 1 楼答案

    我不确定你是否已经解决了这个问题,但我遇到了同样的问题(Ubuntu 10.10/JavaSE6)。在对FreeTTS源进行了一些调查后,我在com中发现了一个死锁。太阳演讲弗里茨。音频JavaStreamingAudioPlayer。当一行被打开并且该行的类型为org时,就会发生死锁。类路径。冰岛。pulseaudio。PulseAudioSourceDataLine(这可能是Ubuntu10.10W JavaSE6中的默认设置)。因为你总是想打开一条线路来输出音频,所以这种死锁总是会发生

    这种死锁的原因在于,在JavaStreamingAudioLayer中,对Line进行了一个假设,即所有LineListener都将从与Line相同的线程收到一个类型为open的LineEvent的通知。调用了open(),或者在行被打开之后(对Line.open()的调用可以返回)。PulseaudioSourceDaline的情况并非如此;它首先从PulseAudio事件线程调用所有LineListener,等待它们全部返回,然后从open调用返回。通过JavaStreamingAudioPlayer,可以在线路调用时强制同步。open()和处理特定LineListener的任务是查看该行是否实际打开,则会发生死锁

    我为解决这个问题选择的解决方法是实现一个没有这个问题的音频播放器。我基本上复制了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: ...
    

    我删除了两个同步块,并没有确保这两个部分相互排斥,而是使用了一个信号灯来表示线路实际上是开放的。当然,这并不是必须的,因为PulseAudioSourceDaline已经保证在返回时被打开,但在另一个平台上测试相同的代码时,它更有可能发挥良好的作用。我没有花足够长的时间研究代码,以说明当多个线程同时打开/关闭/打开行时会发生什么。如果要这样做,可能需要对JavaStreamingAudioPlayer进行更大的重写;)

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

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

    在代码早期的某个地方

    希望这一切对你有用