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)
Without knowing much about the use of your library, it looks like you're setting a
voice
variable in the constructor, then in thetextToMp3
method you're callingvoice.deallocate
. This means if you calltextToMp3
twice on the same Java object, it's going to try and use a deallocated voice.You're also storing the
voiceManager
andvoice
asstatic
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.