diff --git a/rbutil/rbutilqt/base/talkgenerator.cpp b/rbutil/rbutilqt/base/talkgenerator.cpp index 5c0f8e9..6d566e2 100644 --- a/rbutil/rbutilqt/base/talkgenerator.cpp +++ b/rbutil/rbutilqt/base/talkgenerator.cpp @@ -22,7 +22,7 @@ #include "systeminfo.h" #include "wavtrim.h" -TalkGenerator::TalkGenerator(QObject* parent): QObject(parent) +TalkGenerator::TalkGenerator(QObject* parent): QObject(parent), encFutureWatcher(this) { } @@ -184,50 +184,69 @@ TalkGenerator::Status TalkGenerator::voiceList(QList* list,int wavtri //! TalkGenerator::Status TalkGenerator::encodeList(QList* list) { - QStringList dublicates; + QStringList duplicates; - int progressMax = list->size(); - int m_progress = 0; - emit logProgress(m_progress,progressMax); + int itemsCount = list->size(); + emit logProgress(0, itemsCount); - for(int i=0; i < list->size(); i++) + /* Do some preprocessing and remove the invalid entries. As far as I can see, + * this list is not going to be used anywhere else, so we might as well butcher it*/ + for (int idx=0; idx < itemsCount; idx++) { - if(m_abort) + if(list->at(idx).voiced == false) { - emit logItem(tr("Encoding aborted"), LOGERROR); - return eERROR; + qDebug() << "non voiced entry" << list->at(idx).toSpeak <<"detected"; + list->removeAt(idx); + itemsCount--; + idx--; + continue; } - - //skip non-voiced entrys - if(list->at(i).voiced == false) + if(duplicates.contains(list->at(idx).talkfilename)) { - qDebug() << "non voiced entry" << list->at(i).toSpeak <<"detected"; - emit logProgress(++m_progress,progressMax); + list->removeAt(idx); + itemsCount--; + idx--; continue; } - //skip dublicates - if(!dublicates.contains(list->at(i).talkfilename)) - dublicates.append(list->at(i).talkfilename); + duplicates.append(list->at(idx).talkfilename); + (*list)[idx].encoder = m_enc; + (*list)[idx].generator = this; + } + + connect(&encFutureWatcher, SIGNAL(progressValueChanged(int)), this, SLOT(encProgress(int))); + encFutureWatcher.setFuture(QtConcurrent::map(*list, &TalkGenerator::encEntryPoint)); + + /* We use this loop as an equivalent to encFutureWatcher.waitForFinished() + * since the latter blocks all events */ + while (encFutureWatcher.isRunning()) + QCoreApplication::processEvents(QEventLoop::AllEvents); + + if (encFutureWatcher.isCanceled()) + return eERROR; else - { - qDebug() << "dublicate skipped"; - (*list)[i].encoded = true; - emit logProgress(++m_progress,progressMax); - continue; + return eOK; } - //encode entry - qDebug() << "encoding " << list->at(i).wavfilename << "to" << list->at(i).talkfilename; - if(!m_enc->encode(list->at(i).wavfilename,list->at(i).talkfilename)) +void TalkGenerator::encEntryPoint(TalkEntry& entry) { - emit logItem(tr("Encoding of %1 failed").arg(list->at(i).wavfilename), LOGERROR); - return eERROR; + bool res = entry.encoder->encode(entry.wavfilename, entry.talkfilename); + entry.encoded = res; + if (!entry.encoded) + entry.generator->encFailEntry(entry); + return; } - (*list)[i].encoded = true; - emit logProgress(++m_progress,progressMax); - QCoreApplication::processEvents(); + +void TalkGenerator::encProgress(int value) +{ + qDebug() << "[TalkGen] Progress at " << value; + emit logProgress(value, encFutureWatcher.progressMaximum()); } - return eOK; + +void TalkGenerator::encFailEntry(const TalkEntry& entry) +{ + encFutureWatcher.cancel(); + encFutureWatcher.waitForFinished(); + emit logItem(tr("Encoding of %1 failed").arg(entry.wavfilename), LOGERROR); } //! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position @@ -235,5 +254,12 @@ TalkGenerator::Status TalkGenerator::encodeList(QList* list) void TalkGenerator::abort() { m_abort = true; + + if (encFutureWatcher.isRunning()) + { + encFutureWatcher.cancel(); + encFutureWatcher.waitForFinished(); + emit logItem(tr("Encoding aborted"), LOGERROR); + } } diff --git a/rbutil/rbutilqt/base/talkgenerator.h b/rbutil/rbutilqt/base/talkgenerator.h index b139c18..7b54b7b 100644 --- a/rbutil/rbutilqt/base/talkgenerator.h +++ b/rbutil/rbutilqt/base/talkgenerator.h @@ -49,14 +49,22 @@ public: QString target; bool voiced; bool encoded; + + /* We need the following members because + * 1) the QtConcurrent entry points are all static methods (and we need to communicate + * with the TalkGenerator + * 2) we are not guaranteed to go through the list in any particular order, + * so we can't use the progress slot for error checking */ + EncBase* encoder; + TalkGenerator* generator; }; TalkGenerator(QObject* parent); - Status process(QList* list,int wavtrimth = -1); public slots: void abort(); + void encProgress(int value); signals: void done(bool); @@ -64,9 +72,14 @@ signals: void logProgress(int, int); //! set progress bar. private: + QFutureWatcher encFutureWatcher; + void encFailEntry(const TalkEntry& entry); + Status voiceList(QList* list,int wavetrimth); Status encodeList(QList* list); + static void encEntryPoint(TalkEntry& entry); + TTSBase* m_tts; EncBase* m_enc;