From 36fc9790ed6a8f784528d47b60df2408fe0aa9bb Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Wed, 7 May 2014 10:34:04 +0200 Subject: [PATCH] atis voice: add some variation in pitch and speed --- src/Instrumentation/commradio.cxx | 22 +++++++++++++++++++++- src/Sound/VoiceSynthesizer.cxx | 11 +++++++++-- src/Sound/VoiceSynthesizer.hxx | 8 +++++--- src/Sound/flitevoice.cxx | 2 +- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/Instrumentation/commradio.cxx b/src/Instrumentation/commradio.cxx index 786cb23a6..dd36acaa4 100644 --- a/src/Instrumentation/commradio.cxx +++ b/src/Instrumentation/commradio.cxx @@ -69,9 +69,16 @@ public: { return _spokenAtis.pop(); } + + void setStationId(const string & stationId) + { + _stationId = stationId; + } + private: SynthesizeRequest _synthesizeRequest; SGLockedQueue > _spokenAtis; + string _stationId; }; AtisSpeaker::AtisSpeaker() @@ -93,6 +100,18 @@ void AtisSpeaker::valueChanged(SGPropertyNode * node) _synthesizeRequest.text = newText; + 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 + + string::iterator i = _stationId.end() - 1; + if( i != _stationId.begin() ) + --i; + + _synthesizeRequest.speed = ((*i) % 16) / 16.0; + _synthesizeRequest.pitch = ((*i) % 16) / 16.0; + } + FGSoundManager * smgr = dynamic_cast(globals->get_soundmgr()); assert(smgr != NULL); @@ -508,11 +527,12 @@ void CommRadioImpl::update(double dt) _heightAboveStation_ft = SGMiscd::max(0.0, position.getElevationFt() - _commStationForFrequency->airport()->elevation()); - _signalQuality_norm = _signalQualityComputer->computeSignalQuality(_slantDistance_m * SG_METER_TO_NM ); + _signalQuality_norm = _signalQualityComputer->computeSignalQuality(_slantDistance_m * SG_METER_TO_NM); _stationType = _commStationForFrequency->nameForType(_commStationForFrequency->type()); _stationName = _commStationForFrequency->ident(); _airportId = _commStationForFrequency->airport()->getId(); + _atisSpeaker.setStationId(_airportId); switch (_commStationForFrequency->type()) { case FGPositioned::FREQ_ATIS: case FGPositioned::FREQ_AWOS: { diff --git a/src/Sound/VoiceSynthesizer.cxx b/src/Sound/VoiceSynthesizer.cxx index 1db741108..66100217a 100644 --- a/src/Sound/VoiceSynthesizer.cxx +++ b/src/Sound/VoiceSynthesizer.cxx @@ -19,6 +19,7 @@ #include "VoiceSynthesizer.hxx" #include
#include
+#include #include #include #include @@ -67,7 +68,7 @@ void FLITEVoiceSynthesizer::WorkerThread::run() for (;;) { SynthesizeRequest request = _synthesizer->_requests.pop(); if ( NULL != request.listener) { - SGSharedPtr sample = _synthesizer->synthesize(request.text); + SGSharedPtr sample = _synthesizer->synthesize(request.text, request.volume, request.speed, request.pitch); request.listener->SoundSampleReady( sample ); } } @@ -95,10 +96,16 @@ FLITEVoiceSynthesizer::~FLITEVoiceSynthesizer() Flite_HTS_Engine_clear(_engine); } -SGSoundSample * FLITEVoiceSynthesizer::synthesize(const std::string & text) +SGSoundSample * FLITEVoiceSynthesizer::synthesize(const std::string & text, double volume, double speed, double pitch ) { ScopedTempfile scratch(_keepScratchFile); + + SG_CLAMP_RANGE( volume, 0.0, 1.0 ); + SG_CLAMP_RANGE( speed, 0.0, 1.0 ); + SG_CLAMP_RANGE( pitch, 0.0, 1.0 ); HTS_Engine_set_volume( &_engine->engine, _volume ); + HTS_Engine_set_speed( &_engine->engine, 0.8 + 0.4 * speed ); + HTS_Engine_add_half_tone(&_engine->engine, -4.0 + 8.0 * pitch ); if ( FALSE == Flite_HTS_Engine_synthesize(_engine, text.c_str(), scratch.getName())) return NULL; diff --git a/src/Sound/VoiceSynthesizer.hxx b/src/Sound/VoiceSynthesizer.hxx index 375c1f1a0..e6e36fab0 100644 --- a/src/Sound/VoiceSynthesizer.hxx +++ b/src/Sound/VoiceSynthesizer.hxx @@ -31,7 +31,7 @@ struct _Flite_HTS_Engine; class VoiceSynthesizer { public: virtual ~VoiceSynthesizer() {}; - virtual SGSoundSample * synthesize( const std::string & text ) = 0; + virtual SGSoundSample * synthesize( const std::string & text, double volume, double speed, double pitch ) = 0; }; class SoundSampleReadyListener { @@ -42,7 +42,9 @@ public: struct SynthesizeRequest { SynthesizeRequest() { - speed = volume = pitch = 1.0; + speed = 0.5; + volume = 1.0; + pitch = 0.5; listener = NULL; } SynthesizeRequest( const SynthesizeRequest & other ) { @@ -76,7 +78,7 @@ class FLITEVoiceSynthesizer : public VoiceSynthesizer { public: FLITEVoiceSynthesizer( const std::string & voice ); ~FLITEVoiceSynthesizer(); - virtual SGSoundSample * synthesize( const std::string & text ); + virtual SGSoundSample * synthesize( const std::string & text, double volume, double speed, double pitch ); virtual void synthesize( SynthesizeRequest & request ); private: diff --git a/src/Sound/flitevoice.cxx b/src/Sound/flitevoice.cxx index f554c2e8e..bc70b5f2e 100644 --- a/src/Sound/flitevoice.cxx +++ b/src/Sound/flitevoice.cxx @@ -61,7 +61,7 @@ void FGFLITEVoice::speak(const string & msg) string s = simgear::strutils::strip( msg ); if( false == s.empty() ) { - SGSoundSample * sample = _synthesizer->synthesize( msg ); + SGSoundSample * sample = _synthesizer->synthesize( msg, 1.0, 0.5, 0.5 ); _sgr->add(sample, "flite"); _sgr->set_volume(1.0); _sgr->resume(); -- 2.39.5