2010-03-21 14 views
7

Sto provando ad eseguire un programma usando freetts. Sono in grado di compilare il programma tuttavia non sono in grado di utilizzare Kevin o MBROLA voci ricevo il messaggio di output follwing alla fineEccezione con Freetts quando si utilizza kevin o mbrola

sistema di proprietà "mbrola.base" non è definito. Non userà le voci di MBROLA.
LINE UNAVAILABLE: definizione è pcm_signed 16000,0 Hz 16 bit 1 canale big endian

import javax.speech.*; 
import javax.speech.synthesis.*; 
import java.util.*; 

class freetts { 

    public static void main(String[] args) { 
     try{ 
      Calendar calendar = new GregorianCalendar(); 
      String sayTime = "It is " + calendar.get(Calendar.HOUR) + " " + calendar.get(Calendar.MINUTE) + " " + (calendar.get(Calendar.AM_PM)==0 ? "AM":"PM"); 
      Synthesizer synth = Central.createSynthesizer(null); 
      synth.allocate(); 
      synth.resume(); 
      synth.speakPlainText(sayTime, null); 
      synth.waitEngineState(Synthesizer.QUEUE_EMPTY); 
      synth.deallocate(); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Non l'ho usato da molto tempo. Ma hai messo tutto ciò che ti serve nel tuo percorso di classe? Anche da quello che ricordo c'era qualcosa che dovevi mettere nella tua directory home (questa era una versione precedente), che potrebbe essere un'altra ragione per un problema (se hai ancora bisogno di farlo). Inoltre, potrebbero esserci altre variabili d'ambiente che è necessario impostare, come è stato necessario impostare una variabile MBROLA_HOME. Inoltre, sei stato in grado di eseguire uno qualsiasi dei programmi di esempio forniti con esso? Mi dispiace continuare a fare domande, ma aiutano a restringere il problema. –

+0

scusate ancora un paio, l'eccezione non disponibile riga può essere generata quando si sta tentando di riprodurre suoni allo stesso tempo, a seconda di cosa hai fatto per riprodurre i file. Puoi mostrare parte del codice che stai usando per suonare la voce. –

+0

Abbiamo bisogno di copiare speech.properties L'ho già fatto. Tuttavia non sono in grado di collegare le interfacce vocali mbrola con il mio programma né il diffusore predefinito di kevin, tuttavia ho incluso l'utente kevin nel classpath del mio programma – manugupt1

risposta

2

Sembra che "Per abilitare FreeTTS supporto per MBROLA, semplicemente copiare MBROLA/mbrola.jar a lib/mbrola.jar. poi, ogni volta che si esegue qualsiasi applicazione FreeTTS, specificare la directory "mbrola.base" come una proprietà di sistema:

java -Dmbrola.base=/home/jim/mbrola -jar bin/FreeTTSHelloWorld.jar mbrola_us1" 

ho trovato questo a:

http://freetts.sourceforge.net/mbrola/README.html

1

La seconda frase non ha nulla a che fare con mbrola, ma con un orrendo bug audio java linux che non è ancora stato risolto. Controllare il terzo post qui: https://forums.oracle.com/forums/thread.jspa?threadID=2206163

che sta accadendo perché FreeTTS "trust", il sourcedataline, invece di fare la soluzione su quel post. Il bug si trova nel jdk, ma può essere risolto trovando dove è successo in freetts e inserendo la soluzione alternativa & ricompilazione.

Ecco un testcase

package util.speech; 

import java.util.Iterator; 
import java.util.Locale; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.Mixer; 
import javax.sound.sampled.SourceDataLine; 
import org.junit.After; 
import org.junit.AfterClass; 
import org.junit.Assume; 
import org.junit.Before; 
import org.junit.BeforeClass; 
import org.junit.Test; 
import static org.junit.Assert.*; 

public class VoiceTest { 



    public VoiceTest() { 
    } 

    @BeforeClass 
    public static void setUpClass() throws Exception { 
    } 

    @AfterClass 
    public static void tearDownClass() throws Exception { 
    } 

    @Before 
    public void setUp() { 

    } 

    @After 
    public void tearDown() { 
    } 

    @Test 
    public void testDataLineAvailableAndBuggyInJDK() throws LineUnavailableException { 
     boolean failedSimpleGetLine = false; 
     AudioFormat format = new AudioFormat(44100, 16, 2, true, false); 
     SourceDataLine line = null; 
     DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); 
     try { 
      line = (SourceDataLine) AudioSystem.getLine(info); 
     } catch (LineUnavailableException e) { 
      //ok, at least it says so 
      throw e; 
     } 
     try { 
      //if this fails the jdk is very buggy, since it just told us 
      //the line was available 
      line.open(format); 
     } catch (LineUnavailableException e) { 
      failedSimpleGetLine = true; 
     } finally { 
      if (line.isOpen()) { 
       line.close(); 
      } 
     } 



     //now if this is true, test if it's possible to get a valid sourcedataline 
     //or the only bug is adquiring a sourcedataline doesn't throw a lineunavailable 
     //exception before open 
     Assume.assumeTrue(failedSimpleGetLine); 
     line = getSourceDataLine(format); 
     if (line == null) { 
      return; 
     } 

     try { 
      line.open(format); 
     } catch (LineUnavailableException e) { 
      //ok then it is consistent, and there is only one bug 
      fail("Line Unavailable after being adquired"); 
     } finally { 
      if (line.isOpen()) { 
       line.close(); 
      } 
     } 
     fail("line available after first test not managing to adquire it"); 
    } 


    private SourceDataLine getSourceDataLine(AudioFormat format) { 
     try { 
      DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); 
      for (Mixer.Info mi : AudioSystem.getMixerInfo()) { 
       SourceDataLine dataline = null; 
       try { 
        Mixer mixer = AudioSystem.getMixer(mi); 
        dataline = (SourceDataLine) mixer.getLine(info); 
        dataline.open(format); 
        dataline.start(); 
        return dataline; 
       } catch (Exception e) { 
       } 
       if (dataline != null) { 
        try { 
         dataline.close(); 
        } catch (Exception e) { 
        } 
       } 
      } 
     } catch (Exception e) { 
     } 
     return null; 
    } 
} 
+2

Oracle avvitato quel link del forum, qualcuno sa dove si trova adesso? –

+0

Oppure, la patch/soluzione alternativa. –

+0

IIRC la soluzione era di aprire il dataline (con try catch finalmente close). Questo è necessario perché alcuni datalines riportano che supportano un formato, ma quando effettivamente provi ad aprirli esplodono. Questo fa schifo naturalmente. Il collegamento del forum avvitato – i30817

2

http://workorhobby.blogspot.com/2011/02/java-audio-freetts-line-unavailable.html

Un grande grazie all'autore.


Un programma basato sulla FreeTTS, il motore libera text-to-speech per Java, è stato sempre errori occasionali

"LINE UNAVAILABLE: Format is ..." 

venuto fuori che non esiste alcuna eccezione Java o altro meccanismo per rilevare questo errore si verifica all'interno della libreria di FreeTTS. Tutto ciò che ottieni è il messaggio su System.out, quindi non c'è un buon modo per reagire in modo programmatico.

Soluzione temporanea: configurare il lettore audio FreeTTS per tentare di accedere al dispositivo audio più volte finché non riesce. In questo esempio, viene utilizzato un breve ritardo di 0,1 secondi per non perdere un'opportunità per afferrare il dispositivo audio; continuiamo a provare per 30 secondi:

System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.openFailDelayMs", "100"); 
System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.totalOpenFailDelayMs", "30000"); 

Se il dispositivo audio è permanentemente utilizzato da un altro programma, non v'è ovviamente alcun modo per ottenere l'accesso. Sotto Linux, questo comando visualizzerà l'ID del processo che è attualmente in mano il dispositivo audio, in modo da poter poi cercare di sbarazzarsi del programma incriminato:

/sbin/fuser /dev/dsp 
1

So di postarlo po 'tardi, ma questo può aiutare qualcuno. Ho provato con kevin e mbrola, e ha funzionato per me. Si prega di trovare il codice qui sotto.

package com.mani.texttospeech; 

import java.beans.PropertyVetoException; 
import java.util.Locale; 

import javax.speech.AudioException; 
import javax.speech.Central; 
import javax.speech.EngineException; 
import javax.speech.EngineStateError; 
import javax.speech.synthesis.Synthesizer; 
import javax.speech.synthesis.SynthesizerModeDesc; 
import javax.speech.synthesis.Voice; 

/** 
* 
* @author Manindar 
*/ 
public class SpeechUtils { 

