From 3591bd8631e98ea12048262448a945bef9fd6843 Mon Sep 17 00:00:00 2001 From: Julian Smith Date: Wed, 21 Oct 2020 23:56:01 +0100 Subject: [PATCH] Be able to control atis speech pitch, volume and speed. Uses these properties: /sim/atis/speed /sim/atis/volume /sim/atis/pitch Values 1.0 behave as default. Other values are used to multiply default settings. Changes don't take affect immediately. But changing com frequency seems to often cause an update which will then pick up the new values. --- src/Instrumentation/commradio.cxx | 48 +++++++++++++++++++++++++------ src/Sound/VoiceSynthesizer.cxx | 4 +-- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/Instrumentation/commradio.cxx b/src/Instrumentation/commradio.cxx index 2ac6e1104..e882e65c1 100644 --- a/src/Instrumentation/commradio.cxx +++ b/src/Instrumentation/commradio.cxx @@ -81,6 +81,9 @@ private: AtisSpeaker::AtisSpeaker() { _synthesizeRequest.listener = this; + if (!fgHasNode("/sim/atis/speed")) fgSetDouble("/sim/atis/speed", 1); + if (!fgHasNode("/sim/atis/pitch")) fgSetDouble("/sim/atis/pitch", 1); + if (!fgHasNode("/sim/atis/enabled")) fgSetBool("/sim/atis/enabled", true); } AtisSpeaker::~AtisSpeaker() @@ -115,9 +118,9 @@ void AtisSpeaker::valueChanged(SGPropertyNode * node) hash += *i; } - _synthesizeRequest.speed = (hash % 16) / 16.0; - _synthesizeRequest.pitch = (hash % 16) / 16.0; - + _synthesizeRequest.speed = (hash % 16) / 16.0 * fgGetDouble("/sim/atis/speed", 1); + _synthesizeRequest.pitch = (hash % 16) / 16.0 * fgGetDouble("/sim/atis/pitch", 1); + if( starts_with( _stationId, "K" ) || starts_with( _stationId, "C" ) || starts_with( _stationId, "P" ) ) { voice = FLITEVoiceSynthesizer::getVoicePath("cmu_us_arctic_slt"); @@ -133,7 +136,7 @@ void AtisSpeaker::valueChanged(SGPropertyNode * node) FGSoundManager * smgr = globals->get_subsystem(); assert(smgr != NULL); - SG_LOG(SG_INSTR, SG_DEBUG,"AtisSpeaker voice is " << voice ); + SG_LOG(SG_INSTR, SG_DEBUG,"node->getPath()=" << node->getPath() << " AtisSpeaker voice is " << voice ); FLITEVoiceSynthesizer * synthesizer = dynamic_cast(smgr->getSynthesizer(voice)); synthesizer->synthesize(_synthesizeRequest); @@ -484,6 +487,10 @@ private: PropertyObject _addNoise; PropertyObject _cutoffSignalQuality; + SGPropertyNode_ptr _atis_enabled_node; + bool _atis_enabled_prev; + SGSharedPtr _atis_sample; + std::string _soundPrefix; void stopAudio(); void updateAudio(); @@ -514,6 +521,8 @@ void CommRadioImpl::bind() _volume_norm = PropertyObject(_rootNode->getNode("volume", true)); _atis = PropertyObject(_rootNode->getNode("atis", true)); + if (!fgHasNode("/sim/atis/enabled")) fgSetBool("/sim/atis/enabled", true); + _atis_enabled_node = fgGetNode("/sim/atis/enabled"); _addNoise = PropertyObject(_rootNode->getNode("add-noise", true)); _cutoffSignalQuality = PropertyObject(_rootNode->getNode("cutoff-signal-quality", true)); @@ -682,15 +691,38 @@ void CommRadioImpl::updateAudio() noiseSample = noise; } + bool atis_enabled = _atis_enabled_node->getBoolValue(); + int atis_delta = 0; + if (atis_enabled and !_atis_enabled_prev) atis_delta = 1; + if (!atis_enabled and _atis_enabled_prev) atis_delta = -1; + if (_atisSpeaker.hasSpokenAtis()) { // the speaker has created a new atis sample // remove previous atis sample _sampleGroup->remove(atisRef); - - SGSharedPtr sample = _atisSpeaker.getSpokenAtis(); - _sampleGroup->add(sample, atisRef); - _sampleGroup->play_looped(atisRef); + if (!atis_delta and atis_enabled) atis_delta = 1; } + if (atis_delta == 1) { + // Start play of atis text. We store the most recent sample in _atis_sample + // so that we can resume if /sim/atis/enabled is changed from false to + // true. + SGSharedPtr sample = _atisSpeaker.getSpokenAtis(); + if (sample) _atis_sample = sample; + else sample = _atis_sample; + if (sample) { + SG_LOG(SG_INSTR, SG_DEBUG, "starting looped play of atis sample."); + _sampleGroup->add(sample, atisRef); + _sampleGroup->play_looped(atisRef); + } + else { + SG_LOG(SG_INSTR, SG_DEBUG, "no atis sample available"); + } + } + if (atis_delta == -1) { + // Stop play of atis text. + _sampleGroup->remove(atisRef); + } + _atis_enabled_prev = atis_enabled; // adjust volumes const bool doSquelch = (_signalQuality_norm < _cutoffSignalQuality); diff --git a/src/Sound/VoiceSynthesizer.cxx b/src/Sound/VoiceSynthesizer.cxx index dd8316299..be1ecae85 100644 --- a/src/Sound/VoiceSynthesizer.cxx +++ b/src/Sound/VoiceSynthesizer.cxx @@ -112,8 +112,8 @@ FLITEVoiceSynthesizer::~FLITEVoiceSynthesizer() SGSoundSample * FLITEVoiceSynthesizer::synthesize(const std::string & text, double volume, double speed, double pitch ) { SG_CLAMP_RANGE( volume, 0.0, 1.0 ); - SG_CLAMP_RANGE( speed, 0.0, 1.0 ); - SG_CLAMP_RANGE( pitch, 0.0, 1.0 ); + SG_CLAMP_RANGE( speed, 0.0, 10.0 ); + SG_CLAMP_RANGE( pitch, 0.0, 10.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 );