我是一名一直試圖讓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