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:
parent
989ebf73a6
commit
c04406d75a
2 changed files with 26 additions and 3 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue