Handle language change events in widgets.
[maemo-rb.git] / rbutil / rbutilqt / base / talkgenerator.cpp
blob16e1b15184090869cec7fa8689c250bcf6888cd9
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
19 #include "talkgenerator.h"
20 #include "rbsettings.h"
21 #include "systeminfo.h"
22 #include "wavtrim.h"
24 TalkGenerator::TalkGenerator(QObject* parent): QObject(parent)
29 //! \brief Creates Talkfiles.
30 //!
31 TalkGenerator::Status TalkGenerator::process(QList<TalkEntry>* list,int wavtrimth)
33 m_abort = false;
34 QString errStr;
35 bool warnings = false;
37 //tts
38 emit logItem(tr("Starting TTS Engine"),LOGINFO);
39 m_tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString());
40 if(!m_tts->start(&errStr))
42 emit logItem(errStr.trimmed(),LOGERROR);
43 emit logItem(tr("Init of TTS engine failed"),LOGERROR);
44 emit done(true);
45 return eERROR;
47 QCoreApplication::processEvents();
49 // Encoder
50 emit logItem(tr("Starting Encoder Engine"),LOGINFO);
51 m_enc = EncoderBase::getEncoder(this,SystemInfo::value(SystemInfo::CurEncoder).toString());
52 if(!m_enc->start())
54 emit logItem(tr("Init of Encoder engine failed"),LOGERROR);
55 emit done(true);
56 m_tts->stop();
57 return eERROR;
59 QCoreApplication::processEvents();
61 emit logProgress(0,0);
63 // Voice entries
64 emit logItem(tr("Voicing entries..."),LOGINFO);
65 Status voiceStatus= voiceList(list,wavtrimth);
66 if(voiceStatus == eERROR)
68 m_tts->stop();
69 m_enc->stop();
70 emit done(true);
71 return eERROR;
73 else if( voiceStatus == eWARNING)
74 warnings = true;
76 QCoreApplication::processEvents();
78 // Encoding Entries
79 emit logItem(tr("Encoding files..."),LOGINFO);
80 Status encoderStatus = encodeList(list);
81 if( encoderStatus == eERROR)
83 m_tts->stop();
84 m_enc->stop();
85 emit done(true);
86 return eERROR;
88 else if( voiceStatus == eWARNING)
89 warnings = true;
91 QCoreApplication::processEvents();
93 m_tts->stop();
94 m_enc->stop();
95 emit logProgress(1,1);
97 if(warnings)
98 return eWARNING;
99 return eOK;
102 //! \brief Voices a List of string
104 TalkGenerator::Status TalkGenerator::voiceList(QList<TalkEntry>* list,int wavtrimth)
106 int progressMax = list->size();
107 int m_progress = 0;
108 emit logProgress(m_progress,progressMax);
110 QStringList errors;
111 QStringList duplicates;
113 bool warnings = false;
114 for(int i=0; i < list->size(); i++)
116 if(m_abort)
118 emit logItem(tr("Voicing aborted"), LOGERROR);
119 return eERROR;
122 // skip duplicated wav entrys
123 if(!duplicates.contains(list->at(i).wavfilename))
124 duplicates.append(list->at(i).wavfilename);
125 else
127 qDebug() << "[TalkGenerator] duplicate skipped";
128 (*list)[i].voiced = true;
129 emit logProgress(++m_progress,progressMax);
130 continue;
133 // skip already voiced entrys
134 if(list->at(i).voiced == true)
136 emit logProgress(++m_progress,progressMax);
137 continue;
139 // skip entry whith empty text
140 if(list->at(i).toSpeak == "")
142 emit logProgress(++m_progress,progressMax);
143 continue;
146 // voice entry
147 QString error;
148 qDebug() << "[TalkGenerator] voicing: " << list->at(i).toSpeak
149 << "to" << list->at(i).wavfilename;
150 TTSStatus status = m_tts->voice(list->at(i).toSpeak,list->at(i).wavfilename, &error);
151 if(status == Warning)
153 warnings = true;
154 emit logItem(tr("Voicing of %1 failed: %2").arg(list->at(i).toSpeak).arg(error),
155 LOGWARNING);
157 else if (status == FatalError)
159 emit logItem(tr("Voicing of %1 failed: %2").arg(list->at(i).toSpeak).arg(error),
160 LOGERROR);
161 return eERROR;
163 else
164 (*list)[i].voiced = true;
166 // wavtrim if needed
167 if(wavtrimth != -1)
169 char buffer[255];
170 if(wavtrim(list->at(i).wavfilename.toLocal8Bit().data(),
171 wavtrimth, buffer, 255))
173 qDebug() << "[TalkGenerator] wavtrim returned error on"
174 << list->at(i).wavfilename;
175 return eERROR;
179 emit logProgress(++m_progress,progressMax);
180 QCoreApplication::processEvents();
182 if(warnings)
183 return eWARNING;
184 else
185 return eOK;
189 //! \brief Encodes a List of strings
191 TalkGenerator::Status TalkGenerator::encodeList(QList<TalkEntry>* list)
193 QStringList duplicates;
195 int progressMax = list->size();
196 int m_progress = 0;
197 emit logProgress(m_progress,progressMax);
199 for(int i=0; i < list->size(); i++)
201 if(m_abort)
203 emit logItem(tr("Encoding aborted"), LOGERROR);
204 return eERROR;
207 //skip non-voiced entrys
208 if(list->at(i).voiced == false)
210 qDebug() << "[TalkGenerator] non voiced entry detected:"
211 << list->at(i).toSpeak;
212 emit logProgress(++m_progress,progressMax);
213 continue;
215 //skip duplicates
216 if(!duplicates.contains(list->at(i).talkfilename))
217 duplicates.append(list->at(i).talkfilename);
218 else
220 qDebug() << "[TalkGenerator] duplicate skipped";
221 (*list)[i].encoded = true;
222 emit logProgress(++m_progress,progressMax);
223 continue;
226 //encode entry
227 qDebug() << "[TalkGenerator] encoding " << list->at(i).wavfilename
228 << "to" << list->at(i).talkfilename;
229 if(!m_enc->encode(list->at(i).wavfilename,list->at(i).talkfilename))
231 emit logItem(tr("Encoding of %1 failed").arg(
232 QFileInfo(list->at(i).wavfilename).baseName()), LOGERROR);
233 return eERROR;
235 (*list)[i].encoded = true;
236 emit logProgress(++m_progress,progressMax);
237 QCoreApplication::processEvents();
239 return eOK;
242 //! \brief slot, which is connected to the abort of the Logger.
243 //Sets a flag, so Creating Talkfiles ends at the next possible position
245 void TalkGenerator::abort()
247 m_abort = true;
250 QString TalkGenerator::correctString(QString s)
252 QString corrected = s;
253 int i = 0;
254 int max = m_corrections.size();
255 while(i < max) {
256 corrected = corrected.replace(QRegExp(m_corrections.at(i).search,
257 m_corrections.at(i).modifier.contains("i")
258 ? Qt::CaseInsensitive : Qt::CaseSensitive),
259 m_corrections.at(i).replace);
260 i++;
263 if(corrected != s)
264 qDebug() << "[VoiceFileCreator] corrected string" << s << "to" << corrected;
266 return corrected;
267 m_abort = true;
270 void TalkGenerator::setLang(QString name)
272 m_lang = name;
274 // re-initialize corrections list
275 m_corrections.clear();
276 QFile correctionsFile(":/builtin/voice-corrections.txt");
277 correctionsFile.open(QIODevice::ReadOnly);
279 QString engine = RbSettings::value(RbSettings::Tts).toString();
280 TTSBase* tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString());
281 QString vendor = tts->voiceVendor();
282 delete tts;
284 if(m_lang.isEmpty())
285 m_lang = "english";
286 qDebug() << "[TalkGenerator] building string corrections list for"
287 << m_lang << engine << vendor;
288 QTextStream stream(&correctionsFile);
289 while(!stream.atEnd()) {
290 QString line = stream.readLine();
291 if(line.startsWith(" ") || line.length() < 10)
292 continue;
293 // separator is first character
294 QString separator = line.at(0);
295 line.remove(0, 1);
296 QStringList items = line.split(separator);
297 // we need to have at least 6 separate entries.
298 if(items.size() < 6)
299 continue;
301 QRegExp re_lang(items.at(0));
302 QRegExp re_engine(items.at(1));
303 QRegExp re_vendor(items.at(2));
304 if(!re_lang.exactMatch(m_lang)) {
305 continue;
307 if(!re_vendor.exactMatch(vendor)) {
308 continue;
310 if(!re_engine.exactMatch(engine)) {
311 continue;
313 struct CorrectionItems co;
314 co.search = items.at(3);
315 co.replace = items.at(4);
316 // Qt uses backslash for back references, Perl uses dollar sign.
317 co.replace.replace(QRegExp("\\$(\\d+)"), "\\\\1");
318 co.modifier = items.at(5);
319 m_corrections.append(co);
321 correctionsFile.close();