FreeTTS, Java, Linux:Solução alternativa para “LINHA INDISPONÍVEL:O formato é…”
-
15-11-2019 - |
Pergunta
Quando executo exemplos do FreeTTS, recebo este erro:
LINE UNAVAILABLE: Format is pcm_signed 16000.0 Hz 16 bits 1 channel big endian
Nesta postagem, Problema de Freett em Java
Alguém afirma que é um bug de som linux/java conhecido e tem uma solução alternativa, vinculando -se a http://forums.sun.com/thread.jspa?threadID=5189363 .
Mas esse link não funciona mais desde que a Oracle estragou tudo.Archive.org parece não ter esta página arquivada.
Alguém tem a solução alternativa/patch para o FreeTTS?
Obrigado, Ondra
Solução 2
Hmm, tive mais sorte pesquisando no Google depois de fazer a pergunta, então...:http://workorhobby.blogspot.com/2011/02/java-audio-freetts-line-unavailable.htmlUm grande obrigado ao autor.
Atualizar: Na verdade, esta não é uma boa solução alternativa, pois manterá o FreeTTS em espera até que a linha esteja livre.
FWIU, o patch mencionado tinha uma solução melhor - não exigindo acesso exclusivo ou algo assim.
Atualizar: Eu compilei um Solução de problemas do FreeTTS página.
Um programa baseado no FreeTTS, o mecanismo de conversão de texto em fala gratuito para Java, apresentava erros ocasionais
"LINE UNAVAILABLE: Format is ..."
Acontece que não há exceção Java ou outro mecanismo para detectar esse erro que ocorre dentro da biblioteca FreeTTS.Tudo o que você recebe é a mensagem no System.out, portanto não há uma boa maneira de reagir programaticamente.
Gambiarra:Configure o reprodutor de áudio FreeTTS para tentar acessar o dispositivo de áudio mais de uma vez até conseguir.Neste exemplo, um pequeno atraso de 0,1 segundos é usado para não perder a oportunidade de capturar o dispositivo de áudio;continuamos tentando por 30 segundos:
System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.openFailDelayMs", "100");
System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.totalOpenFailDelayMs", "30000");
Se o dispositivo de áudio for usado permanentemente por outro programa, é claro que não há como obter acesso.No Linux, este comando exibirá o ID do processo que está atualmente mantendo o dispositivo de áudio, para que você possa tentar se livrar do programa agressor:
/sbin/fuser /dev/dsp
Outras dicas
A ALSA do Linux é uma API grande e complexa.O OpenJDK e o JDK da Sun parecem usá-lo de maneira diferente.A maioria das distribuições Linux modernas também usa PulseAudio, que virtualiza o ALSA para que todo o áudio passe pelo PulseAudio para mixagem de software antes de ir para o ALSA para reprodução.
Quando nada acessa a placa de som e Java é o único usuário, ela tende a funcionar.No entanto, quando outra coisa está com a placa de som aberta, os aplicativos Java quebram rapidamente com o seu erro e "javax.sound.sampled.LineUnavailableException:Dispositivo de áudio indisponível".
Uma possível solução alternativa é enumerar todos os mixers no sistema com AudioSystem.getMixerInfo()
, então tente abrir a linha com AudioSystem.getSourceDataLine(format, mixerInfo)
para os misturadores que você deseja.Alguns funcionarão melhor que outros.Em particular, os mixers "Java Sound Audio Engine" e "default [default]", se existirem, tendem a funcionar.
A única solução se você não quiser modificar o código-fonte do FreeTTS é instalar o pulse-java.Isso registra um provedor de som PulseAudio especial, que ignora a virtualização ALSA e vai diretamente para o PulseAudio.O Ubuntu instala isso como parte de seu pacote OpenJDK.
Alguém realmente deveria corrigir o Java Sound para brincar com o ALSA de uma forma mais amigável.Para um nome de dispositivo ALSA deve ser prefixado com plug:
para que o ALSA converta formatos de som e taxas de amostragem instantaneamente.E as outras regras para subconjunto ALSA seguro também deve ser seguido.
Em relação ao link ferrado pela Oracle - visto que resposta SO mais antiga você refere menções Horrendo bug de som java linux que ainda não foi corrigido e sugere verificar a terceira postagem, é provável que o thread perdido tenha sido migrado para:
- https://forums.oracle.com/forums/thread.jspa?threadID=2206163
- o tópico acima começa com referência ao JMF Bug 4352921 em http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4352921_
- a terceira postagem no tópico diz "Sim, de acordo com a documentação da API, é um erro" catastrófico "do qual nenhum jogador pode retornar com segurança.É por isso que é tão estranho poder acioná-lo tão facilmente..."
- a solução alternativa para o problema discutido é descrita na sexta postagem da seguinte forma:
Me deparei com uma postagem no blog que sugeria que o Java precisa ser instruído a usar as bibliotecas OSS, pois ainda não depende do ALSA.O comando a ser utilizado foi "padsp" que força a aplicação a utilizar OSS.Então, se eu chamar "padsp jmstudio", ele agora reproduz e mixa o áudio perfeitamente.Também tentei com meu aplicativo, que pré-busca vários players na mesma JVM, e todos eles pré-buscaram perfeitamente.Parece que, por enquanto, os aplicativos JMF no Linux podem precisar ser chamados por meio do padsp.