1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2007 by Dominik Wenger
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 ****************************************************************************/
21 #include "rbsettings.h"
23 TalkFileCreator::TalkFileCreator(QObject
* parent
): QObject(parent
)
28 //! \brief Creates Talkfiles.
30 //! \param logger A pointer to a Loggerobject
31 bool TalkFileCreator::createTalkFiles(ProgressloggerInterface
* logger
)
36 QMultiMap
<QString
,QString
> fileList
;
37 QMultiMap
<QString
,QString
> dirList
;
38 QStringList toSpeakList
, voicedEntries
, encodedEntries
;
41 m_logger
->addItem(tr("Starting Talk file generation"),LOGINFO
);
44 m_tts
= TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts
).toString());
46 if(!m_tts
->start(&errStr
))
48 m_logger
->addItem(errStr
.trimmed(),LOGERROR
);
49 m_logger
->addItem(tr("Init of TTS engine failed"),LOGERROR
);
50 m_logger
->setFinished();
55 m_enc
= EncBase::getEncoder(this,RbSettings::value(RbSettings::CurEncoder
).toString());
59 m_logger
->addItem(tr("Init of Encoder engine failed"),LOGERROR
);
60 m_logger
->setFinished();
65 QCoreApplication::processEvents();
67 connect(logger
,SIGNAL(aborted()),this,SLOT(abort()));
68 m_logger
->setProgressMax(0);
70 // read in Maps of paths - file/dirnames
71 m_logger
->addItem(tr("Reading Filelist..."),LOGINFO
);
72 if(createDirAndFileMaps(m_dir
,&dirList
,&fileList
) == false)
74 m_logger
->addItem(tr("Talk file creation aborted"),LOGERROR
);
79 // create List of all Files/Dirs to speak
80 QMapIterator
<QString
, QString
> dirIt(dirList
);
81 while (dirIt
.hasNext())
84 // insert only non dublicate dir entries into list
85 if(!toSpeakList
.contains(dirIt
.value()))
87 qDebug() << "toSpeaklist dir:" << dirIt
.value();
88 toSpeakList
.append(dirIt
.value());
91 QMapIterator
<QString
, QString
> fileIt(fileList
);
92 while (fileIt
.hasNext())
95 // insert only non- dublictae file entries into list
96 if(!toSpeakList
.contains(fileIt
.value()))
99 toSpeakList
.append(stripExtension(fileIt
.value()));
101 toSpeakList
.append(fileIt
.value());
106 m_logger
->addItem(tr("Voicing entries..."),LOGINFO
);
107 TTSStatus voiceStatus
= voiceList(toSpeakList
,voicedEntries
);
108 if(voiceStatus
== FatalError
)
110 doAbort(toSpeakList
);
115 m_logger
->addItem(tr("Encoding files..."),LOGINFO
);
116 if(encodeList(voicedEntries
,encodedEntries
) == false)
118 doAbort(toSpeakList
);
122 // Copying talk files
123 m_logger
->addItem(tr("Copying Talkfile for Dirs..."),LOGINFO
);
124 if(copyTalkDirFiles(dirList
,&errStr
) == false)
126 m_logger
->addItem(errStr
,LOGERROR
);
127 doAbort(toSpeakList
);
131 //Copying file talk files
132 m_logger
->addItem(tr("Copying Talkfile for Files..."),LOGINFO
);
133 if(copyTalkFileFiles(fileList
,&errStr
) == false)
135 m_logger
->addItem(errStr
,LOGERROR
);
136 doAbort(toSpeakList
);
140 // Deleting left overs
141 if( !cleanup(toSpeakList
))
146 m_logger
->addItem(tr("Finished creating Talk files"),LOGOK
);
147 m_logger
->setProgressMax(1);
148 m_logger
->setProgressValue(1);
149 m_logger
->setFinished();
154 //! \brief resets the internal progress counter, and sets the Progressbar in the Logger
156 //! \param max The maximum to shich the Progressbar is set.
157 void TalkFileCreator::resetProgress(int max
)
160 m_logger
->setProgressMax(max
);
161 m_logger
->setProgressValue(m_progress
);
164 //! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed
166 //! \param filename The filename from which to strip the Extension
167 //! \returns the modified string
168 QString
TalkFileCreator::stripExtension(QString filename
)
170 if(filename
.lastIndexOf(".") != -1)
171 return filename
.left(filename
.lastIndexOf("."));
176 //! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder
178 //! \param cleanupList List of filenames to give to cleanup()
179 void TalkFileCreator::doAbort(QStringList cleanupList
)
181 cleanup(cleanupList
);
182 m_logger
->setProgressMax(1);
183 m_logger
->setProgressValue(0);
184 m_logger
->setFinished();
189 //! \brief Creates MultiMaps (paths -> File/dir names) of all Dirs and Files in a Folder.
190 //! Depending on settings, either Dirs or Files can be ignored.
191 //! Also recursion is controlled by settings
193 //! \param startDir The dir where it beginns scanning
194 //! \param dirMap The MulitMap where the dirs are stored
195 //! \param filMap The MultiMap where Files are stored
196 //! \returns true on Success, false if User aborted.
197 bool TalkFileCreator::createDirAndFileMaps(QDir startDir
,QMultiMap
<QString
,QString
> *dirMap
,QMultiMap
<QString
,QString
> *fileMap
)
200 QDirIterator::IteratorFlags flags
= QDirIterator::NoIteratorFlags
;
202 flags
= QDirIterator::Subdirectories
;
204 QDirIterator
it(startDir
,flags
);
206 // read in Maps of paths - file/dirnames
215 QFileInfo fileInf
= it
.fileInfo();
220 QDir dir
= fileInf
.dir();
223 if(!dir
.dirName().isEmpty() && m_talkFolders
)
225 qDebug() << "Dir: " << dir
.dirName() << " - " << dir
.path();
226 dirMap
->insert(dir
.path(),dir
.dirName());
232 if( !fileInf
.fileName().isEmpty() && !fileInf
.fileName().endsWith(".talk") && m_talkFiles
)
234 qDebug() << "File: " << fileInf
.fileName() << " - " << fileInf
.path();
235 fileMap
->insert(fileInf
.path(),fileInf
.fileName());
238 QCoreApplication::processEvents();
243 //! \brief Voices a List of string to the temp dir. Progress is handled inside.
245 //! \param toSpeak QStringList with the Entries to voice.
246 //! \param errString pointer to where the Error cause is written
247 //! \returns true on success, false on error or user abort
248 TTSStatus
TalkFileCreator::voiceList(QStringList toSpeak
,QStringList
& voicedEntries
)
250 resetProgress(toSpeak
.size());
253 bool warnings
= false;
254 for(int i
=0; i
< toSpeak
.size(); i
++)
258 m_logger
->addItem(tr("Talk file creation aborted"), LOGERROR
);
262 QString filename
= QDir::tempPath()+ "/"+ toSpeak
[i
] + ".wav";
265 TTSStatus status
= m_tts
->voice(toSpeak
[i
],filename
, &error
);
266 if(status
== Warning
)
269 m_logger
->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak
[i
]).arg(error
),
272 else if (status
== FatalError
)
274 m_logger
->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak
[i
]).arg(error
),
279 voicedEntries
.append(toSpeak
[i
]);
280 m_logger
->setProgressValue(++m_progress
);
281 QCoreApplication::processEvents();
290 //! \brief Encodes a List of strings from/to the temp dir. Progress is handled inside.
291 //! It expects the inputfile in the temp dir with the name in the List appended with ".wav"
293 //! \param toSpeak QStringList with the Entries to encode.
294 //! \param errString pointer to where the Error cause is written
295 //! \returns true on success, false on error or user abort
296 bool TalkFileCreator::encodeList(QStringList toEncode
,QStringList
& encodedEntries
)
298 resetProgress(toEncode
.size());
299 for(int i
=0; i
< toEncode
.size(); i
++)
303 m_logger
->addItem(tr("Talk file creation aborted"), LOGERROR
);
307 QString wavfilename
= QDir::tempPath()+ "/"+ toEncode
[i
] + ".wav";
308 QString filename
= QDir::tempPath()+ "/"+ toEncode
[i
] + ".talk";
310 if(!m_enc
->encode(wavfilename
,filename
))
312 m_logger
->addItem(tr("Encoding of %1 failed").arg(filename
), LOGERROR
);
315 encodedEntries
.append(toEncode
[i
]);
316 m_logger
->setProgressValue(++m_progress
);
317 QCoreApplication::processEvents();
322 //! \brief copys Talkfile for Dirs from the temp dir to the target. Progress and installlog is handled inside
324 //! \param dirMap a MultiMap of Paths -> Dirnames
325 //! \param errString Pointer to a QString where the error cause is written.
326 //! \returns true on success, false on error or user abort
327 bool TalkFileCreator::copyTalkDirFiles(QMultiMap
<QString
,QString
> dirMap
,QString
* errString
)
329 resetProgress(dirMap
.size());
331 QSettings
installlog(m_mountpoint
+ "/.rockbox/rbutil.log", QSettings::IniFormat
, 0);
332 installlog
.beginGroup("talkfiles");
334 QMapIterator
<QString
, QString
> it(dirMap
);
340 *errString
= tr("Talk file creation aborted");
344 QString source
= QDir::tempPath()+ "/"+ it
.value() + ".talk";
346 if(!QFileInfo(source
).exists())
347 continue; // this file was skipped in one of the previous steps
349 QString target
= it
.key() + "/" + "_dirname.talk";
351 // remove target if it exists, and if we should overwrite it
352 if(m_overwriteTalk
&& QFile::exists(target
))
353 QFile::remove(target
);
356 if(!QFile::copy(source
,target
))
358 *errString
= tr("Copying of %1 to %2 failed").arg(source
).arg(target
);
363 QString now
= QDate::currentDate().toString("yyyyMMdd");
364 installlog
.setValue(target
.remove(0,m_mountpoint
.length()),now
);
366 m_logger
->setProgressValue(++m_progress
);
367 QCoreApplication::processEvents();
369 installlog
.endGroup();
374 //! \brief copys Talkfile for Files from the temp dir to the target. Progress and installlog is handled inside
376 //! \param fileMap a MultiMap of Paths -> Filenames
377 //! \param errString Pointer to a QString where the error cause is written.
378 //! \returns true on success, false on error or user abort
379 bool TalkFileCreator::copyTalkFileFiles(QMultiMap
<QString
,QString
> fileMap
,QString
* errString
)
381 resetProgress(fileMap
.size());
383 QSettings
installlog(m_mountpoint
+ "/.rockbox/rbutil.log", QSettings::IniFormat
, 0);
384 installlog
.beginGroup("talkfiles");
386 QMapIterator
<QString
, QString
> it(fileMap
);
392 *errString
= tr("Talk file creation aborted");
397 QString target
= it
.key() + "/" + it
.value() + ".talk";
399 // correct source if we hav stripExtension enabled
400 if(m_stripExtensions
)
401 source
= QDir::tempPath()+ "/"+ stripExtension(it
.value()) + ".talk";
403 source
= QDir::tempPath()+ "/"+ it
.value() + ".talk";
405 if(!QFileInfo(source
).exists())
406 continue; // this file was skipped in one of the previous steps
408 // remove target if it exists, and if we should overwrite it
409 if(m_overwriteTalk
&& QFile::exists(target
))
410 QFile::remove(target
);
413 qDebug() << "copying: " << source
<< " to " << target
;
414 if(!QFile::copy(source
,target
))
416 *errString
= tr("Copying of %1 to %2 failed").arg(source
).arg(target
);
420 // add to Install log
421 QString now
= QDate::currentDate().toString("yyyyMMdd");
422 installlog
.setValue(target
.remove(0,m_mountpoint
.length()),now
);
424 m_logger
->setProgressValue(++m_progress
);
425 QCoreApplication::processEvents();
427 installlog
.endGroup();
433 //! \brief Cleans up Files potentially left in the temp dir
435 //! \param list List of file to try to delete in the temp dir. Function appends ".wav" and ".talk" to the filenames
436 bool TalkFileCreator::cleanup(QStringList list
)
438 m_logger
->addItem(tr("Cleaning up.."),LOGINFO
);
440 for(int i
=0; i
< list
.size(); i
++)
442 if(QFile::exists(QDir::tempPath()+ "/"+ list
[i
] + ".wav"))
443 QFile::remove(QDir::tempPath()+ "/"+ list
[i
] + ".wav");
444 if(QFile::exists(QDir::tempPath()+ "/"+ list
[i
] + ".talk"))
445 QFile::remove(QDir::tempPath()+ "/"+ list
[i
] + ".talk");
447 QCoreApplication::processEvents();
452 //! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position
454 void TalkFileCreator::abort()