1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id: tts.cpp 15212 2007-10-19 21:49:07Z domonoky $
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
22 #include "browsedirtree.h"
24 static QMap
<QString
,QString
> ttsList
;
25 static QMap
<QString
,TTSBase
*> ttsCache
;
29 ttsList
["espeak"] = "Espeak TTS Engine";
30 ttsList
["flite"] = "Flite TTS Engine";
31 ttsList
["swift"] = "Swift TTS Engine";
33 ttsList
["sapi"] = "Sapi 5 TTS Engine";
38 // function to get a specific encoder
39 TTSBase
* getTTS(QString ttsname
)
41 // init list if its empty
42 if(ttsList
.count() == 0) initTTSList();
44 QString ttsName
= ttsList
.key(ttsname
);
47 if(ttsCache
.contains(ttsName
))
48 return ttsCache
.value(ttsName
);
54 ttsCache
[ttsName
] = tts
;
59 tts
= new TTSExes(ttsName
);
60 ttsCache
[ttsName
] = tts
;
65 // get the list of encoders, nice names
66 QStringList
getTTSList()
68 // init list if its empty
69 if(ttsList
.count() == 0) initTTSList();
71 QStringList ttsNameList
;
72 QMapIterator
<QString
, QString
> i(ttsList
);
75 ttsNameList
<< i
.value();
82 /*********************************************************************
84 **********************************************************************/
85 TTSBase::TTSBase(QWidget
*parent
): QDialog(parent
)
90 /*********************************************************************
92 **********************************************************************/
93 TTSExes::TTSExes(QString name
,QWidget
*parent
) : TTSBase(parent
)
97 m_TemplateMap
["espeak"] = "\"%exe\" \"%options\" -w \"%wavfile\" \"%text\"";
98 m_TemplateMap
["flite"] = "\"%exe\" \"%options\" -o \"%wavfile\" \"%text\"";
99 m_TemplateMap
["swift"] = "\"%exe\" \"%options\" -o \"%wavfile\" \"%text\"";
103 connect(ui
.reset
,SIGNAL(clicked()),this,SLOT(reset()));
104 connect(ui
.browse
,SIGNAL(clicked()),this,SLOT(browse()));
107 bool TTSExes::start(QString
*errStr
)
109 userSettings
->beginGroup(m_name
);
110 m_TTSexec
= userSettings
->value("ttspath","").toString();
111 m_TTSOpts
= userSettings
->value("ttsoptions","").toString();
112 userSettings
->endGroup();
114 m_TTSTemplate
= m_TemplateMap
.value(m_name
);
116 QFileInfo
tts(m_TTSexec
);
123 *errStr
= tr("TTS executable not found");
128 bool TTSExes::voice(QString text
,QString wavfile
)
130 QString execstring
= m_TTSTemplate
;
132 execstring
.replace("%exe",m_TTSexec
);
133 execstring
.replace("%options",m_TTSOpts
);
134 execstring
.replace("%wavfile",wavfile
);
135 execstring
.replace("%text",text
);
136 //qDebug() << "voicing" << execstring;
137 QProcess::execute(execstring
);
143 void TTSExes::reset()
145 ui
.ttspath
->setText("");
146 ui
.ttsoptions
->setText("");
149 void TTSExes::showCfg()
151 // try to get config from settings
152 userSettings
->beginGroup(m_name
);
153 QString exepath
=userSettings
->value("ttspath","").toString();
154 ui
.ttsoptions
->setText(userSettings
->value("ttsoptions","").toString());
155 userSettings
->endGroup();
161 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
162 QStringList path
= QString(getenv("PATH")).split(":", QString::SkipEmptyParts
);
163 #elif defined(Q_OS_WIN)
164 QStringList path
= QString(getenv("PATH")).split(";", QString::SkipEmptyParts
);
167 for(int i
= 0; i
< path
.size(); i
++)
169 QString executable
= QDir::fromNativeSeparators(path
.at(i
)) + "/" + m_name
;
170 #if defined(Q_OS_WIN)
171 executable
+= ".exe";
172 QStringList ex
= executable
.split("\"", QString::SkipEmptyParts
);
173 executable
= ex
.join("");
175 qDebug() << executable
;
176 if(QFileInfo(executable
).isExecutable())
178 exepath
= QDir::toNativeSeparators(executable
);
185 ui
.ttspath
->setText(exepath
);
192 void TTSExes::accept(void)
194 if(userSettings
!= NULL
)
196 //save settings in user config
197 userSettings
->beginGroup(m_name
);
198 userSettings
->setValue("ttspath",ui
.ttspath
->text());
199 userSettings
->setValue("ttsoptions",ui
.ttsoptions
->text());
200 userSettings
->endGroup();
202 userSettings
->sync();
207 void TTSExes::reject(void)
212 bool TTSExes::configOk()
214 userSettings
->beginGroup(m_name
);
215 QString path
= userSettings
->value("ttspath","").toString();
216 userSettings
->endGroup();
218 if (QFileInfo(path
).exists())
224 void TTSExes::browse()
226 BrowseDirtree
browser(this);
227 browser
.setFilter(QDir::Dirs
| QDir::Files
| QDir::NoDotAndDotDot
);
229 if(QFileInfo(ui
.ttspath
->text()).isDir())
231 browser
.setDir(ui
.ttspath
->text());
233 if(browser
.exec() == QDialog::Accepted
)
235 qDebug() << browser
.getSelected();
236 QString exe
= browser
.getSelected();
237 if(!QFileInfo(exe
).isExecutable())
239 ui
.ttspath
->setText(exe
);
243 /*********************************************************************
245 **********************************************************************/
246 TTSSapi::TTSSapi(QWidget
*parent
) : TTSBase(parent
)
248 m_TTSTemplate
= "cscript //nologo \"%exe\" /language:%lang /voice:\"%voice\" /speed:%speed \"%options\"";
249 defaultLanguage
="english";
252 connect(ui
.reset
,SIGNAL(clicked()),this,SLOT(reset()));
253 connect(ui
.languagecombo
,SIGNAL(currentIndexChanged(QString
)),this,SLOT(updateVoices(QString
)));
257 bool TTSSapi::start(QString
*errStr
)
260 userSettings
->beginGroup("sapi");
261 m_TTSOpts
= userSettings
->value("ttsoptions","").toString();
262 m_TTSLanguage
=userSettings
->value("ttslanguage","").toString();
263 m_TTSVoice
=userSettings
->value("ttsvoice","").toString();
264 m_TTSSpeed
=userSettings
->value("ttsspeed","").toString();
265 userSettings
->endGroup();
267 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
268 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
269 m_TTSexec
= QDir::tempPath() +"/sapi_voice.vbs";
271 QFileInfo
tts(m_TTSexec
);
274 *errStr
= tr("Could not copy the Sapi-script");
277 // create the voice process
278 QString execstring
= m_TTSTemplate
;
279 execstring
.replace("%exe",m_TTSexec
);
280 execstring
.replace("%options",m_TTSOpts
);
281 execstring
.replace("%lang",m_TTSLanguage
);
282 execstring
.replace("%voice",m_TTSVoice
);
283 execstring
.replace("%speed",m_TTSSpeed
);
285 qDebug() << "init" << execstring
;
286 voicescript
= new QProcess(NULL
);
287 //connect(voicescript,SIGNAL(readyReadStandardError()),this,SLOT(error()));
289 voicescript
->start(execstring
);
290 if(!voicescript
->waitForStarted())
292 *errStr
= tr("Could not start the Sapi-script");
296 if(!voicescript
->waitForReadyRead(100))
298 *errStr
= voicescript
->readAllStandardError();
306 QStringList
TTSSapi::getVoiceList(QString language
)
310 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
311 m_TTSexec
= QDir::tempPath() +"/sapi_voice.vbs";
313 QFileInfo
tts(m_TTSexec
);
317 // create the voice process
318 QString execstring
= "cscript //nologo \"%exe\" /language:%lang /listvoices";;
319 execstring
.replace("%exe",m_TTSexec
);
320 execstring
.replace("%lang",language
);
321 qDebug() << "init" << execstring
;
322 voicescript
= new QProcess(NULL
);
323 voicescript
->start(execstring
);
324 if(!voicescript
->waitForStarted())
327 voicescript
->waitForReadyRead();
329 QString dataRaw
= voicescript
->readAllStandardError().data();
330 result
= dataRaw
.split(",",QString::SkipEmptyParts
);
332 result
.removeFirst();
335 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",QFile::ReadOwner
|QFile::WriteOwner
|QFile::ExeOwner
336 |QFile::ReadUser
| QFile::WriteUser
| QFile::ExeUser
337 |QFile::ReadGroup
|QFile::WriteGroup
|QFile::ExeGroup
338 |QFile::ReadOther
|QFile::WriteOther
|QFile::ExeOther
);
339 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
344 void TTSSapi::updateVoices(QString language
)
346 QStringList Voices
= getVoiceList(language
);
347 ui
.voicecombo
->clear();
348 ui
.voicecombo
->addItems(Voices
);
353 bool TTSSapi::voice(QString text
,QString wavfile
)
355 QString query
= "SPEAK\t"+wavfile
+"\t"+text
+"\r\n";
356 qDebug() << "voicing" << query
;
357 voicescript
->write(query
.toUtf8());
358 voicescript
->write("SYNC\tbla\r\n");
359 voicescript
->waitForReadyRead();
365 QString query
= "QUIT\r\n";
366 voicescript
->write(query
.toUtf8());
367 voicescript
->waitForFinished();
369 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",QFile::ReadOwner
|QFile::WriteOwner
|QFile::ExeOwner
370 |QFile::ReadUser
| QFile::WriteUser
| QFile::ExeUser
371 |QFile::ReadGroup
|QFile::WriteGroup
|QFile::ExeGroup
372 |QFile::ReadOther
|QFile::WriteOther
|QFile::ExeOther
);
373 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
378 void TTSSapi::reset()
380 ui
.ttsoptions
->setText("");
381 ui
.languagecombo
->setCurrentIndex(ui
.languagecombo
->findText(defaultLanguage
));
384 void TTSSapi::showCfg()
386 // try to get config from settings
387 userSettings
->beginGroup("sapi");
388 ui
.ttsoptions
->setText(userSettings
->value("ttsoptions","").toString());
389 QString selLang
= userSettings
->value("ttslanguage",defaultLanguage
).toString();
390 QString selVoice
= userSettings
->value("ttsvoice","").toString();
391 ui
.speed
->setValue(userSettings
->value("ttsspeed",0).toInt());
392 userSettings
->endGroup();
394 // fill in language combobox
396 deviceSettings
->beginGroup("languages");
397 QStringList keys
= deviceSettings
->allKeys();
398 QStringList languages
;
399 for(int i
=0 ; i
< keys
.size();i
++)
401 languages
<< deviceSettings
->value(keys
.at(i
)).toString();
403 deviceSettings
->endGroup();
406 ui
.languagecombo
->clear();
407 ui
.languagecombo
->addItems(languages
);
410 ui
.languagecombo
->setCurrentIndex(ui
.languagecombo
->findText(selLang
));
412 // fill in voice combobox
413 updateVoices(selLang
);
416 ui
.voicecombo
->setCurrentIndex(ui
.voicecombo
->findText(selVoice
));
423 void TTSSapi::accept(void)
425 if(userSettings
!= NULL
)
427 //save settings in user config
428 userSettings
->beginGroup("sapi");
429 userSettings
->setValue("ttsoptions",ui
.ttsoptions
->text());
430 userSettings
->setValue("ttslanguage",ui
.languagecombo
->currentText());
431 userSettings
->setValue("ttsvoice",ui
.voicecombo
->currentText());
432 userSettings
->setValue("ttsspeed",QString("%1").arg(ui
.speed
->value()));
433 userSettings
->endGroup();
435 userSettings
->sync();
440 void TTSSapi::reject(void)
445 bool TTSSapi::configOk()