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<TalkEntry>* list,int wavtri
//!
TalkGenerator::Status TalkGenerator::encodeList(QList<TalkEntry>* 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<TalkEntry>* 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<TalkEntry>* 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<void> encFutureWatcher;
+ void encFailEntry(const TalkEntry& entry);
+
Status voiceList(QList<TalkEntry>* list,int wavetrimth);
Status encodeList(QList<TalkEntry>* list);
+ static void encEntryPoint(TalkEntry& entry);
+
TTSBase* m_tts;
EncBase* m_enc;