summaryrefslogtreecommitdiffstats
path: root/rbutil/rbutilqt
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2011-10-01 19:48:58 +0000
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2011-10-01 19:48:58 +0000
commit4f56b50df45cf81370c3a29bd443b91cf5fca1b0 (patch)
tree92b105d056a47401949c9db6b5529570a63cb3f9 /rbutil/rbutilqt
parent7f2defc453045e037cccf50456753d310c7d7e88 (diff)
downloadrockbox-4f56b50df45cf81370c3a29bd443b91cf5fca1b0.tar.gz
rockbox-4f56b50df45cf81370c3a29bd443b91cf5fca1b0.tar.bz2
rockbox-4f56b50df45cf81370c3a29bd443b91cf5fca1b0.zip
Voicefile generation: implement string corrections.
Voicefile generation now can correct strings for the TTS system similar to what voice.pl does. The current implementation has some limitations: - only implemented for voicefile creation. - the corrections file is built in and can't get changed. - string corrections can be disabled in the configuration dialog. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30628 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'rbutil/rbutilqt')
-rw-r--r--rbutil/rbutilqt/base/rbsettings.cpp1
-rw-r--r--rbutil/rbutilqt/base/rbsettings.h1
-rw-r--r--rbutil/rbutilqt/base/talkfile.cpp1
-rw-r--r--rbutil/rbutilqt/base/talkgenerator.cpp81
-rw-r--r--rbutil/rbutilqt/base/talkgenerator.h11
-rw-r--r--rbutil/rbutilqt/base/voicefile.cpp7
-rw-r--r--rbutil/rbutilqt/base/voicefile.h5
-rw-r--r--rbutil/rbutilqt/configure.cpp4
-rw-r--r--rbutil/rbutilqt/configurefrm.ui7
-rw-r--r--rbutil/rbutilqt/rbutilqt.qrc9
10 files changed, 119 insertions, 8 deletions
diff --git a/rbutil/rbutilqt/base/rbsettings.cpp b/rbutil/rbutilqt/base/rbsettings.cpp
index 592e5c1148..29c893c66c 100644
--- a/rbutil/rbutilqt/base/rbsettings.cpp
+++ b/rbutil/rbutilqt/base/rbsettings.cpp
@@ -48,6 +48,7 @@ const static struct {
#else
{ RbSettings::Tts, "tts", "espeak" },
#endif
+ { RbSettings::UseTtsCorrections, "use_tts_corrections", "true" },
{ RbSettings::LastTalkedFolder, "last_talked_folder", "" },
{ RbSettings::VoiceLanguage, "voicelanguage", "" },
{ RbSettings::TtsLanguage, ":tts:/language", "" },
diff --git a/rbutil/rbutilqt/base/rbsettings.h b/rbutil/rbutilqt/base/rbsettings.h
index 277b2197d1..ab001c4916 100644
--- a/rbutil/rbutilqt/base/rbsettings.h
+++ b/rbutil/rbutilqt/base/rbsettings.h
@@ -42,6 +42,7 @@ class RbSettings : public QObject
Platform,
Language,
Tts,
+ UseTtsCorrections,
LastTalkedFolder,
VoiceLanguage,
TtsLanguage,
diff --git a/rbutil/rbutilqt/base/talkfile.cpp b/rbutil/rbutilqt/base/talkfile.cpp
index 3813912347..badb77f42b 100644
--- a/rbutil/rbutilqt/base/talkfile.cpp
+++ b/rbutil/rbutilqt/base/talkfile.cpp
@@ -50,6 +50,7 @@ bool TalkFileCreator::createTalkFiles()
// generate entries
{
TalkGenerator generator(this);
+ // no string corrections yet: do not set language for TalkGenerator.
connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool)));
connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int)));
connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int)));
diff --git a/rbutil/rbutilqt/base/talkgenerator.cpp b/rbutil/rbutilqt/base/talkgenerator.cpp
index 9b0cbf4066..4dffe69a42 100644
--- a/rbutil/rbutilqt/base/talkgenerator.cpp
+++ b/rbutil/rbutilqt/base/talkgenerator.cpp
@@ -25,6 +25,7 @@
TalkGenerator::TalkGenerator(QObject* parent): QObject(parent), encFutureWatcher(this), ttsFutureWatcher(this)
{
m_userAborted = false;
+ m_lang = "";
}
//! \brief Creates Talkfiles.
@@ -113,6 +114,11 @@ TalkGenerator::Status TalkGenerator::voiceList(QList<TalkEntry>* list,int wavtri
(*list)[i].refs.tts = m_tts;
(*list)[i].refs.wavtrim = wavtrimth;
(*list)[i].refs.generator = this;
+ // enable voice corrections only if a language is set.
+ if(!m_lang.isEmpty()) {
+ QString s = (*list)[i].toSpeak;
+ (*list)[i].toSpeak = correctString(s);
+ }
// skip duplicated wav entries
if(!duplicates.contains(list->at(i).wavfilename))
@@ -247,7 +253,7 @@ TalkGenerator::Status TalkGenerator::encodeList(QList<TalkEntry>* list)
TalkGenerators.*/
}
- connect(&encFutureWatcher, SIGNAL(progressValueChanged(int)),
+ connect(&encFutureWatcher, SIGNAL(progressValueChanged(int)),
this, SLOT(encProgress(int)));
encFutureWatcher.setFuture(QtConcurrent::map(*list, &TalkGenerator::encEntryPoint));
@@ -302,3 +308,76 @@ void TalkGenerator::abort()
m_userAborted = true;
}
+QString TalkGenerator::correctString(QString s)
+{
+ QString corrected = s;
+ int i = 0;
+ int max = m_corrections.size();
+ while(i < max) {
+ corrected = corrected.replace(QRegExp(m_corrections.at(i).search,
+ m_corrections.at(i).modifier.contains("i")
+ ? Qt::CaseInsensitive : Qt::CaseSensitive),
+ m_corrections.at(i).replace);
+ i++;
+ }
+
+ if(corrected != s)
+ qDebug() << "[VoiceFileCreator] corrected string" << s << "to" << corrected;
+
+ return corrected;
+}
+
+
+void TalkGenerator::setLang(QString name)
+{
+ m_lang = name;
+
+ // re-initialize corrections list
+ m_corrections.clear();
+ QFile correctionsFile(":/builtin/voice-corrections.txt");
+ correctionsFile.open(QIODevice::ReadOnly);
+
+ QString engine = RbSettings::value(RbSettings::Tts).toString();
+ TTSBase* tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString());
+ QString vendor = tts->voiceVendor();
+ delete tts;
+
+ if(m_lang.isEmpty())
+ m_lang = "english";
+ qDebug() << "[TalkGenerator] building string corrections list for"
+ << m_lang << engine << vendor;
+ QTextStream stream(&correctionsFile);
+ while(!stream.atEnd()) {
+ QString line = stream.readLine();
+ if(line.startsWith(" ") || line.length() < 10)
+ continue;
+ // separator is first character
+ QString separator = line.at(0);
+ line.remove(0, 1);
+ QStringList items = line.split(separator);
+ // we need to have at least 6 separate entries.
+ if(items.size() < 6)
+ continue;
+
+ QRegExp re_lang(items.at(0));
+ QRegExp re_engine(items.at(1));
+ QRegExp re_vendor(items.at(2));
+ if(!re_lang.exactMatch(m_lang)) {
+ continue;
+ }
+ if(!re_vendor.exactMatch(vendor)) {
+ continue;
+ }
+ if(!re_engine.exactMatch(engine)) {
+ continue;
+ }
+ struct CorrectionItems co;
+ co.search = items.at(3);
+ co.replace = items.at(4);
+ // Qt uses backslash for back references, Perl uses dollar sign.
+ co.replace.replace(QRegExp("\\$(\\d+)"), "\\\\1");
+ co.modifier = items.at(5);
+ m_corrections.append(co);
+ }
+ correctionsFile.close();
+}
diff --git a/rbutil/rbutilqt/base/talkgenerator.h b/rbutil/rbutilqt/base/talkgenerator.h
index d0cbcd0af3..8617b27238 100644
--- a/rbutil/rbutilqt/base/talkgenerator.h
+++ b/rbutil/rbutilqt/base/talkgenerator.h
@@ -67,11 +67,13 @@ public:
TalkGenerator(QObject* parent);
Status process(QList<TalkEntry>* list,int wavtrimth = -1);
+ QString correctString(QString s);
public slots:
void abort();
void encProgress(int value);
void ttsProgress(int value);
+ void setLang(QString name);
signals:
void done(bool);
@@ -95,6 +97,15 @@ private:
bool m_ttsWarnings;
bool m_userAborted;
+ QString m_lang;
+
+ struct CorrectionItems
+ {
+ QString search;
+ QString replace;
+ QString modifier;
+ };
+ QList<struct CorrectionItems> m_corrections;
};
diff --git a/rbutil/rbutilqt/base/voicefile.cpp b/rbutil/rbutilqt/base/voicefile.cpp
index ce4596828f..04825f6d91 100644
--- a/rbutil/rbutilqt/base/voicefile.cpp
+++ b/rbutil/rbutilqt/base/voicefile.cpp
@@ -132,6 +132,7 @@ void VoiceFileCreator::downloadDone(bool error)
QString id, voice;
bool idfound = false;
bool voicefound=false;
+ bool useCorrection = RbSettings::value(RbSettings::UseTtsCorrections).toBool();
while (!in.atEnd())
{
QString line = in.readLine();
@@ -151,7 +152,8 @@ void VoiceFileCreator::downloadDone(bool error)
TalkGenerator::TalkEntry entry;
entry.toSpeak = voice;
entry.wavfilename = m_path + "/" + id + ".wav";
- entry.talkfilename = m_path + "/" + id + ".mp3"; //voicefont wants them with .mp3 extension
+ //voicefont wants them with .mp3 extension
+ entry.talkfilename = m_path + "/" + id + ".mp3";
entry.voiced = false;
entry.encoded = false;
if(id == "VOICE_PAUSE")
@@ -178,6 +180,9 @@ void VoiceFileCreator::downloadDone(bool error)
// generate files
{
TalkGenerator generator(this);
+ // set language for string correction. If not set no correction will be made.
+ if(useCorrection)
+ generator.setLang(m_lang);
connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool)));
connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int)));
connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int)));
diff --git a/rbutil/rbutilqt/base/voicefile.h b/rbutil/rbutilqt/base/voicefile.h
index 72f905e4f2..94aea6c643 100644
--- a/rbutil/rbutilqt/base/voicefile.h
+++ b/rbutil/rbutilqt/base/voicefile.h
@@ -40,7 +40,7 @@ public:
bool createVoiceFile();
void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; }
- void setLang(QString name){m_lang =name;}
+ void setLang(QString name) { m_lang = name; }
void setWavtrimThreshold(int th){m_wavtrimThreshold = th;}
public slots:
@@ -56,8 +56,9 @@ private slots:
void downloadDone(bool error);
private:
+
void cleanup();
-
+
HttpGet *getter;
QString filename; //the temporary file
QString m_mountpoint; //mountpoint of the device
diff --git a/rbutil/rbutilqt/configure.cpp b/rbutil/rbutilqt/configure.cpp
index 9e1978974f..4a6fb67a43 100644
--- a/rbutil/rbutilqt/configure.cpp
+++ b/rbutil/rbutilqt/configure.cpp
@@ -205,6 +205,7 @@ void Config::accept()
RbSettings::setValue(RbSettings::CacheOffline, ui.cacheOfflineMode->isChecked());
// tts settings
+ RbSettings::setValue(RbSettings::UseTtsCorrections, ui.ttsCorrections->isChecked());
int i = ui.comboTts->currentIndex();
RbSettings::setValue(RbSettings::Tts, ui.comboTts->itemData(i).toString());
@@ -288,6 +289,9 @@ void Config::setUserSettings()
ui.cacheDisable->setChecked(RbSettings::value(RbSettings::CacheDisabled).toBool());
ui.cacheOfflineMode->setChecked(RbSettings::value(RbSettings::CacheOffline).toBool());
updateCacheInfo(RbSettings::value(RbSettings::CachePath).toString());
+
+ // TTS tab
+ ui.ttsCorrections->setChecked(RbSettings::value(RbSettings::UseTtsCorrections).toBool());
}
diff --git a/rbutil/rbutilqt/configurefrm.ui b/rbutil/rbutilqt/configurefrm.ui
index 5d2de0647b..3c0afdc15b 100644
--- a/rbutil/rbutilqt/configurefrm.ui
+++ b/rbutil/rbutilqt/configurefrm.ui
@@ -449,6 +449,13 @@
</property>
</widget>
</item>
+ <item row="2" column="0" colspan="3">
+ <widget class="QCheckBox" name="ttsCorrections">
+ <property name="text">
+ <string>&amp;Use string corrections for TTS</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/rbutil/rbutilqt/rbutilqt.qrc b/rbutil/rbutilqt/rbutilqt.qrc
index 4138db78bd..28ab8fa370 100644
--- a/rbutil/rbutilqt/rbutilqt.qrc
+++ b/rbutil/rbutilqt/rbutilqt.qrc
@@ -1,12 +1,13 @@
<RCC>
- <qresource prefix="/" >
+ <qresource prefix="/">
<file>../../docs/CREDITS</file>
<file>../../docs/gpl-2.0.html</file>
</qresource>
- <qresource>
+ <qresource>
<file alias="builtin/VOICE_PAUSE.wav">../../tools/VOICE_PAUSE.wav</file>
+ <file alias="builtin/voice-corrections.txt">../../tools/voice-corrections.txt</file>
</qresource>
- <qresource prefix="/" >
+ <qresource prefix="/">
<file>icons/audio-input-microphone.png</file>
<file>icons/bootloader_btn.png</file>
<file>icons/dialog-error.png</file>
@@ -36,7 +37,7 @@
<file>icons/wizard.jpg</file>
<file alias="icons/rockbox-clef.svg">../../docs/logo/rockbox-clef.svg</file>
</qresource>
- <qresource prefix="/ini" >
+ <qresource prefix="/ini">
<file>rbutil.ini</file>
</qresource>
</RCC>