Add missing keywords property.
[kugel-rb.git] / rbutil / rbutilqt / tts.cpp
blobd6049f8aec29390fccbd4aeffba802c2defc3e8f
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
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"
23 // static variables
24 QMap<QString,QString> TTSBase::ttsList;
25 QMap<QString,TTSBase*> TTSBase::ttsCache;
27 // static functions
28 void TTSBase::initTTSList()
30 ttsList["espeak"] = "Espeak TTS Engine";
31 ttsList["flite"] = "Flite TTS Engine";
32 ttsList["swift"] = "Swift TTS Engine";
33 #if defined(Q_OS_WIN)
34 ttsList["sapi"] = "Sapi TTS Engine";
35 #endif
39 // function to get a specific encoder
40 TTSBase* TTSBase::getTTS(QString ttsName)
42 // check cache
43 if(ttsCache.contains(ttsName))
44 return ttsCache.value(ttsName);
46 TTSBase* tts;
47 if(ttsName == "sapi")
49 tts = new TTSSapi();
50 ttsCache[ttsName] = tts;
51 return tts;
53 else
55 tts = new TTSExes(ttsName);
56 ttsCache[ttsName] = tts;
57 return tts;
61 // get the list of encoders, nice names
62 QStringList TTSBase::getTTSList()
64 // init list if its empty
65 if(ttsList.count() == 0)
66 initTTSList();
68 return ttsList.keys();
71 // get nice name of a specific tts
72 QString TTSBase::getTTSName(QString tts)
74 if(ttsList.isEmpty())
75 initTTSList();
76 return ttsList.value(tts);
79 /*********************************************************************
80 * TTS Base
81 **********************************************************************/
82 TTSBase::TTSBase(): QObject()
87 /*********************************************************************
88 * General TTS Exes
89 **********************************************************************/
90 TTSExes::TTSExes(QString name) : TTSBase()
92 m_name = name;
94 m_TemplateMap["espeak"] = "\"%exe\" \"%options\" -w \"%wavfile\" \"%text\"";
95 m_TemplateMap["flite"] = "\"%exe\" \"%options\" -o \"%wavfile\" \"%text\"";
96 m_TemplateMap["swift"] = "\"%exe\" \"%options\" -o \"%wavfile\" \"%text\"";
100 bool TTSExes::start(QString *errStr)
102 m_TTSexec = settings->ttsPath(m_name);
103 m_TTSOpts = settings->ttsOptions(m_name);
105 m_TTSTemplate = m_TemplateMap.value(m_name);
107 QFileInfo tts(m_TTSexec);
108 if(tts.exists())
110 return true;
112 else
114 *errStr = tr("TTS executable not found");
115 return false;
119 bool TTSExes::voice(QString text,QString wavfile)
121 QString execstring = m_TTSTemplate;
123 execstring.replace("%exe",m_TTSexec);
124 execstring.replace("%options",m_TTSOpts);
125 execstring.replace("%wavfile",wavfile);
126 execstring.replace("%text",text);
127 //qDebug() << "voicing" << execstring;
128 QProcess::execute(execstring);
129 return true;
133 void TTSExes::showCfg()
135 #ifndef CONSOLE
136 TTSExesGui gui;
137 #else
138 TTSExesGuiCli gui;
139 #endif
140 gui.setCfg(settings);
141 gui.showCfg(m_name);
144 bool TTSExes::configOk()
146 QString path = settings->ttsPath(m_name);
148 if (QFileInfo(path).exists())
149 return true;
151 return false;
154 /*********************************************************************
155 * TTS Sapi
156 **********************************************************************/
157 TTSSapi::TTSSapi() : TTSBase()
159 m_TTSTemplate = "cscript //nologo \"%exe\" /language:%lang /voice:\"%voice\" /speed:%speed \"%options\"";
160 defaultLanguage ="english";
161 m_sapi4 =false;
165 bool TTSSapi::start(QString *errStr)
168 m_TTSOpts = settings->ttsOptions("sapi");
169 m_TTSLanguage =settings->ttsLang("sapi");
170 m_TTSVoice=settings->ttsVoice("sapi");
171 m_TTSSpeed=QString("%1").arg(settings->ttsSpeed("sapi"));
172 m_sapi4 = settings->ttsUseSapi4();
174 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
175 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
176 m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs";
178 QFileInfo tts(m_TTSexec);
179 if(!tts.exists())
181 *errStr = tr("Could not copy the Sapi-script");
182 return false;
184 // create the voice process
185 QString execstring = m_TTSTemplate;
186 execstring.replace("%exe",m_TTSexec);
187 execstring.replace("%options",m_TTSOpts);
188 execstring.replace("%lang",m_TTSLanguage);
189 execstring.replace("%voice",m_TTSVoice);
190 execstring.replace("%speed",m_TTSSpeed);
192 if(m_sapi4)
193 execstring.append(" /sapi4 ");
195 qDebug() << "init" << execstring;
196 voicescript = new QProcess(NULL);
197 //connect(voicescript,SIGNAL(readyReadStandardError()),this,SLOT(error()));
199 voicescript->start(execstring);
200 if(!voicescript->waitForStarted())
202 *errStr = tr("Could not start the Sapi-script");
203 return false;
206 if(!voicescript->waitForReadyRead(300))
208 *errStr = voicescript->readAllStandardError();
209 if(*errStr != "")
210 return false;
212 return true;
216 QStringList TTSSapi::getVoiceList(QString language)
218 QStringList result;
220 QFile::copy(":/builtin/sapi_voice.vbs",QDir::tempPath() + "/sapi_voice.vbs");
221 m_TTSexec = QDir::tempPath() +"/sapi_voice.vbs";
223 QFileInfo tts(m_TTSexec);
224 if(!tts.exists())
225 return result;
227 // create the voice process
228 QString execstring = "cscript //nologo \"%exe\" /language:%lang /listvoices";
229 execstring.replace("%exe",m_TTSexec);
230 execstring.replace("%lang",language);
232 if(settings->ttsUseSapi4())
233 execstring.append(" /sapi4 ");
235 qDebug() << "init" << execstring;
236 voicescript = new QProcess(NULL);
237 voicescript->start(execstring);
238 if(!voicescript->waitForStarted())
239 return result;
241 voicescript->waitForReadyRead();
243 QString dataRaw = voicescript->readAllStandardError().data();
244 result = dataRaw.split(",",QString::SkipEmptyParts);
245 result.sort();
246 result.removeFirst();
247 for(int i = 0; i< result.size();i++)
249 result[i] = result.at(i).simplified();
253 delete voicescript;
254 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",QFile::ReadOwner |QFile::WriteOwner|QFile::ExeOwner
255 |QFile::ReadUser| QFile::WriteUser| QFile::ExeUser
256 |QFile::ReadGroup |QFile::WriteGroup |QFile::ExeGroup
257 |QFile::ReadOther |QFile::WriteOther |QFile::ExeOther );
258 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
260 return result;
265 bool TTSSapi::voice(QString text,QString wavfile)
267 QString query = "SPEAK\t"+wavfile+"\t"+text+"\r\n";
268 qDebug() << "voicing" << query;
269 voicescript->write(query.toLocal8Bit());
270 voicescript->write("SYNC\tbla\r\n");
271 voicescript->waitForReadyRead();
272 return true;
275 bool TTSSapi::stop()
277 QString query = "QUIT\r\n";
278 voicescript->write(query.toLocal8Bit());
279 voicescript->waitForFinished();
280 delete voicescript;
281 QFile::setPermissions(QDir::tempPath() +"/sapi_voice.vbs",QFile::ReadOwner |QFile::WriteOwner|QFile::ExeOwner
282 |QFile::ReadUser| QFile::WriteUser| QFile::ExeUser
283 |QFile::ReadGroup |QFile::WriteGroup |QFile::ExeGroup
284 |QFile::ReadOther |QFile::WriteOther |QFile::ExeOther );
285 QFile::remove(QDir::tempPath() +"/sapi_voice.vbs");
286 return true;
290 void TTSSapi::showCfg()
292 #ifndef CONSOLE
293 TTSSapiGui gui(this);
294 #else
295 TTSSapiGuiCli gui(this);
296 #endif
297 gui.setCfg(settings);
298 gui.showCfg();
301 bool TTSSapi::configOk()
303 if(settings->ttsVoice("sapi").isEmpty())
304 return false;
305 return true;