我是一名一直试图让FreeTTS在其Ubuntu上工作一周的学生。最后我在这里找到了答案:非常感谢你hakvroot!
你的答案很完美,但你没有把你的实现,这花了我一个多小时了解JavaStreamingAudioPlayer类中发生了什么。为了帮助像我这样的人,他们不用在一个完全未知的Java代码中(我仍然是一名学生)“潜水”,我会在这里放置我的代码,并希望它能帮助其他人:)。
首先,更详细的解释:在第152行左右,JavaStreamingAudioPlayer打开一个Line。但是这个操作在使用之前可能需要一些时间,所以想要检查它是否打开。在当前的实现中,使用的解决方案是创建一个LineListener,监听这一行,然后进入休眠状态(使用线程的wait()方法)。
LineListener会使用notifyAll()“唤醒”主线程,并且只有当它收到一个类型为“OPEN”的LineEvent时才会这样做,这将保证该线已被打开。
但正如hakvroot在这里解释的那样,问题在于,由于Ubuntu使用的DataLine的特定行为,通知永远不会发送。
因此,我删除了代码的同步wait()和notifyAll()部分,但作为hakvroot,那么JavaStreamingAudioPlayer可能会在打开它之前尝试使用您的Line:您需要等待带有新机制的确认停止JavaStreamingAudioPlayer并在稍后确认到达时将其唤醒。
因此,我使用的信号量,其havkroot使用(参见的Javadoc此锁定系统上的解释)被1个栈启动:
这里是我的代码:
声明一个信号变量:
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();
}
}
我你也可以在这里看到:https://bugs.launchpad.net/communication/+bug/920734 – 2013-01-08 22:34:16