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);