More AtisSpeaker variations
Also hide the voice installation path from the user of the VoiceSynthesizer
This commit is contained in:
parent
54f954fd02
commit
ffe6c39a1d
3 changed files with 52 additions and 19 deletions
|
@ -75,27 +75,14 @@ public:
|
|||
_stationId = stationId;
|
||||
}
|
||||
|
||||
void setVoice(const string & voice)
|
||||
{
|
||||
_voice = voice;
|
||||
}
|
||||
|
||||
const string & getVoice() const
|
||||
{
|
||||
return _voice;
|
||||
}
|
||||
|
||||
private:
|
||||
SynthesizeRequest _synthesizeRequest;
|
||||
SGLockedQueue<SGSharedPtr<SGSoundSample> > _spokenAtis;
|
||||
string _stationId;
|
||||
string _voice;
|
||||
};
|
||||
|
||||
AtisSpeaker::AtisSpeaker()
|
||||
:
|
||||
_voice("/ATC/cmu_us_arctic_slt.htsvoice")
|
||||
// _voice("/ATC/cstr_uk_female-1.0.htsvoice")
|
||||
{
|
||||
_synthesizeRequest.listener = this;
|
||||
}
|
||||
|
@ -107,29 +94,42 @@ AtisSpeaker::~AtisSpeaker()
|
|||
void AtisSpeaker::valueChanged(SGPropertyNode * node)
|
||||
{
|
||||
if (!fgGetBool("/sim/sound/working", false))
|
||||
return;
|
||||
return;
|
||||
|
||||
string newText = node->getStringValue();
|
||||
if (_synthesizeRequest.text == newText) return;
|
||||
|
||||
_synthesizeRequest.text = newText;
|
||||
|
||||
string voice = "cmu_us_arctic_slt";
|
||||
|
||||
if (!_stationId.empty()) {
|
||||
// lets play a bit with the voice so not every airports atis sounds alike
|
||||
// but every atis of an airport has the same voice
|
||||
|
||||
// create a simple hash from the last two letters of the airport's id
|
||||
unsigned char hash = 0;
|
||||
string::iterator i = _stationId.end() - 1;
|
||||
if( i != _stationId.begin() )
|
||||
--i;
|
||||
hash += *i;
|
||||
|
||||
_synthesizeRequest.speed = ((*i) % 16) / 16.0;
|
||||
_synthesizeRequest.pitch = ((*i) % 16) / 16.0;
|
||||
if( i != _stationId.begin() ) {
|
||||
--i;
|
||||
hash += *i;
|
||||
}
|
||||
|
||||
_synthesizeRequest.speed = (hash % 16) / 16.0;
|
||||
_synthesizeRequest.pitch = (hash % 16) / 16.0;
|
||||
|
||||
// pick a voice
|
||||
voice = FLITEVoiceSynthesizer::getVoicePath(
|
||||
static_cast<FLITEVoiceSynthesizer::voice_t>(hash % FLITEVoiceSynthesizer::VOICE_UNKNOWN) );
|
||||
}
|
||||
|
||||
|
||||
FGSoundManager * smgr = dynamic_cast<FGSoundManager*>(globals->get_soundmgr());
|
||||
assert(smgr != NULL);
|
||||
|
||||
string voice = globals->get_fg_root() + _voice;
|
||||
SG_LOG(SG_INSTR,SG_INFO,"AtisSpeaker voice is " << voice );
|
||||
FLITEVoiceSynthesizer * synthesizer = dynamic_cast<FLITEVoiceSynthesizer*>(smgr->getSynthesizer(voice));
|
||||
|
||||
synthesizer->synthesize(_synthesizeRequest);
|
||||
|
|
|
@ -26,6 +26,13 @@
|
|||
#include <OpenThreads/Thread>
|
||||
#include <flite_hts_engine.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
static const char * VOICE_FILES[] = {
|
||||
"cmu_us_arctic_slt.htsvoice",
|
||||
"cstr_uk_female-1.0.htsvoice"
|
||||
};
|
||||
|
||||
class FLITEVoiceSynthesizer::WorkerThread: public OpenThreads::Thread {
|
||||
public:
|
||||
WorkerThread(FLITEVoiceSynthesizer * synthesizer)
|
||||
|
@ -48,6 +55,21 @@ void FLITEVoiceSynthesizer::WorkerThread::run()
|
|||
}
|
||||
}
|
||||
|
||||
string FLITEVoiceSynthesizer::getVoicePath( voice_t voice )
|
||||
{
|
||||
if( voice < 0 || voice >= VOICE_UNKNOWN ) return string("");
|
||||
string voicePath = globals->get_fg_root() + "/ATC/" + VOICE_FILES[voice];
|
||||
return voicePath;
|
||||
}
|
||||
|
||||
string FLITEVoiceSynthesizer::getVoicePath( const string & voice )
|
||||
{
|
||||
if( voice == "cmu_us_arctic_slt" ) return getVoicePath(CMU_US_ARCTIC_SLT);
|
||||
if( voice == "cstr_uk_female" ) return getVoicePath(CSTR_UK_FEMALE);
|
||||
return getVoicePath(VOICE_UNKNOWN);
|
||||
}
|
||||
|
||||
|
||||
void FLITEVoiceSynthesizer::synthesize( SynthesizeRequest & request)
|
||||
{
|
||||
_requests.push(request);
|
||||
|
|
|
@ -76,6 +76,17 @@ struct SynthesizeRequest {
|
|||
*/
|
||||
class FLITEVoiceSynthesizer : public VoiceSynthesizer {
|
||||
public:
|
||||
|
||||
typedef enum {
|
||||
CMU_US_ARCTIC_SLT = 0,
|
||||
CSTR_UK_FEMALE,
|
||||
|
||||
VOICE_UNKNOWN // keep this at the end
|
||||
} voice_t;
|
||||
|
||||
static std::string getVoicePath( voice_t voice );
|
||||
static std::string getVoicePath( const std::string & voice );
|
||||
|
||||
FLITEVoiceSynthesizer( const std::string & voice );
|
||||
~FLITEVoiceSynthesizer();
|
||||
virtual SGSoundSample * synthesize( const std::string & text, double volume, double speed, double pitch );
|
||||
|
|
Loading…
Add table
Reference in a new issue