From c04406d75aa5db9e1f969416f3904e8fef06b8ae Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 19 Feb 2017 09:54:57 -0800 Subject: [PATCH] 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. --- src/Sound/VoiceSynthesizer.cxx | 25 ++++++++++++++++++++++--- src/Sound/VoiceSynthesizer.hxx | 4 ++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/Sound/VoiceSynthesizer.cxx b/src/Sound/VoiceSynthesizer.cxx index 5871716d0..ef51c3b5b 100644 --- a/src/Sound/VoiceSynthesizer.cxx +++ b/src/Sound/VoiceSynthesizer.cxx @@ -23,7 +23,8 @@ #include #include #include -#include +#include + #include using std::string; @@ -33,7 +34,8 @@ static const char * VOICE_FILES[] = { "cstr_uk_female-1.0.htsvoice" }; -class FLITEVoiceSynthesizer::WorkerThread: public OpenThreads::Thread { +class FLITEVoiceSynthesizer::WorkerThread : public SGThread +{ public: WorkerThread(FLITEVoiceSynthesizer * synthesizer) : _synthesizer(synthesizer) @@ -48,6 +50,13 @@ void FLITEVoiceSynthesizer::WorkerThread::run() { for (;;) { 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) { SGSharedPtr sample = _synthesizer->synthesize(request.text, request.volume, request.speed, request.pitch); 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 ) { if( voice < 0 || voice >= VOICE_UNKNOWN ) return string(""); @@ -86,8 +103,10 @@ FLITEVoiceSynthesizer::FLITEVoiceSynthesizer(const std::string & voice) FLITEVoiceSynthesizer::~FLITEVoiceSynthesizer() { - _worker->cancel(); + // push the special marker value + _requests.push(SynthesizeRequest::cancelThreadRequest()); _worker->join(); + SG_LOG(SG_SOUND, SG_INFO, "FLITE synthesis thread joined OK"); Flite_HTS_Engine_clear(_engine); } diff --git a/src/Sound/VoiceSynthesizer.hxx b/src/Sound/VoiceSynthesizer.hxx index 246085d9b..cce9da2be 100644 --- a/src/Sound/VoiceSynthesizer.hxx +++ b/src/Sound/VoiceSynthesizer.hxx @@ -64,6 +64,10 @@ struct SynthesizeRequest { return *this; } + // return a special marker request used to indicate the synthesis thread + // should be exited. + static SynthesizeRequest cancelThreadRequest(); + std::string text; double speed; double volume;