Save the internal name for tts / encoder in the configuration file, not the displayed...
[Rockbox.git] / rbutil / rbutilqt / tts.cpp
blobeb78f31006486432f4ab027cc533ead3bfc5bf09
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
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 ****************************************************************************/
20 #include "tts.h"
24 static QMap<QString,QString> ttsList;
25 static QMap<QString,TTSBase*> ttsCache;
27 void initTTSList()
29 ttsList["espeak"] = "Espeak TTS Engine";
30 ttsList["flite"] = "Flite TTS Engine";
31 ttsList["swift"] = "Swift TTS Engine";
32 #if defined(Q_OS_WIN)
33 ttsList["sapi"] = "Sapi 5 TTS Engine";
34 #endif
38 // function to get a specific encoder
39 TTSBase* getTTS(QString ttsName)
41 // check cache
42 if(ttsCache.contains(ttsName))
43 return ttsCache.value(ttsName);
45 TTSBase* tts;
46 if(ttsName == "sapi")
48 tts = new TTSSapi();
49 ttsCache[ttsName] = tts;
50 return tts;
52 else
54 tts = new TTSExes(ttsName);
55 ttsCache[ttsName] = tts;
56 return tts;
60 // get the list of encoders, nice names
61 QStringList getTTSList()
63 // init list if its empty
64 if(ttsList.count() == 0)
65 initTTSList();
67 return ttsList.keys();
70 QString getTTSName(QString tts)
72 if(ttsList.isEmpty())
73 initTTSList();
74 return ttsList.value(tts);
77 /*********************************************************************
78 * TTS Base
79 **********************************************************************/
80 TTSBase::TTSBase(): QObject()
85 /*********************************************************************
86 * General TTS Exes
87 **********************************************************************/
88 TTSExes::TTSExes(QString name) : TTSBase()
90 m_name = name;
92 m_TemplateMap["espeak"] = "\"%exe\" \"%options\" -w \"%wavfile\" \"%text\"";
93 m_TemplateMap["flite"] = "\"%exe\" \"%options\" -o \"%wavfile\" \"%text\"";
94 m_TemplateMap["swift"] = "\"%exe\" \"%options\" -o \"%wavfile\" \"%text\"";
98 bool TTSExes::start(QString *errStr)
100 m_TTSexec = settings->ttsPath(m_name);
101 m_TTSOpts = settings->ttsOptions(m_name);
103 m_TTSTemplate = m_TemplateMap.value(m_name);
105 QFileInfo tts(m_TTSexec);
106 if(tts.exists())
108 return true;
110 else
112 *errStr = tr("TTS executable not found");
113 return false;
117 bool TTSExes::voice(QString text,QString wavfile)
119 QString execstring = m_TTSTemplate;
121 execstring.replace("%exe",m_TTSexec);
122 execstring.replace("%options",m_TTSOpts);
123 execstring.replace("%wavfile",wavfile);
124 execstring.replace("%text",text);
125 //qDebug() << "voicing" << execstring;
126 QProcess::execute(execstring);
127 return true;
131 void TTSExes::showCfg()
133 TTSExesGui gui;
134 gui.setCfg(settings);
135 gui.showCfg(m_name);
138 bool TTSExes::configOk()
140 QString path = settings->ttsPath(m_name);
142 if (QFileInfo(path).exists())
143 return true;
145 return false;
148 /*********************************************************************
149 * TTS Sapi
150 **********************************************************************/
151 TTSSapi::TTSSapi() : TTSBase()
153 m_TTSTemplate = "cscript //nologo \"%exe\" /language:%lang /voice:\"%voice\" /speed:%speed \"%options\"";
154 defaultLanguage ="english";
159 bool TTSSapi::start(QString *errStr)
162 m_TTSOpts = settings->ttsOptions("sapi");
163 m_TTSLanguage =settings->ttsLang("sapi");
164 m_TTSVoice=settings->ttsVoice("sapi");
165 m_TTSSpeed=settings->ttsSpeed("sapi");
167 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
168 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
169 m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs";
171 QFileInfo tts(m_TTSexec);
172 if(!tts.exists())
174 *errStr = tr("Could not copy the Sapi-script");
175 return false;
177 // create the voice process
178 QString execstring = m_TTSTemplate;
179 execstring.replace("%exe",m_TTSexec);
180 execstring.replace("%options",m_TTSOpts);
181 execstring.replace("%lang",m_TTSLanguage);
182 execstring.replace("%voice",m_TTSVoice);
183 execstring.replace("%speed",m_TTSSpeed);
185 qDebug() << "init" << execstring;
186 voicescript = new QProcess(NULL);
187 //connect(voicescript,SIGNAL(readyReadStandardError()),this,SLOT(error()));
189 voicescript->start(execstring);
190 if(!voicescript->waitForStarted())
192 *errStr = tr("Could not start the Sapi-script");
193 return false;
196 if(!voicescript->waitForReadyRead(100))
198 *errStr = voicescript->readAllStandardError();
199 if(*errStr != "")
200 return false;
202 return true;
206 QStringList TTSSapi::getVoiceList(QString language)
208 QStringList result;
210 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
211 m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs";
213 QFileInfo tts(m_TTSexec);
214 if(!tts.exists())
215 return result;
217 // create the voice process
218 QString execstring = "cscript //nologo \"%exe\" /language:%lang /listvoices";;
219 execstring.replace("%exe",m_TTSexec);
220 execstring.replace("%lang",language);
221 qDebug() << "init" << execstring;
222 voicescript = new QProcess(NULL);
223 voicescript->start(execstring);
224 if(!voicescript->waitForStarted())
225 return result;
227 voicescript->waitForReadyRead();
229 QString dataRaw = voicescript->readAllStandardError().data();
230 result = dataRaw.split(",",QString::SkipEmptyParts);
231 result.sort();
232 result.removeFirst();
234 delete voicescript;
235 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",QFile::ReadOwner |QFile::WriteOwner|QFile::ExeOwner
236 |QFile::ReadUser| QFile::WriteUser| QFile::ExeUser
237 |QFile::ReadGroup |QFile::WriteGroup |QFile::ExeGroup
238 |QFile::ReadOther |QFile::WriteOther |QFile::ExeOther );
239 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
241 return result;
246 bool TTSSapi::voice(QString text,QString wavfile)
248 QString query = "SPEAK\t"+wavfile+"\t"+text+"\r\n";
249 qDebug() << "voicing" << query;
250 voicescript->write(query.toUtf8());
251 voicescript->write("SYNC\tbla\r\n");
252 voicescript->waitForReadyRead();
253 return true;
256 bool TTSSapi::stop()
258 QString query = "QUIT\r\n";
259 voicescript->write(query.toUtf8());
260 voicescript->waitForFinished();
261 delete voicescript;
262 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",QFile::ReadOwner |QFile::WriteOwner|QFile::ExeOwner
263 |QFile::ReadUser| QFile::WriteUser| QFile::ExeUser
264 |QFile::ReadGroup |QFile::WriteGroup |QFile::ExeGroup
265 |QFile::ReadOther |QFile::WriteOther |QFile::ExeOther );
266 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
267 return true;
271 void TTSSapi::showCfg()
273 TTSSapiGui gui(this);
274 gui.setCfg(settings);
275 gui.showCfg();
278 bool TTSSapi::configOk()
280 return true;