Index: rbutil/rbutilqt/base/rbsettings.cpp
===================================================================
--- rbutil/rbutilqt/base/rbsettings.cpp (revision 21524)
+++ rbutil/rbutilqt/base/rbsettings.cpp (working copy)
@@ -82,6 +82,8 @@
{ RbSettings::TtsOptions, ":tts:/options", "" },
{ RbSettings::TtsPath, ":tts:/path", "" },
{ RbSettings::TtsVoice, ":tts:/voice", "" },
+ { RbSettings::TtsVolume, ":tts:/volume", "100" },
+ { RbSettings::TtsPitch, ":tts:/pitch", "0" },
{ RbSettings::EncoderPath, ":encoder:/encoderpath", "" },
{ RbSettings::EncoderOptions, ":encoder:/encoderoptions", "" },
{ RbSettings::CacheOffline, "offline", "false" },
Index: rbutil/rbutilqt/base/rbsettings.h
===================================================================
--- rbutil/rbutilqt/base/rbsettings.h (revision 21524)
+++ rbutil/rbutilqt/base/rbsettings.h (working copy)
@@ -56,6 +56,8 @@
TtsOptions,
TtsPath,
TtsVoice,
+ TtsVolume,
+ TtsPitch,
EncoderPath,
EncoderOptions,
WavtrimThreshold,
Index: rbutil/rbutilqt/base/tts.cpp
===================================================================
--- rbutil/rbutilqt/base/tts.cpp (revision 21524)
+++ rbutil/rbutilqt/base/tts.cpp (working copy)
@@ -36,6 +36,7 @@
ttsList["espeak"] = "Espeak TTS Engine";
ttsList["flite"] = "Flite TTS Engine";
ttsList["swift"] = "Swift TTS Engine";
+ ttsList["open-sapi"] = "Open Sapi Engine";
#if defined(Q_OS_WIN)
ttsList["sapi"] = "Sapi TTS Engine";
#endif
@@ -47,26 +48,24 @@
// function to get a specific encoder
TTSBase* TTSBase::getTTS(QObject* parent,QString ttsName)
{
-
TTSBase* tts;
-#if defined(Q_OS_WIN)
if(ttsName == "sapi")
{
tts = new TTSSapi(parent);
return tts;
}
- else
-#endif
-#if defined(Q_OS_LINUX)
- if (ttsName == "festival")
+ else if (ttsName == "festival")
{
tts = new TTSFestival(parent);
return tts;
}
- else
-#endif
- if (true) // fix for OS other than WIN or LINUX
+ else if(ttsName == "open-sapi")
{
+ tts = new TTSOpenSapi(parent);
+ return tts;
+ }
+ else // fix for OS other than WIN or LINUX
+ {
tts = new TTSExes(ttsName,parent);
return tts;
}
@@ -664,3 +663,140 @@
}
+/*********************************************************************
+* OpenSapi
+**********************************************************************/
+TTSOpenSapi::TTSOpenSapi(QObject* parent) : TTSBase(parent)
+{
+ m_path = "";
+}
+
+void TTSOpenSapi::generateSettings()
+{
+ // server path
+ QString exepath = RbSettings::subValue("open-sapi",RbSettings::TtsPath).toString();
+ if(exepath == "" ) exepath = findExecutable("server.exe");
+ EncTtsSetting* setting =new EncTtsSetting(this,EncTtsSetting::eSTRING,"Path to Open-Sapi server:",exepath,EncTtsSetting::eBROWSEBTN);
+ connect(setting,SIGNAL(dataChanged()),this,SLOT(updateVoiceList()));
+ insertSetting(eSERVERPATH,setting);
+
+ //TODO language is missing ? or not needed for this ?
+
+ //TODO Format
+
+ // voice
+ insertSetting(eVOICE,new EncTtsSetting(this,EncTtsSetting::eSTRINGLIST,
+ tr("Voice:"),RbSettings::subValue("open-sapi",RbSettings::TtsVoice),getVoiceList(exepath)));
+
+ //Volume
+ insertSetting(eVOLUME,new EncTtsSetting(this,EncTtsSetting::eINT,
+ tr("Volume:"),RbSettings::subValue("open-sapi",RbSettings::TtsVolume),0,100));
+
+ //speed
+ insertSetting(eSPEED,new EncTtsSetting(this,EncTtsSetting::eINT,
+ tr("Rate:"),RbSettings::subValue("open-sapi",RbSettings::TtsSpeed),-10,10));
+
+ //pitch
+ insertSetting(ePITCH,new EncTtsSetting(this,EncTtsSetting::eINT,
+ tr("Pitch:"),RbSettings::subValue("open-sapi",RbSettings::TtsPitch),-10,10));
+
+}
+
+void TTSOpenSapi::saveSettings()
+{
+ RbSettings::setSubValue("open-sapi",RbSettings::TtsPath,getSetting(eSERVERPATH)->current().toString());
+ RbSettings::setSubValue("open-sapi",RbSettings::TtsVoice,getSetting(eVOICE)->current().toString());
+ RbSettings::setSubValue("open-sapi",RbSettings::TtsVolume,getSetting(eVOLUME)->current().toInt());
+ RbSettings::setSubValue("open-sapi",RbSettings::TtsSpeed,getSetting(eSPEED)->current().toInt());
+ RbSettings::setSubValue("open-sapi",RbSettings::TtsPitch,getSetting(ePITCH)->current().toInt());
+
+ //TODO save other settings
+}
+
+void TTSOpenSapi::updateVoiceList()
+{
+ QStringList voiceList = getVoiceList(getSetting(eSERVERPATH)->current().toString());
+ getSetting(eVOICE)->setList(voiceList);
+ if(voiceList.size() > 0) getSetting(eVOICE)->setCurrent(voiceList.at(0));
+ else getSetting(eVOICE)->setCurrent("");
+}
+
+QStringList TTSOpenSapi::getVoiceList(QString path)
+{
+ QStringList result;
+ QString errstr;
+ m_path = path;
+ if(start(&errstr))
+ {
+ // TODO ask server for list
+ stop();
+ }
+ m_path = "";
+ return result;
+}
+
+bool TTSOpenSapi::start(QString *errStr)
+{
+ if(!configOk())
+ return false;
+
+ if(m_path == "")
+ m_path = RbSettings::subValue("open-sapi",RbSettings::TtsPath).toString();
+
+#if defined(Q_OS_LINUX)
+ m_path = "wine "+m_path;
+#endif
+
+ // m_serverProcess.start(m_path);
+ // m_serverProcess.waitForStarted();
+
+ m_clientSocket.connectToHost("127.0.0.1",5491);
+ if(!m_clientSocket.waitForConnected(5000))
+ {
+ *errStr = tr("Could not connect to open-sapi server:") + m_clientSocket.errorString();
+ return false;
+ }
+
+ return true;
+}
+
+bool TTSOpenSapi::stop()
+{
+ m_clientSocket.disconnectFromHost();
+ // m_serverProcess.terminate();
+ // m_serverProcess.kill();
+
+ return true;
+}
+
+TTSStatus TTSOpenSapi::voice(QString text,QString wavfile, QString *errStr)
+{
+ (void) errStr;
+
+ //set outfile
+ QString message = "outFile "+wavfile+"\n";
+ m_clientSocket.write(message.toUtf8());
+ //TODO set other settings, language? and voice.
+
+ message = "speakMe " +
+ " " +
+ " "+text+"\n";
+ m_clientSocket.write(message.toUtf8());
+ m_clientSocket.flush();
+
+ return NoError;
+
+}
+
+bool TTSOpenSapi::configOk()
+{
+ bool ret= false;
+ QString serverPath = RbSettings::subValue("open-sapi",RbSettings::TtsPath).toString();
+
+ if(QFileInfo(serverPath).exists())
+ ret = true;
+
+ //TODO more checks
+
+ return ret;
+}
Index: rbutil/rbutilqt/base/tts.h
===================================================================
--- rbutil/rbutilqt/base/tts.h (revision 21524)
+++ rbutil/rbutilqt/base/tts.h (working copy)
@@ -177,4 +177,37 @@
QMap voiceDescriptions;
};
+class TTSOpenSapi : public TTSBase
+{
+ enum ESettings
+ {
+ eSERVERPATH,
+ eVOICE,
+ eVOLUME,
+ eSPEED,
+ ePITCH
+ };
+
+ Q_OBJECT
+ public:
+ TTSOpenSapi(QObject* parent=NULL);
+ TTSStatus voice(QString text,QString wavfile, QString *errStr);
+ bool start(QString *errStr);
+ bool stop();
+
+ // for settings
+ void generateSettings();
+ void saveSettings();
+ bool configOk();
+ public slots:
+ void updateVoiceList();
+ private slots:
+ QStringList getVoiceList(QString path);
+ private:
+ QTcpSocket m_clientSocket;
+ QProcess m_serverProcess;
+ QString m_path;
+};
+
+
#endif
Index: rbutil/rbutilqt/configure.cpp
===================================================================
--- rbutil/rbutilqt/configure.cpp (revision 21525)
+++ rbutil/rbutilqt/configure.cpp (working copy)
@@ -680,7 +680,7 @@
QTemporaryFile file(this);
file.open();
- QString filename = file.fileName();
+ QString filename = file.fileName() + ".wav";
file.close();
if(tts->voice(tr("Rockbox Utility Voice Test"),filename,&errstr) == FatalError)
Index: rbutil/rbutilqt/encttscfggui.cpp
===================================================================
--- rbutil/rbutilqt/encttscfggui.cpp (revision 21524)
+++ rbutil/rbutilqt/encttscfggui.cpp (working copy)
@@ -356,7 +356,7 @@
QString curPath = setting->current().toString();
// show file dialog
QString exe = QFileDialog::getOpenFileName(this, tr("Select excutable"), curPath, "*");
- if(!QFileInfo(exe).isExecutable())
+ if(!QFileInfo(exe).exists())
return;
// set new value, gui will update automatically
setting->setCurrent(exe);