atis voice: add some variation in pitch and speed
This commit is contained in:
parent
c6371c4152
commit
36fc9790ed
4 changed files with 36 additions and 7 deletions
|
@ -69,9 +69,16 @@ public:
|
|||
{
|
||||
return _spokenAtis.pop();
|
||||
}
|
||||
|
||||
void setStationId(const string & stationId)
|
||||
{
|
||||
_stationId = stationId;
|
||||
}
|
||||
|
||||
private:
|
||||
SynthesizeRequest _synthesizeRequest;
|
||||
SGLockedQueue<SGSharedPtr<SGSoundSample> > _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<FGSoundManager*>(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: {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "VoiceSynthesizer.hxx"
|
||||
#include <Main/globals.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <simgear/sg_inlines.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/sound/readwav.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
@ -67,7 +68,7 @@ void FLITEVoiceSynthesizer::WorkerThread::run()
|
|||
for (;;) {
|
||||
SynthesizeRequest request = _synthesizer->_requests.pop();
|
||||
if ( NULL != request.listener) {
|
||||
SGSharedPtr<SGSoundSample> sample = _synthesizer->synthesize(request.text);
|
||||
SGSharedPtr<SGSoundSample> 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;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue