From d007eb24489fa429de479e5378a681e77e599d2e Mon Sep 17 00:00:00 2001 From: domonoky Date: Sun, 23 Sep 2007 13:35:45 +0000 Subject: [PATCH] rbutil: added support for talkfile creation with the rockbox sapi_voice.vbs script. Also let the configure dialog remember options and paths for different tts and encoders. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14828 a1c6a512-1295-4272-9138-f99709370657 --- rbutil/rbutilqt/configure.cpp | 96 ++++++++++++++++++++++------- rbutil/rbutilqt/configurefrm.ui | 16 ++++- rbutil/rbutilqt/installtalkwindow.cpp | 60 +++++++++++-------- rbutil/rbutilqt/rbutil.ini | 17 ++++++ rbutil/rbutilqt/talkfile.cpp | 110 +++++++++++++++++++++++++--------- rbutil/rbutilqt/talkfile.h | 60 +++++++++++++++++-- 6 files changed, 276 insertions(+), 83 deletions(-) diff --git a/rbutil/rbutilqt/configure.cpp b/rbutil/rbutilqt/configure.cpp index 967e0111e..f45eb42f1 100644 --- a/rbutil/rbutilqt/configure.cpp +++ b/rbutil/rbutilqt/configure.cpp @@ -128,18 +128,35 @@ void Config::accept() userSettings->setValue("offline", ui.cacheOfflineMode->isChecked()); // tts settings - if(QFileInfo(ui.ttsExecutable->text()).isExecutable()) - userSettings->setValue("ttsbin", ui.ttsExecutable->text()); - userSettings->setValue("ttsopts", ui.ttsOptions->text()); - if(QFileInfo(ui.encoderExecutable->text()).isExecutable()) - userSettings->setValue("encbin", ui.encoderExecutable->text()); - userSettings->setValue("ttsopts", ui.ttsOptions->text()); QString preset; - preset = ui.comboEncoder->itemData(ui.comboEncoder->currentIndex(), Qt::UserRole).toString(); - userSettings->setValue("encpreset", preset); preset = ui.comboTts->itemData(ui.comboTts->currentIndex(), Qt::UserRole).toString(); userSettings->setValue("ttspreset", preset); - + userSettings->beginGroup(preset); + + if(QFileInfo(ui.ttsExecutable->text()).exists()) + userSettings->setValue("binary", ui.ttsExecutable->text()); + userSettings->setValue("options", ui.ttsOptions->text()); + userSettings->setValue("language", ui.ttsLanguage->text()); + devices->beginGroup(preset); + userSettings->setValue("template", devices->value("template").toString()); + userSettings->setValue("type", devices->value("tts").toString()); + devices->endGroup(); + userSettings->endGroup(); + + //encoder settings + preset = ui.comboEncoder->itemData(ui.comboEncoder->currentIndex(), Qt::UserRole).toString(); + userSettings->setValue("encpreset", preset); + userSettings->beginGroup(preset); + + if(QFileInfo(ui.encoderExecutable->text()).isExecutable()) + userSettings->setValue("binary", ui.encoderExecutable->text()); + userSettings->setValue("options", ui.encoderOptions->text()); + devices->beginGroup(preset); + userSettings->setValue("template", devices->value("template").toString()); + userSettings->setValue("type", devices->value("tts").toString()); + devices->endGroup(); + userSettings->endGroup(); + // sync settings userSettings->sync(); this->close(); @@ -302,7 +319,21 @@ void Config::setDevices(QSettings *dev) devices->beginGroup("tts"); keys = devices->allKeys(); for(int i=0; i < keys.size();i++) - ui.comboTts->addItem(devices->value(keys.at(i), "null").toString(), keys.at(i)); + { + devices->endGroup(); + devices->beginGroup(keys.at(i)); + QString os = devices->value("os").toString(); + devices->endGroup(); + devices->beginGroup("tts"); + + if(os == "all") + ui.comboTts->addItem(devices->value(keys.at(i), "null").toString(), keys.at(i)); + +#if defined(Q_OS_WIN32) + if(os == "win32") + ui.comboTts->addItem(devices->value(keys.at(i), "null").toString(), keys.at(i)); +#endif + } devices->endGroup(); int index; @@ -311,14 +342,12 @@ void Config::setDevices(QSettings *dev) if(index < 0) index = 0; ui.comboTts->setCurrentIndex(index); updateTtsOpts(index); - ui.ttsExecutable->setText(userSettings->value("ttsbin").toString()); - + index = ui.comboEncoder->findData(userSettings->value("encpreset").toString(), Qt::UserRole, Qt::MatchExactly); if(index < 0) index = 0; ui.comboEncoder->setCurrentIndex(index); updateEncOpts(index); - ui.encoderExecutable->setText(userSettings->value("encbin").toString()); } @@ -347,9 +376,9 @@ void Config::updateEncOpts(int index) for(int i = 0; i < path.size(); i++) { QString executable = QDir::fromNativeSeparators(path.at(i)) + "/" + e; #if defined(Q_OS_WIN) - executable += ".exe"; - QStringList ex = executable.split("\"", QString::SkipEmptyParts); - executable = ex.join(""); + executable += ".exe"; + QStringList ex = executable.split("\"", QString::SkipEmptyParts); + executable = ex.join(""); #endif if(QFileInfo(executable).isExecutable()) { qDebug() << "found:" << executable; @@ -360,6 +389,15 @@ void Config::updateEncOpts(int index) break; } } + + //user settings + userSettings->beginGroup(c); + QString temp = userSettings->value("binary","null").toString(); + if(temp != "null") ui.encoderExecutable->setText(temp); + temp = userSettings->value("options","null").toString(); + if(temp != "null") ui.encoderOptions->setText(temp); + userSettings->endGroup(); + } @@ -367,14 +405,18 @@ void Config::updateTtsOpts(int index) { bool edit; QString e; + bool needsLanguageCfg; QString c = ui.comboTts->itemData(index, Qt::UserRole).toString(); devices->beginGroup(c); edit = devices->value("edit").toBool(); + needsLanguageCfg = devices->value("needslanguagecfg").toBool(); + ui.ttsLanguage->setVisible(needsLanguageCfg); + ui.ttsLanguageLabel->setVisible(needsLanguageCfg); ui.ttsOptions->setText(devices->value("options").toString()); ui.ttsOptions->setEnabled(devices->value("edit").toBool()); e = devices->value("tts").toString(); devices->endGroup(); - + #if defined(Q_OS_LINUX) || defined(Q_OS_MACX) QStringList path = QString(getenv("PATH")).split(":", QString::SkipEmptyParts); #elif defined(Q_OS_WIN) @@ -385,11 +427,11 @@ void Config::updateTtsOpts(int index) for(int i = 0; i < path.size(); i++) { QString executable = QDir::fromNativeSeparators(path.at(i)) + "/" + e; #if defined(Q_OS_WIN) - executable += ".exe"; - QStringList ex = executable.split("\"", QString::SkipEmptyParts); - executable = ex.join(""); + executable += ".exe"; + QStringList ex = executable.split("\"", QString::SkipEmptyParts); + executable = ex.join(""); #endif - qDebug() << executable; + qDebug() << executable; if(QFileInfo(executable).isExecutable()) { ui.ttsExecutable->setText(QDir::toNativeSeparators(executable)); // disallow changing the detected path if non-customizable profile @@ -398,6 +440,16 @@ void Config::updateTtsOpts(int index) break; } } + + //user settings + userSettings->beginGroup(c); + QString temp = userSettings->value("binary","null").toString(); + if(temp != "null") ui.ttsExecutable->setText(temp); + temp = userSettings->value("options","null").toString(); + if(temp != "null") ui.ttsOptions->setText(temp); + temp = userSettings->value("language","null").toString(); + if(temp != "null") ui.ttsLanguage->setText(temp); + userSettings->endGroup(); } @@ -672,7 +724,7 @@ void Config::browseTts() { qDebug() << browser.getSelected(); QString exe = browser.getSelected(); - if(!QFileInfo(exe).isExecutable()) + if(!QFileInfo(exe).exists()) return; ui.ttsExecutable->setText(exe); } diff --git a/rbutil/rbutilqt/configurefrm.ui b/rbutil/rbutilqt/configurefrm.ui index 4533b4450..f0bd71209 100644 --- a/rbutil/rbutilqt/configurefrm.ui +++ b/rbutil/rbutilqt/configurefrm.ui @@ -5,8 +5,8 @@ 0 0 - 500 - 435 + 548 + 472 @@ -23,7 +23,7 @@ - 0 + 4 @@ -414,6 +414,16 @@ + + + + TTS Language + + + + + + diff --git a/rbutil/rbutilqt/installtalkwindow.cpp b/rbutil/rbutilqt/installtalkwindow.cpp index 4324f693a..4c341fa79 100644 --- a/rbutil/rbutilqt/installtalkwindow.cpp +++ b/rbutil/rbutilqt/installtalkwindow.cpp @@ -69,24 +69,41 @@ void InstallTalkWindow::accept() connect(logger,SIGNAL(closed()),this,SLOT(close())); QString folderToTalk = ui.lineTalkFolder->text(); - QString pathEncoder = userSettings->value("encbin").toString(); - QString pathTTS = userSettings->value("ttsbin").toString(); - + + // tts + QString preset = userSettings->value("ttspreset").toString(); + userSettings->beginGroup(preset); + QString pathTTS = userSettings->value("binary").toString(); + QString ttsOpts = userSettings->value("options").toString(); + QString ttsLanguage = userSettings->value("language").toString(); + QString ttsTemplate = userSettings->value("template").toString(); + QString ttsType =userSettings->value("type").toString(); + userSettings->endGroup(); + + //encoder + QString encoderPreset = userSettings->value("encpreset").toString(); + userSettings->beginGroup(encoderPreset); + QString pathEncoder = userSettings->value("binary").toString(); + QString encOpts = userSettings->value("options").toString(); + QString encTemplate = userSettings->value("template").toString(); + QString encType =userSettings->value("type").toString(); + userSettings->endGroup(); + if(!QFileInfo(folderToTalk).isDir()) { - logger->addItem(tr("The Folder to Talk is wrong!"),LOGERROR); - logger->abort(); - return; + logger->addItem(tr("The Folder to Talk is wrong!"),LOGERROR); + logger->abort(); + return; } if(!QFileInfo(pathEncoder).isExecutable()) { - logger->addItem(tr("Path to Encoder is wrong!"),LOGERROR); - logger->abort(); - return; + logger->addItem(tr("Path to Encoder is wrong!"),LOGERROR); + logger->abort(); + return; } - if(!QFileInfo(pathTTS).isExecutable()) + if(!QFileInfo(pathTTS).exists()) { logger->addItem(tr("Path to TTS is wrong!"),LOGERROR); logger->abort(); @@ -99,21 +116,16 @@ void InstallTalkWindow::accept() talkcreator->setDir(folderToTalk); talkcreator->setTTSexe(pathTTS); + talkcreator->setTTsOpts(ttsOpts); + talkcreator->setTTsLanguage(ttsLanguage); + talkcreator->setTTsType(ttsType); + talkcreator->setTTsTemplate(ttsTemplate); + talkcreator->setEncexe(pathEncoder); - talkcreator->setEncOpts(userSettings->value("encopts").toString()); - talkcreator->setTTsOpts(userSettings->value("ttsopts").toString()); - - devices->beginGroup(userSettings->value("ttspreset").toString()); - talkcreator->setTTsType(devices->value("tts").toString()); - talkcreator->setTTsOpts(devices->value("options").toString()); - talkcreator->setTTsTemplate(devices->value("template").toString()); - devices->endGroup(); - devices->beginGroup(userSettings->value("encpreset").toString()); - talkcreator->setEncType(devices->value("encoder").toString()); - talkcreator->setEncOpts(devices->value("options").toString()); - talkcreator->setEncTemplate(devices->value("template").toString()); - devices->endGroup(); - + talkcreator->setEncOpts(encOpts); + talkcreator->setEncTemplate(encTemplate); + talkcreator->setEncType(encType); + talkcreator->setOverwriteTalk(ui.OverwriteTalk->isChecked()); talkcreator->setOverwriteWav(ui.OverwriteWav->isChecked()); talkcreator->setRemoveWav(ui.RemoveWav->isChecked()); diff --git a/rbutil/rbutilqt/rbutil.ini b/rbutil/rbutilqt/rbutil.ini index 74c0c4d92..ea6a1a4cd 100644 --- a/rbutil/rbutilqt/rbutil.ini +++ b/rbutil/rbutilqt/rbutil.ini @@ -399,27 +399,44 @@ ttspreset01 = "espeak (default)" ttspreset02 = "espeak (user-adjusted)" ttspreset03 = "flite (default)" ttspreset04 = "flite (user-adjusted)" +ttspreset05 = "sapi (default)" [ttspreset01] tts = "espeak" options = "" template = "\"%exe\" %options -w \"%wavfile\" \"%text\"" edit = false +os = all +needslanguagecfg = false [ttspreset02] tts = "espeak" options = "" template = "\"%exe\" %options -w \"%wavfile\" \"%text\"" edit = true +os = all +needslanguagecfg = false [ttspreset03] tts = "flite" options = "" template = "\"%exe\" %options -o \"%wavfile\" \"%text\"" edit = false +os = all +needslanguagecfg = false [ttspreset04] tts = "flite" options = "" template = "\"%exe\" %options -o \"%wavfile\" \"%text\"" edit = true +os = all +needslanguagecfg = false + +[ttspreset05] +tts = "sapi" +options = "" +template = "cscript //nologo \"%exe\" /language:english %options" +edit = false +os = win32 +needslanguagecfg = true diff --git a/rbutil/rbutilqt/talkfile.cpp b/rbutil/rbutilqt/talkfile.cpp index 2096c8150..d3e3a2478 100644 --- a/rbutil/rbutilqt/talkfile.cpp +++ b/rbutil/rbutilqt/talkfile.cpp @@ -38,26 +38,24 @@ bool TalkFileCreator::initEncoder() } } -bool TalkFileCreator::initTTS() -{ - QFileInfo tts(m_TTSexec); - - if(tts.exists()) - { - return true; - } - else - { - return false; - } -} bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger) { m_abort = false; m_logger = logger; m_logger->addItem("Starting Talkfile generation",LOGINFO); - if(!initTTS()) + + if(m_curTTS == "sapi") + m_tts = new TTSSapi(); + else + m_tts = new TTSExes(); + + m_tts->setTTSexe(m_TTSexec); + m_tts->setTTsOpts(m_TTSOpts); + m_tts->setTTsLanguage(m_TTSLanguage); + m_tts->setTTsTemplate(m_curTTSTemplate); + + if(!m_tts->start()) { m_logger->addItem("Init of TTS engine failed",LOGERROR); return false; @@ -65,6 +63,7 @@ bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger) if(!initEncoder()) { m_logger->addItem("Init of encoder failed",LOGERROR); + m_tts->stop(); return false; } QApplication::processEvents(); @@ -80,6 +79,7 @@ bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger) if(m_abort) { m_logger->addItem("Talkfile creation aborted",LOGERROR); + m_tts->stop(); return false; } @@ -117,10 +117,11 @@ bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger) if(!wavfilenameInf.exists() || m_overwriteWav) { m_logger->addItem("Voicing of " + toSpeak,LOGINFO); - if(!voice(toSpeak,wavfilename)) + if(!m_tts->voice(toSpeak,wavfilename)) { m_logger->addItem("Voicing of " + toSpeak + " failed",LOGERROR); m_logger->abort(); + m_tts->stop(); return false; } } @@ -129,6 +130,7 @@ bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger) { m_logger->addItem("Encoding of " + wavfilename + " failed",LOGERROR); m_logger->abort(); + m_tts->stop(); return false; } } @@ -148,6 +150,7 @@ bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger) } installlog.endGroup(); + m_tts->stop(); m_logger->addItem("Finished creating Talkfiles",LOGOK); m_logger->setProgressMax(1); m_logger->setProgressValue(1); @@ -162,33 +165,82 @@ void TalkFileCreator::abort() m_abort = true; } -bool TalkFileCreator::voice(QString text,QString wavfile) +bool TalkFileCreator::encode(QString input,QString output) { + qDebug() << "encoding.."; + QString execstring = m_curEncTemplate; - QString execstring = m_curTTSTemplate; + execstring.replace("%exe",m_EncExec); + execstring.replace("%options",m_EncOpts); + execstring.replace("%input",input); + execstring.replace("%output",output); + qDebug() << execstring; + QProcess::execute(execstring); + return true; + +} +bool TTSSapi::start() +{ + QFileInfo tts(m_TTSexec); + if(!tts.exists()) + return false; + + // create the voice process + QString execstring = m_TTSTemplate; execstring.replace("%exe",m_TTSexec); execstring.replace("%options",m_TTSOpts); - execstring.replace("%wavfile",wavfile); - execstring.replace("%text",text); + qDebug() << "init" << execstring; + voicescript = new QProcess(NULL); + voicescript->start(execstring); + if(!voicescript->waitForStarted()) + return false; + return true; +} - QProcess::execute(execstring); +bool TTSSapi::voice(QString text,QString wavfile) +{ + QString query = "SPEAK\t"+wavfile+"\t"+text+"\r\n"; + qDebug() << "voicing" << query; + voicescript->write(query.toLocal8Bit()); + voicescript->write("SYNC\tbla\r\n"); + voicescript->waitForReadyRead(); return true; +} +bool TTSSapi::stop() +{ + QString query = "QUIT\r\n"; + voicescript->write(query.toLocal8Bit()); + voicescript->waitForFinished(); + delete voicescript; + return true; } -bool TalkFileCreator::encode(QString input,QString output) +bool TTSExes::start() { - QString execstring = m_curEncTemplate; + QFileInfo tts(m_TTSexec); + qDebug() << "ttsexe init"; + if(tts.exists()) + { + return true; + } + else + { + return false; + } +} - execstring.replace("%exe",m_EncExec); - execstring.replace("%options",m_EncOpts); - execstring.replace("%input",input); - execstring.replace("%output",output); +bool TTSExes::voice(QString text,QString wavfile) +{ + QString execstring = m_TTSTemplate; + execstring.replace("%exe",m_TTSexec); + execstring.replace("%options",m_TTSOpts); + execstring.replace("%wavfile",wavfile); + execstring.replace("%text",text); + qDebug() << "voicing" << execstring; QProcess::execute(execstring); return true; -} - - +} \ No newline at end of file diff --git a/rbutil/rbutilqt/talkfile.h b/rbutil/rbutilqt/talkfile.h index f2119bc44..b2d6aa448 100644 --- a/rbutil/rbutilqt/talkfile.h +++ b/rbutil/rbutilqt/talkfile.h @@ -23,6 +23,29 @@ #include "progressloggerinterface.h" +class TTSBase : public QObject +{ + Q_OBJECT +public: + TTSBase(){} + virtual ~TTSBase(){} + virtual bool voice(QString text,QString wavfile){return false;} + virtual bool start(){return false;} + virtual bool stop(){return false;} + + void setTTSexe(QString exe){m_TTSexec=exe;} + void setTTsOpts(QString opts) {m_TTSOpts=opts;} + void setTTsLanguage(QString language) {m_TTSLanguage = language;} + void setTTsTemplate(QString t) { m_TTSTemplate = t; } + +protected: + QString m_TTSexec; + QString m_TTSOpts; + QString m_TTSTemplate; + QString m_TTSLanguage; +}; + + class TalkFileCreator :public QObject { Q_OBJECT @@ -37,6 +60,7 @@ public: void setTTsType(QString tts) { m_curTTS = tts; } void setTTsOpts(QString opts) {m_TTSOpts=opts;} + void setTTsLanguage(QString language) {m_TTSLanguage = language;} void setTTsTemplate(QString t) { m_curTTSTemplate = t; } void setEncType(QString enc) { m_curEnc = enc; } @@ -56,19 +80,20 @@ private slots: void abort(); private: - - bool initTTS(); - bool stopTTS(); + TTSBase* m_tts; + //bool initTTS(); + //bool stopTTS(); bool initEncoder(); - + bool encode(QString input,QString output); - bool voice(QString text,QString wavfile); + //bool voice(QString text,QString wavfile); QString m_dir; QString m_mountpoint; QString m_curTTS; QString m_TTSexec; QString m_TTSOpts; + QString m_TTSLanguage; QString m_curTTSTemplate; QString m_curEnc; @@ -87,4 +112,29 @@ private: bool m_abort; }; +class TTSSapi : public TTSBase +{ +public: + TTSSapi() {}; + virtual bool voice(QString text,QString wavfile); + virtual bool start(); + virtual bool stop(); + +private: + QProcess* voicescript; +}; + +class TTSExes : public TTSBase +{ +public: + TTSExes() {}; + virtual bool voice(QString text,QString wavfile); + virtual bool start(); + virtual bool stop() {return true;} + +private: + +}; + #endif + -- 2.11.4.GIT