summaryrefslogtreecommitdiff
path: root/rbutil
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil')
-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 {
48#else 48#else
49 { RbSettings::Tts, "tts", "espeak" }, 49 { RbSettings::Tts, "tts", "espeak" },
50#endif 50#endif
51 { RbSettings::UseTtsCorrections, "use_tts_corrections", "true" },
51 { RbSettings::LastTalkedFolder, "last_talked_folder", "" }, 52 { RbSettings::LastTalkedFolder, "last_talked_folder", "" },
52 { RbSettings::VoiceLanguage, "voicelanguage", "" }, 53 { RbSettings::VoiceLanguage, "voicelanguage", "" },
53 { RbSettings::TtsLanguage, ":tts:/language", "" }, 54 { 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
42 Platform, 42 Platform,
43 Language, 43 Language,
44 Tts, 44 Tts,
45 UseTtsCorrections,
45 LastTalkedFolder, 46 LastTalkedFolder,
46 VoiceLanguage, 47 VoiceLanguage,
47 TtsLanguage, 48 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()
50 // generate entries 50 // generate entries
51 { 51 {
52 TalkGenerator generator(this); 52 TalkGenerator generator(this);
53 // no string corrections yet: do not set language for TalkGenerator.
53 connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool))); 54 connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool)));
54 connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int))); 55 connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int)));
55 connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int))); 56 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 @@
25TalkGenerator::TalkGenerator(QObject* parent): QObject(parent), encFutureWatcher(this), ttsFutureWatcher(this) 25TalkGenerator::TalkGenerator(QObject* parent): QObject(parent), encFutureWatcher(this), ttsFutureWatcher(this)
26{ 26{
27 m_userAborted = false; 27 m_userAborted = false;
28 m_lang = "";
28} 29}
29 30
30//! \brief Creates Talkfiles. 31//! \brief Creates Talkfiles.
@@ -113,6 +114,11 @@ TalkGenerator::Status TalkGenerator::voiceList(QList<TalkEntry>* list,int wavtri
113 (*list)[i].refs.tts = m_tts; 114 (*list)[i].refs.tts = m_tts;
114 (*list)[i].refs.wavtrim = wavtrimth; 115 (*list)[i].refs.wavtrim = wavtrimth;
115 (*list)[i].refs.generator = this; 116 (*list)[i].refs.generator = this;
117 // enable voice corrections only if a language is set.
118 if(!m_lang.isEmpty()) {
119 QString s = (*list)[i].toSpeak;
120 (*list)[i].toSpeak = correctString(s);
121 }
116 122
117 // skip duplicated wav entries 123 // skip duplicated wav entries
118 if(!duplicates.contains(list->at(i).wavfilename)) 124 if(!duplicates.contains(list->at(i).wavfilename))
@@ -247,7 +253,7 @@ TalkGenerator::Status TalkGenerator::encodeList(QList<TalkEntry>* list)
247 TalkGenerators.*/ 253 TalkGenerators.*/
248 } 254 }
249 255
250 connect(&encFutureWatcher, SIGNAL(progressValueChanged(int)), 256 connect(&encFutureWatcher, SIGNAL(progressValueChanged(int)),
251 this, SLOT(encProgress(int))); 257 this, SLOT(encProgress(int)));
252 encFutureWatcher.setFuture(QtConcurrent::map(*list, &TalkGenerator::encEntryPoint)); 258 encFutureWatcher.setFuture(QtConcurrent::map(*list, &TalkGenerator::encEntryPoint));
253 259
@@ -302,3 +308,76 @@ void TalkGenerator::abort()
302 m_userAborted = true; 308 m_userAborted = true;
303} 309}
304 310
311QString TalkGenerator::correctString(QString s)
312{
313 QString corrected = s;
314 int i = 0;
315 int max = m_corrections.size();
316 while(i < max) {
317 corrected = corrected.replace(QRegExp(m_corrections.at(i).search,
318 m_corrections.at(i).modifier.contains("i")
319 ? Qt::CaseInsensitive : Qt::CaseSensitive),
320 m_corrections.at(i).replace);
321 i++;
322 }
323
324 if(corrected != s)
325 qDebug() << "[VoiceFileCreator] corrected string" << s << "to" << corrected;
326
327 return corrected;
328}
329
330
331void TalkGenerator::setLang(QString name)
332{
333 m_lang = name;
334
335 // re-initialize corrections list
336 m_corrections.clear();
337 QFile correctionsFile(":/builtin/voice-corrections.txt");
338 correctionsFile.open(QIODevice::ReadOnly);
339
340 QString engine = RbSettings::value(RbSettings::Tts).toString();
341 TTSBase* tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString());
342 QString vendor = tts->voiceVendor();
343 delete tts;
344
345 if(m_lang.isEmpty())
346 m_lang = "english";
347 qDebug() << "[TalkGenerator] building string corrections list for"
348 << m_lang << engine << vendor;
349 QTextStream stream(&correctionsFile);
350 while(!stream.atEnd()) {
351 QString line = stream.readLine();
352 if(line.startsWith(" ") || line.length() < 10)
353 continue;
354 // separator is first character
355 QString separator = line.at(0);
356 line.remove(0, 1);
357 QStringList items = line.split(separator);
358 // we need to have at least 6 separate entries.
359 if(items.size() < 6)
360 continue;
361
362 QRegExp re_lang(items.at(0));
363 QRegExp re_engine(items.at(1));
364 QRegExp re_vendor(items.at(2));
365 if(!re_lang.exactMatch(m_lang)) {
366 continue;
367 }
368 if(!re_vendor.exactMatch(vendor)) {
369 continue;
370 }
371 if(!re_engine.exactMatch(engine)) {
372 continue;
373 }
374 struct CorrectionItems co;
375 co.search = items.at(3);
376 co.replace = items.at(4);
377 // Qt uses backslash for back references, Perl uses dollar sign.
378 co.replace.replace(QRegExp("\\$(\\d+)"), "\\\\1");
379 co.modifier = items.at(5);
380 m_corrections.append(co);
381 }
382 correctionsFile.close();
383}
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:
67 67
68 TalkGenerator(QObject* parent); 68 TalkGenerator(QObject* parent);
69 Status process(QList<TalkEntry>* list,int wavtrimth = -1); 69 Status process(QList<TalkEntry>* list,int wavtrimth = -1);
70 QString correctString(QString s);
70 71
71public slots: 72public slots:
72 void abort(); 73 void abort();
73 void encProgress(int value); 74 void encProgress(int value);
74 void ttsProgress(int value); 75 void ttsProgress(int value);
76 void setLang(QString name);
75 77
76signals: 78signals:
77 void done(bool); 79 void done(bool);
@@ -95,6 +97,15 @@ private:
95 97
96 bool m_ttsWarnings; 98 bool m_ttsWarnings;
97 bool m_userAborted; 99 bool m_userAborted;
100 QString m_lang;
101
102 struct CorrectionItems
103 {
104 QString search;
105 QString replace;
106 QString modifier;
107 };
108 QList<struct CorrectionItems> m_corrections;
98}; 109};
99 110
100 111
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)
132 QString id, voice; 132 QString id, voice;
133 bool idfound = false; 133 bool idfound = false;
134 bool voicefound=false; 134 bool voicefound=false;
135 bool useCorrection = RbSettings::value(RbSettings::UseTtsCorrections).toBool();
135 while (!in.atEnd()) 136 while (!in.atEnd())
136 { 137 {
137 QString line = in.readLine(); 138 QString line = in.readLine();
@@ -151,7 +152,8 @@ void VoiceFileCreator::downloadDone(bool error)
151 TalkGenerator::TalkEntry entry; 152 TalkGenerator::TalkEntry entry;
152 entry.toSpeak = voice; 153 entry.toSpeak = voice;
153 entry.wavfilename = m_path + "/" + id + ".wav"; 154 entry.wavfilename = m_path + "/" + id + ".wav";
154 entry.talkfilename = m_path + "/" + id + ".mp3"; //voicefont wants them with .mp3 extension 155 //voicefont wants them with .mp3 extension
156 entry.talkfilename = m_path + "/" + id + ".mp3";
155 entry.voiced = false; 157 entry.voiced = false;
156 entry.encoded = false; 158 entry.encoded = false;
157 if(id == "VOICE_PAUSE") 159 if(id == "VOICE_PAUSE")
@@ -178,6 +180,9 @@ void VoiceFileCreator::downloadDone(bool error)
178 // generate files 180 // generate files
179 { 181 {
180 TalkGenerator generator(this); 182 TalkGenerator generator(this);
183 // set language for string correction. If not set no correction will be made.
184 if(useCorrection)
185 generator.setLang(m_lang);
181 connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool))); 186 connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool)));
182 connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int))); 187 connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int)));
183 connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int))); 188 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:
40 bool createVoiceFile(); 40 bool createVoiceFile();
41 41
42 void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; } 42 void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; }
43 void setLang(QString name){m_lang =name;} 43 void setLang(QString name) { m_lang = name; }
44 void setWavtrimThreshold(int th){m_wavtrimThreshold = th;} 44 void setWavtrimThreshold(int th){m_wavtrimThreshold = th;}
45 45
46public slots: 46public slots:
@@ -56,8 +56,9 @@ private slots:
56 void downloadDone(bool error); 56 void downloadDone(bool error);
57 57
58private: 58private:
59
59 void cleanup(); 60 void cleanup();
60 61
61 HttpGet *getter; 62 HttpGet *getter;
62 QString filename; //the temporary file 63 QString filename; //the temporary file
63 QString m_mountpoint; //mountpoint of the device 64 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()
205 RbSettings::setValue(RbSettings::CacheOffline, ui.cacheOfflineMode->isChecked()); 205 RbSettings::setValue(RbSettings::CacheOffline, ui.cacheOfflineMode->isChecked());
206 206
207 // tts settings 207 // tts settings
208 RbSettings::setValue(RbSettings::UseTtsCorrections, ui.ttsCorrections->isChecked());
208 int i = ui.comboTts->currentIndex(); 209 int i = ui.comboTts->currentIndex();
209 RbSettings::setValue(RbSettings::Tts, ui.comboTts->itemData(i).toString()); 210 RbSettings::setValue(RbSettings::Tts, ui.comboTts->itemData(i).toString());
210 211
@@ -288,6 +289,9 @@ void Config::setUserSettings()
288 ui.cacheDisable->setChecked(RbSettings::value(RbSettings::CacheDisabled).toBool()); 289 ui.cacheDisable->setChecked(RbSettings::value(RbSettings::CacheDisabled).toBool());
289 ui.cacheOfflineMode->setChecked(RbSettings::value(RbSettings::CacheOffline).toBool()); 290 ui.cacheOfflineMode->setChecked(RbSettings::value(RbSettings::CacheOffline).toBool());
290 updateCacheInfo(RbSettings::value(RbSettings::CachePath).toString()); 291 updateCacheInfo(RbSettings::value(RbSettings::CachePath).toString());
292
293 // TTS tab
294 ui.ttsCorrections->setChecked(RbSettings::value(RbSettings::UseTtsCorrections).toBool());
291} 295}
292 296
293 297
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 @@
449 </property> 449 </property>
450 </widget> 450 </widget>
451 </item> 451 </item>
452 <item row="2" column="0" colspan="3">
453 <widget class="QCheckBox" name="ttsCorrections">
454 <property name="text">
455 <string>&amp;Use string corrections for TTS</string>
456 </property>
457 </widget>
458 </item>
452 </layout> 459 </layout>
453 </widget> 460 </widget>
454 </item> 461 </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 @@
1<RCC> 1<RCC>
2 <qresource prefix="/" > 2 <qresource prefix="/">
3 <file>../../docs/CREDITS</file> 3 <file>../../docs/CREDITS</file>
4 <file>../../docs/gpl-2.0.html</file> 4 <file>../../docs/gpl-2.0.html</file>
5 </qresource> 5 </qresource>
6 <qresource> 6 <qresource>
7 <file alias="builtin/VOICE_PAUSE.wav">../../tools/VOICE_PAUSE.wav</file> 7 <file alias="builtin/VOICE_PAUSE.wav">../../tools/VOICE_PAUSE.wav</file>
8 <file alias="builtin/voice-corrections.txt">../../tools/voice-corrections.txt</file>
8 </qresource> 9 </qresource>
9 <qresource prefix="/" > 10 <qresource prefix="/">
10 <file>icons/audio-input-microphone.png</file> 11 <file>icons/audio-input-microphone.png</file>
11 <file>icons/bootloader_btn.png</file> 12 <file>icons/bootloader_btn.png</file>
12 <file>icons/dialog-error.png</file> 13 <file>icons/dialog-error.png</file>
@@ -36,7 +37,7 @@
36 <file>icons/wizard.jpg</file> 37 <file>icons/wizard.jpg</file>
37 <file alias="icons/rockbox-clef.svg">../../docs/logo/rockbox-clef.svg</file> 38 <file alias="icons/rockbox-clef.svg">../../docs/logo/rockbox-clef.svg</file>
38 </qresource> 39 </qresource>
39 <qresource prefix="/ini" > 40 <qresource prefix="/ini">
40 <file>rbutil.ini</file> 41 <file>rbutil.ini</file>
41 </qresource> 42 </qresource>
42</RCC> 43</RCC>