From ac45f76968b48d4c1693ceb5fde6b97c8bc45822 Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Fri, 4 Feb 2011 22:35:43 +0100 Subject: [PATCH] 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. - does not respect the TTS vendor. - the corrections file is built in and can't get changed. - string corrections can be disabled in the configuration dialog. --- rbutil/rbutilqt/base/rbsettings.cpp | 1 + rbutil/rbutilqt/base/rbsettings.h | 1 + rbutil/rbutilqt/base/voicefile.cpp | 74 ++++++++++++++++++++++++++++++++++- rbutil/rbutilqt/base/voicefile.h | 13 +++++- rbutil/rbutilqt/configure.cpp | 4 ++ rbutil/rbutilqt/configurefrm.ui | 15 +++++++- rbutil/rbutilqt/rbutilqt.qrc | 9 ++-- 7 files changed, 108 insertions(+), 9 deletions(-) diff --git a/rbutil/rbutilqt/base/rbsettings.cpp b/rbutil/rbutilqt/base/rbsettings.cpp index c6f1bfc..2ec9b5a 100644 --- a/rbutil/rbutilqt/base/rbsettings.cpp +++ b/rbutil/rbutilqt/base/rbsettings.cpp @@ -42,6 +42,7 @@ const static struct { { RbSettings::Platform, "platform", "" }, { RbSettings::Language, "lang", "" }, { RbSettings::Tts, "tts", "" }, + { 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 d66a01d..5663f0a 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/voicefile.cpp b/rbutil/rbutilqt/base/voicefile.cpp index a3950ca..73f43aa 100644 --- a/rbutil/rbutilqt/base/voicefile.cpp +++ b/rbutil/rbutilqt/base/voicefile.cpp @@ -28,6 +28,74 @@ VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent) m_wavtrimThreshold=500; } + +void VoiceFileCreator::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(); + if(m_lang.isEmpty()) + m_lang = "english"; + qDebug() << "[VoiceFileCreator] building string corrections list for" + << m_lang << engine; + 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)); + if(!re_lang.exactMatch(m_lang)) { + 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(); +} + + +QString VoiceFileCreator::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 VoiceFileCreator::abort() { m_abort = true; @@ -129,6 +197,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(); @@ -146,9 +215,10 @@ void VoiceFileCreator::downloadDone(bool error) if(idfound && voicefound) { TalkGenerator::TalkEntry entry; - entry.toSpeak = voice; + entry.toSpeak = (useCorrection == true) ? correctString(voice) : 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") diff --git a/rbutil/rbutilqt/base/voicefile.h b/rbutil/rbutilqt/base/voicefile.h index 72f905e..0ba6fdd 100644 --- a/rbutil/rbutilqt/base/voicefile.h +++ b/rbutil/rbutilqt/base/voicefile.h @@ -38,9 +38,10 @@ public: //start creation bool createVoiceFile(); + QString correctString(QString s); void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; } - void setLang(QString name){m_lang =name;} + void setLang(QString name); void setWavtrimThreshold(int th){m_wavtrimThreshold = th;} public slots: @@ -56,8 +57,16 @@ private slots: void downloadDone(bool error); private: + struct CorrectionItems + { + QString search; + QString replace; + QString modifier; + }; + QList m_corrections; + 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 65f24f7..f159cb9 100644 --- a/rbutil/rbutilqt/configure.cpp +++ b/rbutil/rbutilqt/configure.cpp @@ -184,6 +184,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()); @@ -265,6 +266,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 0c82e5d..db59fde 100644 --- a/rbutil/rbutilqt/configurefrm.ui +++ b/rbutil/rbutilqt/configurefrm.ui @@ -97,7 +97,13 @@ - + + + + 1 + + + @@ -440,6 +446,13 @@ + + + + &Use string corrections for TTS + + + diff --git a/rbutil/rbutilqt/rbutilqt.qrc b/rbutil/rbutilqt/rbutilqt.qrc index ed26020..3f2356b 100644 --- a/rbutil/rbutilqt/rbutilqt.qrc +++ b/rbutil/rbutilqt/rbutilqt.qrc @@ -1,12 +1,13 @@ - + ../../docs/CREDITS ../../docs/gpl-2.0.html - + ../../tools/VOICE_PAUSE.wav + ../../tools/voice-corrections.txt - + icons/audio-input-microphone.png icons/bootloader_btn.png icons/dialog-error.png @@ -36,7 +37,7 @@ icons/wizard.xpm icons/rockbox-clef.svg - + rbutil.ini -- 1.7.4