Getting exception trying to generate 2 tts files using freetts

119 views Asked by At

When I'm trying to call method textToMp3() second time, I'm getting IllegalStateException. I tried only closing the player, I tried only ending it and as you can see it still doesn't work. It always works for when I'm calling that method first time and always throws excetion after being called second time.Do you have any ideas why?

public class TextToSpeech {
    static VoiceManager manager;
    static Voice voice;

    public TextToSpeech() {

        manager = VoiceManager.getInstance();

        Voice[] voices = new MbrolaVoiceDirectory().getVoices();

        voice = voices[0];
        assert voice != null;
        voice.allocate();

    }

    public File textToMp3(String text, String filename) throws IOException {
        File dir = new File("atis");
        if (!dir.exists()) dir.mkdir();

        SingleFileAudioPlayer player = new SingleFileAudioPlayer(dir.getName() + "\\"+ filename, AudioFileFormat.Type.WAVE);

        player.setVolume(100);

        voice.setAudioPlayer(player);
        voice.setRate(125);

        voice.speak(text);
        voice.deallocate();

        player.end();
        player.close();
        return new File(dir.getName() + "\\"+ filename);
    }
}

And here's the exception

Trouble while processing utterance java.lang.IllegalStateException: output queue closed
java.lang.IllegalStateException: output queue closed
    at com.sun.speech.freetts.OutputQueue.post(OutputQueue.java:53)
    at com.sun.speech.freetts.Voice.processUtterance(Voice.java:424)
    at com.sun.speech.freetts.Voice.speak(Voice.java:289)
    at com.sun.speech.freetts.Voice.speak(Voice.java:235)
    at LavaPlayer.TextToSpeech.textToMp3(TextToSpeech.java:42)
    at Commands.Atis.onGuildMessageReceived(Atis.java:179)
    at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:463)
    at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:96)
    at net.dv8tion.jda.internal.hooks.EventManagerProxy.handleInternally(EventManagerProxy.java:88)
    at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:70)
    at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:158)
    at net.dv8tion.jda.internal.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:97)
    at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:36)
    at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:952)
    at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:839)
    at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:817)
    at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:990)
    at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385)
    at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276)
    at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996)
    at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755)
    at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108)
    at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64)
    at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45)
1

There are 1 answers

0
AlBlue On

Without knowing much about the use of your library, it looks like you're setting a voice variable in the constructor, then in the textToMp3 method you're calling voice.deallocate. This means if you call textToMp3 twice on the same Java object, it's going to try and use a deallocated voice.

You're also storing the voiceManager and voice as static class fields, but it looks like the code you're using is only going to work assuming they are instance variables. You should probably change this so that they are referred to as instance fields instead, so you can construct a class and access it each time.