Я студент, который пытался заставить FreeTTS работать с Ubuntu в течение одной недели.И, наконец, я нашел ответ здесь: большое спасибо hakvroot!
Ваш ответ был идеальным, но вы не поместили свою реализацию, и мне потребовался целый час, чтобы понять, что происходит в классе JavaStreamingAudioPlayer.Чтобы помочь другим людям, таким как я, которые не используются для «погружения» в совершенно неизвестном коде Java (я еще студент), я добавлю сюда свой код и надеюсь, что он поможет другим людям :).
Во-первых, более подробное объяснение: около строки 152 JavaStreamingAudioPlayer открывает строку.Однако эта операция может занять некоторое время, поэтому перед ее использованием она хочет проверить, открыта ли она.В текущей реализации используемое решение состоит в том, чтобы создать LineListener, прослушивающий эту строку, а затем перевести его в спящий режим (используя метод wait () потоков).
LineListener "разбудит" основной поток, используяa notifyAll () и будет делать это только тогда, когда он получит LineEvent типа «OPEN», который будет гарантировать, что линия была открыта.
Однако, как объясняется здесь hakvroot, проблема заключается в том, что уведомление никогда не отправляетсяиз-за специфического поведения DataLine, используемого Ubuntu.
Так что я удалил синхронизированные части кода, wait () и notifyAll (), но как hakvroot, ваш JavaStreamingAudioPlayer может попытаться использовать вашу Line перед этимоткрывается: вам нужно дождаться подтверждения с новым механизмом, чтобы остановить JavaStreamingAudioPlayer и разбудить его позже, когда пришло подтверждение.
Поэтому я использовал семафор, который использовал havkroot (см. Javadoc для объясненийэта система блокировки) инициируется с 1 стека:
когда линия открыта, она получает один стек (таким образом, 0 остается)
, когда она хочет использовать линию, она пытается получить другую (так что этоостановлено)
когда слушатель получает искомое событие, он освобождает семафор
, это освобождает JavaStreamingAudioPlayer, который может перейти кследующая часть
не забудьте снова выпустить семафор, чтобы у него снова был 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();
}
}