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 ****************************************************************************/
22 TalkFileCreator::TalkFileCreator(QObject
* parent
): QObject(parent
)
27 //! \brief Creates Talkfiles.
29 //! \param logger A pointer to a Loggerobject
30 bool TalkFileCreator::createTalkFiles(ProgressloggerInterface
* logger
)
35 QMultiMap
<QString
,QString
> fileList
;
36 QMultiMap
<QString
,QString
> dirList
;
37 QStringList toSpeakList
, voicedEntries
, encodedEntries
;
40 m_logger
->addItem(tr("Starting Talk file generation"),LOGINFO
);
43 m_tts
= TTSBase::getTTS(settings
->curTTS());
44 m_tts
->setCfg(settings
);
46 if(!m_tts
->start(&errStr
))
48 m_logger
->addItem(errStr
.trimmed(),LOGERROR
);
49 m_logger
->addItem(tr("Init of TTS engine failed"),LOGERROR
);
55 m_enc
= EncBase::getEncoder(settings
->curEncoder());
56 m_enc
->setCfg(settings
);
60 m_logger
->addItem(tr("Init of Encoder engine failed"),LOGERROR
);
66 QCoreApplication::processEvents();
68 connect(logger
,SIGNAL(aborted()),this,SLOT(abort()));
69 m_logger
->setProgressMax(0);
71 // read in Maps of paths - file/dirnames
72 m_logger
->addItem(tr("Reading Filelist..."),LOGINFO
);
73 if(createDirAndFileMaps(m_dir
,&dirList
,&fileList
) == false)
75 m_logger
->addItem(tr("Talk file creation aborted"),LOGERROR
);
80 // create List of all Files/Dirs to speak
81 QMapIterator
<QString
, QString
> dirIt(dirList
);
82 while (dirIt
.hasNext())
85 // insert only non dublicate dir entries into list
86 if(!toSpeakList
.contains(dirIt
.value()))
88 qDebug() << "toSpeaklist dir:" << dirIt
.value();
89 toSpeakList
.append(dirIt
.value());
92 QMapIterator
<QString
, QString
> fileIt(fileList
);
93 while (fileIt
.hasNext())
96 // insert only non- dublictae file entries into list
97 if(!toSpeakList
.contains(fileIt
.value()))
100 toSpeakList
.append(stripExtension(fileIt
.value()));
102 toSpeakList
.append(fileIt
.value());
107 m_logger
->addItem(tr("Voicing entries..."),LOGINFO
);
108 TTSStatus voiceStatus
= voiceList(toSpeakList
,voicedEntries
);
109 if(voiceStatus
== FatalError
)
111 doAbort(toSpeakList
);
116 m_logger
->addItem(tr("Encoding files..."),LOGINFO
);
117 if(encodeList(voicedEntries
,encodedEntries
) == false)
119 doAbort(toSpeakList
);
123 // Copying talk files
124 m_logger
->addItem(tr("Copying Talkfile for Dirs..."),LOGINFO
);
125 if(copyTalkDirFiles(dirList
,&errStr
) == false)
127 m_logger
->addItem(errStr
,LOGERROR
);
128 doAbort(toSpeakList
);
132 //Copying file talk files
133 m_logger
->addItem(tr("Copying Talkfile for Files..."),LOGINFO
);
134 if(copyTalkFileFiles(fileList
,&errStr
) == false)
136 m_logger
->addItem(errStr
,LOGERROR
);
137 doAbort(toSpeakList
);
141 // Deleting left overs
142 if( !cleanup(toSpeakList
))
147 m_logger
->addItem(tr("Finished creating Talk files"),LOGOK
);
148 m_logger
->setProgressMax(1);
149 m_logger
->setProgressValue(1);
155 //! \brief resets the internal progress counter, and sets the Progressbar in the Logger
157 //! \param max The maximum to shich the Progressbar is set.
158 void TalkFileCreator::resetProgress(int max
)
161 m_logger
->setProgressMax(max
);
162 m_logger
->setProgressValue(m_progress
);
165 //! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed
167 //! \param filename The filename from which to strip the Extension
168 //! \returns the modified string
169 QString
TalkFileCreator::stripExtension(QString filename
)
171 if(filename
.lastIndexOf(".") != -1)
172 return filename
.left(filename
.lastIndexOf("."));
177 //! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder
179 //! \param cleanupList List of filenames to give to cleanup()
180 void TalkFileCreator::doAbort(QStringList cleanupList
)
182 cleanup(cleanupList
);
183 m_logger
->setProgressMax(1);
184 m_logger
->setProgressValue(0);
190 //! \brief Creates MultiMaps (paths -> File/dir names) of all Dirs and Files in a Folder.
191 //! Depending on settings, either Dirs or Files can be ignored.
192 //! Also recursion is controlled by settings
194 //! \param startDir The dir where it beginns scanning
195 //! \param dirMap The MulitMap where the dirs are stored
196 //! \param filMap The MultiMap where Files are stored
197 //! \returns true on Success, false if User aborted.
198 bool TalkFileCreator::createDirAndFileMaps(QDir startDir
,QMultiMap
<QString
,QString
> *dirMap
,QMultiMap
<QString
,QString
> *fileMap
)
201 QDirIterator::IteratorFlags flags
= QDirIterator::NoIteratorFlags
;
203 flags
= QDirIterator::Subdirectories
;
205 QDirIterator
it(startDir
,flags
);
207 // read in Maps of paths - file/dirnames
216 QFileInfo fileInf
= it
.fileInfo();
221 QDir dir
= fileInf
.dir();
224 if(!dir
.dirName().isEmpty() && m_talkFolders
)
226 qDebug() << "Dir: " << dir
.dirName() << " - " << dir
.path();
227 dirMap
->insert(dir
.path(),dir
.dirName());
233 if( !fileInf
.fileName().isEmpty() && !fileInf
.fileName().endsWith(".talk") && m_talkFiles
)
235 qDebug() << "File: " << fileInf
.fileName() << " - " << fileInf
.path();
236 fileMap
->insert(fileInf
.path(),fileInf
.fileName());
239 QCoreApplication::processEvents();
244 //! \brief Voices a List of string to the temp dir. Progress is handled inside.
246 //! \param toSpeak QStringList with the Entries to voice.
247 //! \param errString pointer to where the Error cause is written
248 //! \returns true on success, false on error or user abort
249 TTSStatus
TalkFileCreator::voiceList(QStringList toSpeak
,QStringList
& voicedEntries
)
251 resetProgress(toSpeak
.size());
254 bool warnings
= false;
255 for(int i
=0; i
< toSpeak
.size(); i
++)
259 m_logger
->addItem(tr("Talk file creation aborted"), LOGERROR
);
263 QString filename
= QDir::tempPath()+ "/"+ toSpeak
[i
] + ".wav";
266 TTSStatus status
= m_tts
->voice(toSpeak
[i
],filename
, &error
);
267 if(status
== Warning
)
270 m_logger
->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak
[i
]).arg(error
),
273 else if (status
== FatalError
)
275 m_logger
->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak
[i
]).arg(error
),
280 voicedEntries
.append(toSpeak
[i
]);
281 m_logger
->setProgressValue(++m_progress
);
282 QCoreApplication::processEvents();
291 //! \brief Encodes a List of strings from/to the temp dir. Progress is handled inside.
292 //! It expects the inputfile in the temp dir with the name in the List appended with ".wav"
294 //! \param toSpeak QStringList with the Entries to encode.
295 //! \param errString pointer to where the Error cause is written
296 //! \returns true on success, false on error or user abort
297 bool TalkFileCreator::encodeList(QStringList toEncode
,QStringList
& encodedEntries
)
299 resetProgress(toEncode
.size());
300 for(int i
=0; i
< toEncode
.size(); i
++)
304 m_logger
->addItem(tr("Talk file creation aborted"), LOGERROR
);
308 QString wavfilename
= QDir::tempPath()+ "/"+ toEncode
[i
] + ".wav";
309 QString filename
= QDir::tempPath()+ "/"+ toEncode
[i
] + ".talk";
311 if(!m_enc
->encode(wavfilename
,filename
))
313 m_logger
->addItem(tr("Encoding of %1 failed").arg(filename
), LOGERROR
);
316 encodedEntries
.append(toEncode
[i
]);
317 m_logger
->setProgressValue(++m_progress
);
318 QCoreApplication::processEvents();
323 //! \brief copys Talkfile for Dirs from the temp dir to the target. Progress and installlog is handled inside
325 //! \param dirMap a MultiMap of Paths -> Dirnames
326 //! \param errString Pointer to a QString where the error cause is written.
327 //! \returns true on success, false on error or user abort
328 bool TalkFileCreator::copyTalkDirFiles(QMultiMap
<QString
,QString
> dirMap
,QString
* errString
)
330 resetProgress(dirMap
.size());
332 QSettings
installlog(m_mountpoint
+ "/.rockbox/rbutil.log", QSettings::IniFormat
, 0);
333 installlog
.beginGroup("talkfiles");
335 QMapIterator
<QString
, QString
> it(dirMap
);
341 *errString
= tr("Talk file creation aborted");
345 QString source
= QDir::tempPath()+ "/"+ it
.value() + ".talk";
347 if(!QFileInfo(source
).exists())
348 continue; // this file was skipped in one of the previous steps
350 QString target
= it
.key() + "/" + "_dirname.talk";
352 // remove target if it exists, and if we should overwrite it
353 if(m_overwriteTalk
&& QFile::exists(target
))
354 QFile::remove(target
);
357 if(!QFile::copy(source
,target
))
359 *errString
= tr("Copying of %1 to %2 failed").arg(source
).arg(target
);
364 QString now
= QDate::currentDate().toString("yyyyMMdd");
365 installlog
.setValue(target
.remove(0,m_mountpoint
.length()),now
);
367 m_logger
->setProgressValue(++m_progress
);
368 QCoreApplication::processEvents();
370 installlog
.endGroup();
375 //! \brief copys Talkfile for Files from the temp dir to the target. Progress and installlog is handled inside
377 //! \param fileMap a MultiMap of Paths -> Filenames
378 //! \param errString Pointer to a QString where the error cause is written.
379 //! \returns true on success, false on error or user abort
380 bool TalkFileCreator::copyTalkFileFiles(QMultiMap
<QString
,QString
> fileMap
,QString
* errString
)
382 resetProgress(fileMap
.size());
384 QSettings
installlog(m_mountpoint
+ "/.rockbox/rbutil.log", QSettings::IniFormat
, 0);
385 installlog
.beginGroup("talkfiles");
387 QMapIterator
<QString
, QString
> it(fileMap
);
393 *errString
= tr("Talk file creation aborted");
398 QString target
= it
.key() + "/" + it
.value() + ".talk";
400 // correct source if we hav stripExtension enabled
401 if(m_stripExtensions
)
402 source
= QDir::tempPath()+ "/"+ stripExtension(it
.value()) + ".talk";
404 source
= QDir::tempPath()+ "/"+ it
.value() + ".talk";
406 if(!QFileInfo(source
).exists())
407 continue; // this file was skipped in one of the previous steps
409 // remove target if it exists, and if we should overwrite it
410 if(m_overwriteTalk
&& QFile::exists(target
))
411 QFile::remove(target
);
414 qDebug() << "copying: " << source
<< " to " << target
;
415 if(!QFile::copy(source
,target
))
417 *errString
= tr("Copying of %1 to %2 failed").arg(source
).arg(target
);
421 // add to Install log
422 QString now
= QDate::currentDate().toString("yyyyMMdd");
423 installlog
.setValue(target
.remove(0,m_mountpoint
.length()),now
);
425 m_logger
->setProgressValue(++m_progress
);
426 QCoreApplication::processEvents();
428 installlog
.endGroup();
434 //! \brief Cleans up Files potentially left in the temp dir
436 //! \param list List of file to try to delete in the temp dir. Function appends ".wav" and ".talk" to the filenames
437 bool TalkFileCreator::cleanup(QStringList list
)
439 m_logger
->addItem(tr("Cleaning up.."),LOGINFO
);
441 for(int i
=0; i
< list
.size(); i
++)
443 if(QFile::exists(QDir::tempPath()+ "/"+ list
[i
] + ".wav"))
444 QFile::remove(QDir::tempPath()+ "/"+ list
[i
] + ".wav");
445 if(QFile::exists(QDir::tempPath()+ "/"+ list
[i
] + ".talk"))
446 QFile::remove(QDir::tempPath()+ "/"+ list
[i
] + ".talk");
448 QCoreApplication::processEvents();
453 //! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position
455 void TalkFileCreator::abort()