2010-03-21 15 views
7

J'essaie d'exécuter un programme en utilisant freetts. Je suis en mesure de compiler le programme mais je ne suis pas en mesure d'utiliser kevin ou mbrola voix que je reçois le message de sortie follwing à la finException avec Freetts lors de l'utilisation de kevin ou mbrola

propriété système « mbrola.base » est non défini. N'utilise pas de voix MBROLA.
LINE INDISPONIBLE: Format est pcm_signed 16000,0 Hz 16 bits 1 canal grand 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

Je ne l'ai pas utilisé depuis longtemps. Mais, as-tu mis tout ce dont tu as besoin dans ton cours? D'après ce dont je me souviens, il y avait quelque chose que vous deviez mettre dans votre répertoire personnel (c'était une version plus ancienne), cela pourrait être une autre raison pour un problème (si vous avez encore besoin de faire cela). En outre, il peut être nécessaire de définir d'autres variables d'environnement, comme si vous deviez définir une variable MBROLA_HOME. Aussi avez-vous été en mesure d'exécuter l'un des exemples de programmes qui l'accompagnent? Je suis désolé de continuer à poser des questions, mais ils aident à affiner le problème. –

+0

désolé un couple de plus, l'exception de ligne indisponible peut être levée lorsque vous essayez de jouer des sons en même temps, en fonction de ce que vous avez fait pour lire les fichiers. Pouvez-vous montrer une partie du code que vous utilisez pour jouer la voix. –

+0

Nous devons copier speech.properties que j'ai déjà fait. Cependant, je ne suis pas capable de lier les interfaces vocales mbrola avec mon programme ni le haut-parleur kevin par défaut mais j'ai inclus l'utilisateur kevin dans le classpath de mon programme – manugupt1

Répondre

2

Il semble que « pour permettre FreeTTS soutenir pour MBROLA, simplement copier mbrola/mbrola.jar à lib/mbrola.jar. ensuite, chaque fois que vous exécutez une application FreeTTS, spécifiez le répertoire "mbrola.base" comme propriété système:

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

J'ai trouvé à:

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

1

La deuxième phrase n'a rien à voir avec mbrola, mais avec un horrible bug Java java qui n'est toujours pas corrigé. Vérifiez le troisième message ici: https://forums.oracle.com/forums/thread.jspa?threadID=2206163

Ce qui se passe parce que freetts « trusts », le sourcedataline au lieu de faire la solution de contournement sur ce poste. Le bug est dans le jdk, mais peut être travaillé en trouvant où en freetts qui se passe et en insérant la solution & de recompilation.

Voici 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 vissé ce lien de forum, quelqu'un sait où il est maintenant? –

+0

Ou, le correctif/solution de contournement elle-même. –

+0

IIRC la solution de contournement était d'ouvrir la dataline (avec try catch enfin proche). Cela est nécessaire car certaines datalines indiquent qu'elles prennent en charge un format, mais lorsque vous essayez de les ouvrir, elles explosent. C'est nul, bien sûr. – i30817

2

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

Un grand merci à l'auteur.


Un programme basé sur FreeTTS, le moteur sans texte de synthèse vocale pour Java, obtenait des erreurs occasionnelles

"LINE UNAVAILABLE: Format is ..." 

Turns out il n'y a pas d'exception Java ou un autre mécanisme pour détecter cette erreur se produit à l'intérieur de la bibliothèque FreeTTS. Tout ce que vous obtenez est le message sur System.out, donc il n'y a pas de bonne façon de réagir par programme. Solution de contournement: configurez le lecteur audio FreeTTS pour tenter d'accéder au périphérique audio plusieurs fois jusqu'à ce qu'il réussisse. Dans cet exemple, un délai court de 0,1 seconde est utilisé pour ne pas manquer une opportunité de saisir le périphérique audio; nous continuons à essayer pendant 30 secondes:

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

Si le périphérique audio est en permanence utilisé par un autre programme, il y a bien sûr aucun moyen d'y accéder. Sous Linux, cette commande affiche l'ID du processus qui tient actuellement le périphérique audio, de sorte que vous pouvez alors essayer de se débarrasser du programme incriminé:

/sbin/fuser /dev/dsp 
1

Je sais que je suis le poster peu tard, mais Cela peut aider quelqu'un. J'ai essayé avec kevin et mbrola, et cela a fonctionné pour moi. Veuillez trouver le code ci-dessous.

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(); 
    } 
} 

et ajoutez les dépendances ci-dessous pour votre pom.xml fichier.

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

Espérons que cela vous sera utile.

+0

Ajout de la ligne System.setProperty ("freetts.voices", "com.sun.speech.freetts. en.us.cmu_us_kal.KevinVoiceDirectory "); Et puis mon code fonctionne bien, merci beaucoup. – VanThaoNguyen