1
0
Fork 0

Clean shutdown+join of FLITE synthesis threads.

use a marker value to wake the blocking queue, and allow the thread
loop to terminate cleanly, before calling join() from the parent
thread.
This commit is contained in:
James Turner 2017-02-19 09:54:57 -08:00
parent 989ebf73a6
commit c04406d75a
2 changed files with 26 additions and 3 deletions

View file

@ -23,7 +23,8 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/sound/readwav.hxx> #include <simgear/sound/readwav.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <OpenThreads/Thread> #include <simgear/threads/SGThread.hxx>
#include <flite_hts_engine.h> #include <flite_hts_engine.h>
using std::string; using std::string;
@ -33,7 +34,8 @@ static const char * VOICE_FILES[] = {
"cstr_uk_female-1.0.htsvoice" "cstr_uk_female-1.0.htsvoice"
}; };
class FLITEVoiceSynthesizer::WorkerThread: public OpenThreads::Thread { class FLITEVoiceSynthesizer::WorkerThread : public SGThread
{
public: public:
WorkerThread(FLITEVoiceSynthesizer * synthesizer) WorkerThread(FLITEVoiceSynthesizer * synthesizer)
: _synthesizer(synthesizer) : _synthesizer(synthesizer)
@ -48,6 +50,13 @@ void FLITEVoiceSynthesizer::WorkerThread::run()
{ {
for (;;) { for (;;) {
SynthesizeRequest request = _synthesizer->_requests.pop(); SynthesizeRequest request = _synthesizer->_requests.pop();
// marker value indicating termination requested
if ((request.speed < 0.0) && (request.volume < 0.0)) {
SG_LOG(SG_SOUND, SG_INFO, "FLITE synthesis thread exiting");
return;
}
if ( NULL != request.listener) { if ( NULL != request.listener) {
SGSharedPtr<SGSoundSample> sample = _synthesizer->synthesize(request.text, request.volume, request.speed, request.pitch); SGSharedPtr<SGSoundSample> sample = _synthesizer->synthesize(request.text, request.volume, request.speed, request.pitch);
request.listener->SoundSampleReady( sample ); request.listener->SoundSampleReady( sample );
@ -55,6 +64,14 @@ void FLITEVoiceSynthesizer::WorkerThread::run()
} }
} }
SynthesizeRequest SynthesizeRequest::cancelThreadRequest()
{
SynthesizeRequest marker;
marker.volume = -999.0;
marker.speed = -999.0;
return marker;
}
string FLITEVoiceSynthesizer::getVoicePath( voice_t voice ) string FLITEVoiceSynthesizer::getVoicePath( voice_t voice )
{ {
if( voice < 0 || voice >= VOICE_UNKNOWN ) return string(""); if( voice < 0 || voice >= VOICE_UNKNOWN ) return string("");
@ -86,8 +103,10 @@ FLITEVoiceSynthesizer::FLITEVoiceSynthesizer(const std::string & voice)
FLITEVoiceSynthesizer::~FLITEVoiceSynthesizer() FLITEVoiceSynthesizer::~FLITEVoiceSynthesizer()
{ {
_worker->cancel(); // push the special marker value
_requests.push(SynthesizeRequest::cancelThreadRequest());
_worker->join(); _worker->join();
SG_LOG(SG_SOUND, SG_INFO, "FLITE synthesis thread joined OK");
Flite_HTS_Engine_clear(_engine); Flite_HTS_Engine_clear(_engine);
} }

View file

@ -64,6 +64,10 @@ struct SynthesizeRequest {
return *this; return *this;
} }
// return a special marker request used to indicate the synthesis thread
// should be exited.
static SynthesizeRequest cancelThreadRequest();
std::string text; std::string text;
double speed; double speed;
double volume; double volume;