Soy un estudiante que ha estado tratando de hacer FreeTTS trabajando en su Ubuntu durante una semana. Y finalmente encontré la respuesta aquí: ¡muchas gracias, hakvroot!
Su respuesta fue perfecto, pero no puso su aplicación y esto me llevó bastante una hora para entender lo que estaba pasando en la clase JavaStreamingAudioPlayer. Para ayudar a otras personas como yo que no se utilizan para "bucear" en un código Java completamente desconocido (todavía soy un estudiante), voy a poner aquí mi código y espero que ayude a otras personas :).
En primer lugar, una explicación más detallada: alrededor de la línea 152, la JavaStreamingAudioPlayer abre una línea. Sin embargo, esta operación puede requerir algo de tiempo, por lo que antes de usarla, quiere verificar que esté abierta. En la implementación actual, la solución utilizada es crear un LineListener escuchando esta línea y luego dormir (usando el método wait() de los hilos).
El LineListener "activará" el hilo principal utilizando notifyAll() y lo hará solo cuando reciba un LineEvent de tipo "OPEN" que garantizará que la línea se haya abierto.
Sin embargo, como se explica por hakvroot aquí el problema es que la notificación no se envía nunca debido al comportamiento específico del DataLine utilizado por Ubuntu.
Así que eliminé las partes del código synchronized, wait() y notifyAll(), pero como hakvroot, su JavaStreamingAudioPlayer podría intentar usar su línea antes de abrirla: debe esperar la confirmación con un nuevo mecanismo detener el JavaStreamingAudioPlayer y reactivarlo más tarde, cuando llegó la confirmación.
por lo que utiliza el semáforo, que havkroot utilizado (ver Javadoc para obtener explicaciones sobre este sistema de bloqueo) iniciados con 1 pila:
cuando se abre la línea adquiere una pila (por lo que 0 restos)
cuando se quiere utilizar la línea que trata de adquirir otra (por lo que se detuvo)
cuando el oyente recibe el evento que estamos buscando, se libera el semáforo
esto libera la JavaStreamingAudioPlayer que puede ir para la siguiente parte
no se olvide de liberar de nuevo el semáforo por lo que tiene de nuevo 1 pila para la siguiente línea para abrir
Y aquí está mi código:
declara una variable del semáforo:
private Semaphore hackSemaphore;
Iniciado en el constructor:
hackSemaphore = new Semaphore(1);
A continuación, la primera parte para cambiar (consulte el hakvroot para ver dónde ponerlo):
line = (SourceDataLine) AudioSystem.getLine(info);
line.addLineListener(new JavaStreamLineListener());
line.open(format, AUDIO_BUFFER_SIZE);
hackSemaphore.acquire();
hackSemaphore.acquire();
opened = true;
hackSemaphore.release();
Y la segunda parte:
public void update(LineEvent event) {
if (event.getType().equals(LineEvent.Type.OPEN)) {
hackSemaphore.release();
}
}
I también se encontró con esto como se puede ver aquí: https://bugs.launchpad.net/communication/+bug/920734 –