【问题标题】:Exception with Freetts when using kevin or mbrola使用 kevin 或 mbrola 时 Freetts 例外
【发布时间】:2011-01-30 00:40:31
【问题描述】:

我正在尝试使用 freetts 运行程序。我可以编译程序但是我不能使用 kevinmbrola 声音我在最后得到以下输出消息

系统属性“mbrola.base”未定义。不会使用 MBROLA 声音。
LINE UNAVAILABLE: 格式为 pcm_signed 16000.0 Hz 16 bits 1 channel 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();
        }
    }
}

【问题讨论】:

  • 好久没用这个了。但是,你有没有把你需要的一切都放在你的类路径中?另外据我所知,您必须在主目录中放入一些东西(这是旧版本),这可能是问题的另一个原因(如果您仍然需要这样做)。此外,您可能需要设置其他环境变量,例如您是否必须设置 MBROLA_HOME 变量。此外,您是否能够运行它附带的任何示例程序?很抱歉一直问问题,但它们有助于缩小问题范围。
  • 抱歉,当您尝试同时播放声音时,可能会抛出线路不可用异常,具体取决于您播放文件的操作。你能展示一些你用来播放声音的代码吗?
  • 我们需要复制 Speech.properties 我已经这样做了。但是,我无法将 mbrola 语音接口与我的程序或默认的 kevin 扬声器绑定,但是我已将 kevin 用户包含在程序的类路径中

标签: java text-to-speech jsapi


【解决方案1】:

似乎“要启用对 MBROLA 的 FreeTTS 支持,只需将 mbrola/mbrola.jar 复制到 lib/mbrola.jar。然后,每当您运行任何 FreeTTS 应用程序时,将“mbrola.base”目录指定为系统属性:

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

我在以下位置找到了这个:

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

【讨论】:

    【解决方案2】:

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

    非常感谢作者。


    一个基于 FreeTTS(Java 的免费文本转语音引擎)的程序偶尔会出现错误

    "LINE UNAVAILABLE: Format is ..."
    

    原来没有 Java 异常或其他机制来检测 FreeTTS 库中发生的此错误。你得到的只是 System.out 上的消息,所以没有很好的方式以编程方式做出反应。

    解决方法:将 FreeTTS 音频播放器配置为多次尝试访问音频设备,直到成功。在此示例中,使用 0.1 秒的短暂延迟以不错过抓取音频设备的机会;我们继续尝试 30 秒:

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

    如果音频设备被另一个程序永久使用,当然没有办法访问。在 Linux 下,此命令将显示当前持有音频设备的进程的 ID,因此您可以尝试摆脱有问题的程序:

    /sbin/fuser /dev/dsp
    

    【讨论】:

      【解决方案3】:

      第二个短语与 mbrola 无关,但与一个尚未修复的可怕的 java linux 声音错误有关。 在这里查看第三个帖子: https://forums.oracle.com/forums/thread.jspa?threadID=2206163

      发生这种情况是因为 freetts “信任”源数据行,而不是在该帖子上进行解决方法。该错误存在于 jdk 中,但可以通过查找 freetts 中发生的位置并插入解决方法并重新编译来解决。

      这是一个测试用例

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

      【讨论】:

      • Oracle 搞砸了那个论坛链接,有人知道它现在在哪里吗?
      • IIRC 的解决方法是打开数据线(try catch 最终关闭)。这是必需的,因为某些数据线报告它们支持某种格式,但是当您实际尝试打开它们时,它们会爆炸。这当然很糟糕。
      • 搞砸的论坛链接很可能已移至forums.oracle.com/forums/thread.jspa?threadID=2206163
      【解决方案4】:

      我知道我发布它有点晚了,但这可能会对某人有所帮助。我尝试了 kevin 和 mbrola,它对我有用。请在下面找到代码。

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

      并将以下依赖项添加到您的 pom.xml 文件中。

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

      希望这会有所帮助。

      【讨论】:

      • 添加行 System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");然后我的代码运行良好,非常感谢。
      猜你喜欢
      • 1970-01-01
      • 2014-12-01
      • 1970-01-01
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-20
      相关资源
      最近更新 更多