    SynthesizerModeDesc desc; 
    Synthesizer synthesizer; 
    Voice voice; 

    public void init(String voiceName) throws EngineException, AudioException, EngineStateError, PropertyVetoException { 
     if (desc == null) { 
      System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory"); 
      desc = new SynthesizerModeDesc(Locale.US); 
      Central.registerEngineCentral("com.sun.speech.freetts.jsapi.FreeTTSEngineCentral"); 
      synthesizer = Central.createSynthesizer(desc); 
      synthesizer.allocate(); 
      synthesizer.resume(); 
      SynthesizerModeDesc smd = (SynthesizerModeDesc) synthesizer.getEngineModeDesc(); 
      Voice[] voices = smd.getVoices(); 
      for (Voice voice1 : voices) { 
       if (voice1.getName().equals(voiceName)) { 
        voice = voice1; 
        break; 
       } 
      } 
      synthesizer.getSynthesizerProperties().setVoice(voice); 
     } 
    } 

    public void terminate() throws EngineException, EngineStateError { 
     synthesizer.deallocate(); 
    } 

    public void doSpeak(String speakText) throws EngineException, AudioException, IllegalArgumentException, InterruptedException { 
     synthesizer.speakPlainText(speakText, null); 
     synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY); 
    } 

    public static void main(String[] args) throws Exception { 
     SpeechUtils su = new SpeechUtils(); 
     su.init("kevin16"); 
//  su.init("kevin"); 
//  su.init("mbrola_us1"); 
//  su.init("mbrola_us2"); 
//  su.init("mbrola_us3"); 
     // high quality 
     su.doSpeak("Hi this is Manindar. Welcome to audio world."); 
     su.terminate(); 
    } 
} 

e aggiungere le dipendenze sotto ai tuoi pom.xml file.

<dependencies> 
     <dependency> 
      <groupId>net.sf.sociaal</groupId> 
      <artifactId>freetts</artifactId> 
      <version>1.2.2</version> 
     </dependency> 
    </dependencies> 

Spero che questo sia utile.

+0

Aggiunta linea System.setProperty ("freetts.voices", "com.sun.speech.freetts. en.us.cmu_us_kal.KevinVoiceDirectory "); E poi il mio codice funziona bene, grazie mille. – VanThaoNguyen

Problemi correlati