1 /* 2 * VoiceSynthesizer.hxx - wraps flite+hts_engine 3 * Copyright (C) 2014 Torsten Dreyer - torsten (at) t3r (dot) de 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 */ 19 #ifndef VOICESYNTHESIZER_HXX_ 20 #define VOICESYNTHESIZER_HXX_ 21 22 #include <simgear/sound/sample.hxx> 23 #include <simgear/threads/SGQueue.hxx> 24 25 #include <string> 26 struct _Flite_HTS_Engine; 27 28 /** 29 * A Voice Synthesizer Interface 30 */ 31 class VoiceSynthesizer { 32 public: ~VoiceSynthesizer()33 virtual ~VoiceSynthesizer() {}; 34 virtual SGSoundSample * synthesize( const std::string & text, double volume, double speed, double pitch ) = 0; 35 }; 36 37 class SoundSampleReadyListener { 38 public: ~SoundSampleReadyListener()39 virtual ~SoundSampleReadyListener() {} 40 virtual void SoundSampleReady( SGSharedPtr<SGSoundSample> ) = 0; 41 }; 42 43 struct SynthesizeRequest { SynthesizeRequestSynthesizeRequest44 SynthesizeRequest() { 45 speed = 0.5; 46 volume = 1.0; 47 pitch = 0.5; 48 listener = NULL; 49 } SynthesizeRequestSynthesizeRequest50 SynthesizeRequest( const SynthesizeRequest & other ) { 51 text = other.text; 52 speed = other.speed; 53 volume = other.volume; 54 pitch = other.pitch; 55 listener = other.listener; 56 } 57 operator =SynthesizeRequest58 SynthesizeRequest & operator = ( const SynthesizeRequest & other ) { 59 text = other.text; 60 speed = other.speed; 61 volume = other.volume; 62 pitch = other.pitch; 63 listener = other.listener; 64 return *this; 65 } 66 67 // return a special marker request used to indicate the synthesis thread 68 // should be exited. 69 static SynthesizeRequest cancelThreadRequest(); 70 71 std::string text; 72 double speed; 73 double volume; 74 double pitch; 75 SoundSampleReadyListener * listener; 76 }; 77 78 /** 79 * A Voice Synthesizer using FLITE+HTS 80 */ 81 class FLITEVoiceSynthesizer : public VoiceSynthesizer { 82 public: 83 84 typedef enum { 85 CMU_US_ARCTIC_SLT = 0, 86 CSTR_UK_FEMALE, 87 88 VOICE_UNKNOWN // keep this at the end 89 } voice_t; 90 91 static std::string getVoicePath( voice_t voice ); 92 static std::string getVoicePath( const std::string & voice ); 93 94 FLITEVoiceSynthesizer( const std::string & voice ); 95 ~FLITEVoiceSynthesizer(); 96 virtual SGSoundSample * synthesize( const std::string & text, double volume, double speed, double pitch ); 97 98 virtual void synthesize( SynthesizeRequest & request ); 99 private: 100 struct _Flite_HTS_Engine * _engine; 101 102 class WorkerThread; 103 WorkerThread * _worker; 104 105 typedef SGBlockingQueue<SynthesizeRequest> SynthesizeRequestList; 106 SynthesizeRequestList _requests; 107 108 double _volume; 109 }; 110 111 #endif /* VOICESYNTHESIZER_HXX_ */ 112