Logo Search packages:      
Sourcecode: bayonne version File versions  Download package

flite.cpp

// Copyright (C) 2000 Open Source Telecom Corporation.
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// As a special exception to the GNU General Public License, permission is
// granted for additional uses of the text contained in its release
// of Bayonne as noted here.
//
// This exception is that permission is hereby granted to link Bayonne 
// with the Festival Light text to speech synthesis system known as
// "flite" and available from the Language Technologies Institute of
// Carnegie Mellon Univerity to produce a executable image so long as each
// source file so linked contains this exclusion.
//
// This exception does not however invalidate any other reasons why
// the resulting executable file might be covered by the GNU General
// public license alone or invalidate the licensing requirements of any
// other component or library.
//
// This exception applies only to the code released by OST under the
// name Bayonne.  If you copy code from other releases into a copy of
// Bayonne, as the General Public License permits, the exception does not
// apply to the code that you add in this way.  To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own to Bayonne, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice, at which
// point the terms of your modification would be covered under the GPL
// as explicitly stated in "COPYING".

extern "C" {

#ifdef      THETA_PREFIX
#include <theta.h>
#else
#include <flite/flite.h>
cst_voice *register_cmu_us_kal();
#endif

};

#include <server.h>
#include <cerrno>

#if defined(THETA_PREFIX) && defined(AUDIO_SIGNED_LINEAR_RAW)
#define     RAW_AUDIO
#endif

#ifdef      CCXX_NAMESPACES
namespace ost {
using namespace std;
#endif

#ifdef      THETA_PREFIX
class Flite : public TTS, public Keydata, public Mutex
#else
class Flite : public TTS
#endif
{
private:
#ifdef      THETA_PREFIX
      typedef struct _voices
      {
            struct _voices *next;
            cst_voice *voice;
            char name[1];
      }     voice;

      voice *voices;
      theta_voice_desc *vlist;
#else
      cst_voice *v;
#endif
      bool synth(unsigned id, trunkdata_t *data);

public:
      const char *getName(void)
#ifdef      THETA_PREFIX
            {return "theta";};
#else
            {return "flite";};
#endif

      Flite();
      ~Flite();

} flite;

#ifdef      THETA_PREFIX
Flite::Flite() : TTS(), Keydata("/bayonne/theta"), Mutex()
#else
Flite::Flite() : TTS()
#endif
{
#ifdef      THETA_PREFIX

      static Keydata::Define keydefs[] = {
      {"UsEngM", "Frank"},
      {"UsEngF", "Emily"},
      {"default", "Emily"},
      {"prefix", "/opt/theta"},
      {NULL, NULL}};

      load(keydefs);
      setenv("THETA_HOME", getLast("prefix"), 1);

      voice *v;
      char *name;
      theta_voice_desc *vdesc;

      voices = NULL;
      theta_init(NULL);

      vlist = theta_enum_voices(NULL, NULL);

      for(vdesc = vlist; vdesc; vdesc = vdesc->next)
      {
            name = vdesc->human;
            v = (voice *)alloc(sizeof(voice) + strlen(name));
            v->voice = theta_load_voice(vdesc);
            v->next = voices;
            strcpy(v->name, name);
            voices = v;
      }

#else
      flite_init();
      v = register_cmu_us_kal();    
#endif
}

Flite::~Flite()
{
#ifdef      THETA_PREFIX
      theta_free_voicelist(vlist);
#endif
}

bool Flite::synth(unsigned id, trunkdata_t *data)
{
      char path[96];

      switch(data->play.mode)
      {
      case PLAY_MODE_TEXT:
      case PLAY_MODE_FILE:
            break;
      default:
            return true;
      }

      if(data->play.cache)
      {
            if(!strnicmp(data->play.cache, "cache/", 6))
            {
                  data->play.lock = true;
                  cachelock.readLock();
            }

#ifdef      RAW_AUDIO
            sprintf(path, "%s.sw", data->play.cache);
#else
            sprintf(path, "%s.wav", data->play.cache);
#endif
            if(canAccess(path))
            {
                  strcpy(data->play.list, path);
                  data->play.name = data->play.list;        
#ifdef      RAW_AUDIO
                  data->play.extension = ".sw";
#else
                  data->play.extension = ".wav";
#endif
                  data->play.timeout = 0;
                  data->play.repeat = 0;
                  data->play.maxtime = 0;
                  data->play.mode = PLAY_MODE_ONE;
                  return true;
            }
            if(data->play.lock)
            {
                  cachelock.unlock();
                  cachelock.writeLock();
            }
      }
      else
      {     
#ifdef      RAW_AUDIO
            sprintf(path, "temp/flite-%04d.sw", id);
#else
            sprintf(path, "temp/flite-%04d.wav", id);
#endif
            remove(path);
      }

#ifdef      THETA_PREFIX
      const char *vl = data->play.voice;
      voice *vt = voices;
      cst_voice *v;

      if(!vl)
            vl = "default";

      const char *vn = getLast(vl);

      if(!vn)
            vn = data->play.voice;

      while(vt)
      {
            if(!stricmp(vn, vt->name))
                  break;
            vt = vt->next;
      }

      if(!vt)
            return true;

      v = vt->voice;
      
      enterMutex();
#ifdef      RAW_AUDIO
      theta_set_outfile(v, path, "raw", 8000, 1);
#else
      theta_set_outfile(v, path, "riff", 8000, 1);
#endif
#endif
      switch(data->play.mode)
      {
      case PLAY_MODE_TEXT:
#ifdef      THETA_PREFIX
            theta_tts(data->play.list, v);
            leaveMutex();
#else
            flite_text_to_speech(data->play.list, v, path);
#endif
            break;
      case PLAY_MODE_FILE:
            if(!canAccess(data->play.list))
            {
#ifdef      THETA_PREFIX
                  leaveMutex();
#endif
                  return false;
            }
#ifdef      THETA_PREFIX
            theta_tts_file(data->play.list, v);
            leaveMutex();
#else
            flite_file_to_speech(data->play.list, v, path);
#endif
      default:
#ifdef      THETA_PREFIX
            leaveMutex();
#endif
            return true;
      }
      strcpy(data->play.list, path);
      if(data->play.cache)
            data->play.mode = PLAY_MODE_ONE;
      else
            data->play.mode = PLAY_MODE_TEMP;
      data->play.name = data->play.list;
#ifdef      RAW_AUDIO
      data->play.extension = ".sw";
#else
      data->play.extension = ".wav";
#endif
      data->play.timeout = 0;
      data->play.repeat = 0;
      data->play.maxtime = 0;
      return true;
}

#ifdef CCXX_NAMESPACES
};
#endif

Generated by  Doxygen 1.6.0   Back to index