1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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"
24 TalkGenerator::TalkGenerator(QObject
* parent
): QObject(parent
)
29 //! \brief Creates Talkfiles.
31 TalkGenerator::Status
TalkGenerator::process(QList
<TalkEntry
>* list
,int wavtrimth
)
35 bool warnings
= false;
38 emit
logItem(tr("Starting TTS Engine"), LOGINFO
);
39 m_tts
= TTSBase::getTTS(this, RbSettings::value(RbSettings::Tts
).toString());
42 qDebug() << "[TalkGenerator] getting the TTS object failed!";
43 emit
logItem(tr("Init of TTS engine failed"), LOGERROR
);
47 if(!m_tts
->start(&errStr
))
49 emit
logItem(errStr
.trimmed(),LOGERROR
);
50 emit
logItem(tr("Init of TTS engine failed"), LOGERROR
);
54 QCoreApplication::processEvents();
57 emit
logItem(tr("Starting Encoder Engine"),LOGINFO
);
58 m_enc
= EncoderBase::getEncoder(this,SystemInfo::value(SystemInfo::CurEncoder
).toString());
61 emit
logItem(tr("Init of Encoder engine failed"),LOGERROR
);
66 QCoreApplication::processEvents();
68 emit
logProgress(0,0);
71 emit
logItem(tr("Voicing entries..."),LOGINFO
);
72 Status voiceStatus
= voiceList(list
,wavtrimth
);
73 if(voiceStatus
== eERROR
)
80 else if( voiceStatus
== eWARNING
)
83 QCoreApplication::processEvents();
86 emit
logItem(tr("Encoding files..."),LOGINFO
);
87 Status encoderStatus
= encodeList(list
);
88 if( encoderStatus
== eERROR
)
95 else if( voiceStatus
== eWARNING
)
98 QCoreApplication::processEvents();
102 emit
logProgress(1,1);
109 //! \brief Voices a List of string
111 TalkGenerator::Status
TalkGenerator::voiceList(QList
<TalkEntry
>* list
,int wavtrimth
)
113 int progressMax
= list
->size();
115 emit
logProgress(m_progress
,progressMax
);
118 QStringList duplicates
;
120 bool warnings
= false;
121 for(int i
=0; i
< list
->size(); i
++)
125 emit
logItem(tr("Voicing aborted"), LOGERROR
);
129 // skip duplicated wav entrys
130 if(!duplicates
.contains(list
->at(i
).wavfilename
))
131 duplicates
.append(list
->at(i
).wavfilename
);
134 qDebug() << "[TalkGenerator] duplicate skipped";
135 (*list
)[i
].voiced
= true;
136 emit
logProgress(++m_progress
,progressMax
);
140 // skip already voiced entrys
141 if(list
->at(i
).voiced
== true)
143 emit
logProgress(++m_progress
,progressMax
);
146 // skip entry whith empty text
147 if(list
->at(i
).toSpeak
== "")
149 emit
logProgress(++m_progress
,progressMax
);
155 qDebug() << "[TalkGenerator] voicing: " << list
->at(i
).toSpeak
156 << "to" << list
->at(i
).wavfilename
;
157 TTSStatus status
= m_tts
->voice(list
->at(i
).toSpeak
,list
->at(i
).wavfilename
, &error
);
158 if(status
== Warning
)
161 emit
logItem(tr("Voicing of %1 failed: %2").arg(list
->at(i
).toSpeak
).arg(error
),
164 else if (status
== FatalError
)
166 emit
logItem(tr("Voicing of %1 failed: %2").arg(list
->at(i
).toSpeak
).arg(error
),
171 (*list
)[i
].voiced
= true;
177 if(wavtrim(list
->at(i
).wavfilename
.toLocal8Bit().data(),
178 wavtrimth
, buffer
, 255))
180 qDebug() << "[TalkGenerator] wavtrim returned error on"
181 << list
->at(i
).wavfilename
;
186 emit
logProgress(++m_progress
,progressMax
);
187 QCoreApplication::processEvents();
196 //! \brief Encodes a List of strings
198 TalkGenerator::Status
TalkGenerator::encodeList(QList
<TalkEntry
>* list
)
200 QStringList duplicates
;
202 int progressMax
= list
->size();
204 emit
logProgress(m_progress
,progressMax
);
206 for(int i
=0; i
< list
->size(); i
++)
210 emit
logItem(tr("Encoding aborted"), LOGERROR
);
214 //skip non-voiced entrys
215 if(list
->at(i
).voiced
== false)
217 qDebug() << "[TalkGenerator] non voiced entry detected:"
218 << list
->at(i
).toSpeak
;
219 emit
logProgress(++m_progress
,progressMax
);
223 if(!duplicates
.contains(list
->at(i
).talkfilename
))
224 duplicates
.append(list
->at(i
).talkfilename
);
227 qDebug() << "[TalkGenerator] duplicate skipped";
228 (*list
)[i
].encoded
= true;
229 emit
logProgress(++m_progress
,progressMax
);
234 qDebug() << "[TalkGenerator] encoding " << list
->at(i
).wavfilename
235 << "to" << list
->at(i
).talkfilename
;
236 if(!m_enc
->encode(list
->at(i
).wavfilename
,list
->at(i
).talkfilename
))
238 emit
logItem(tr("Encoding of %1 failed").arg(
239 QFileInfo(list
->at(i
).wavfilename
).baseName()), LOGERROR
);
242 (*list
)[i
].encoded
= true;
243 emit
logProgress(++m_progress
,progressMax
);
244 QCoreApplication::processEvents();
249 //! \brief slot, which is connected to the abort of the Logger.
250 //Sets a flag, so Creating Talkfiles ends at the next possible position
252 void TalkGenerator::abort()
257 QString
TalkGenerator::correctString(QString s
)
259 QString corrected
= s
;
261 int max
= m_corrections
.size();
263 corrected
= corrected
.replace(QRegExp(m_corrections
.at(i
).search
,
264 m_corrections
.at(i
).modifier
.contains("i")
265 ? Qt::CaseInsensitive
: Qt::CaseSensitive
),
266 m_corrections
.at(i
).replace
);
271 qDebug() << "[VoiceFileCreator] corrected string" << s
<< "to" << corrected
;
277 void TalkGenerator::setLang(QString name
)
281 // re-initialize corrections list
282 m_corrections
.clear();
283 QFile
correctionsFile(":/builtin/voice-corrections.txt");
284 correctionsFile
.open(QIODevice::ReadOnly
);
286 QString engine
= RbSettings::value(RbSettings::Tts
).toString();
287 TTSBase
* tts
= TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts
).toString());
290 qDebug() << "[TalkGenerator] getting the TTS object failed!";
293 QString vendor
= tts
->voiceVendor();
298 qDebug() << "[TalkGenerator] building string corrections list for"
299 << m_lang
<< engine
<< vendor
;
300 QTextStream
stream(&correctionsFile
);
301 while(!stream
.atEnd()) {
302 QString line
= stream
.readLine();
303 if(line
.startsWith(" ") || line
.length() < 10)
305 // separator is first character
306 QString separator
= line
.at(0);
308 QStringList items
= line
.split(separator
);
309 // we need to have at least 6 separate entries.
313 QRegExp
re_lang(items
.at(0));
314 QRegExp
re_engine(items
.at(1));
315 QRegExp
re_vendor(items
.at(2));
316 if(!re_lang
.exactMatch(m_lang
)) {
319 if(!re_vendor
.exactMatch(vendor
)) {
322 if(!re_engine
.exactMatch(engine
)) {
325 struct CorrectionItems co
;
326 co
.search
= items
.at(3);
327 co
.replace
= items
.at(4);
328 // Qt uses backslash for back references, Perl uses dollar sign.
329 co
.replace
.replace(QRegExp("\\$(\\d+)"), "\\\\1");
330 co
.modifier
= items
.at(5);
331 m_corrections
.append(co
);
333 correctionsFile
.close();