From 20bf8aaf181dc5f24bad2628953c4d53782533cb Mon Sep 17 00:00:00 2001 From: Dominik Wenger Date: Fri, 26 Jun 2009 20:40:51 +0000 Subject: rbutil: improve voice and talk generation. - introduce a talkgenerator to better share code between voice and talk generation. - name intermediate .talkfiles after the md5sum of the text. (prevents naming problems). - do not directly use the logger, instead emit signals. - move talkfile and voicefile generation to base/ git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21524 a1c6a512-1295-4272-9138-f99709370657 --- rbutil/rbutilqt/base/talkfile.cpp | 263 +++++++++++++++++++ rbutil/rbutilqt/base/talkfile.h | 83 ++++++ rbutil/rbutilqt/base/talkgenerator.cpp | 238 +++++++++++++++++ rbutil/rbutilqt/base/talkgenerator.h | 78 ++++++ rbutil/rbutilqt/base/voicefile.cpp | 246 ++++++++++++++++++ rbutil/rbutilqt/base/voicefile.h | 75 ++++++ rbutil/rbutilqt/createvoicewindow.cpp | 6 +- rbutil/rbutilqt/installtalkwindow.cpp | 7 +- rbutil/rbutilqt/rbutilqt.pro | 10 +- rbutil/rbutilqt/talkfile.cpp | 458 --------------------------------- rbutil/rbutilqt/talkfile.h | 84 ------ rbutil/rbutilqt/voicefile.cpp | 301 ---------------------- rbutil/rbutilqt/voicefile.h | 79 ------ 13 files changed, 1000 insertions(+), 928 deletions(-) create mode 100644 rbutil/rbutilqt/base/talkfile.cpp create mode 100644 rbutil/rbutilqt/base/talkfile.h create mode 100644 rbutil/rbutilqt/base/talkgenerator.cpp create mode 100644 rbutil/rbutilqt/base/talkgenerator.h create mode 100644 rbutil/rbutilqt/base/voicefile.cpp create mode 100644 rbutil/rbutilqt/base/voicefile.h delete mode 100644 rbutil/rbutilqt/talkfile.cpp delete mode 100644 rbutil/rbutilqt/talkfile.h delete mode 100644 rbutil/rbutilqt/voicefile.cpp delete mode 100644 rbutil/rbutilqt/voicefile.h diff --git a/rbutil/rbutilqt/base/talkfile.cpp b/rbutil/rbutilqt/base/talkfile.cpp new file mode 100644 index 0000000000..81dcf01ff5 --- /dev/null +++ b/rbutil/rbutilqt/base/talkfile.cpp @@ -0,0 +1,263 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2007 by Dominik Wenger + * $Id$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "talkfile.h" +#include "rbsettings.h" + +TalkFileCreator::TalkFileCreator(QObject* parent): QObject(parent) +{ + +} + +//! \brief Creates Talkfiles. +//! +//! \param logger A pointer to a Loggerobject +bool TalkFileCreator::createTalkFiles() +{ + m_abort = false; + QString errStr; + + emit logItem(tr("Starting Talk file generation"),LOGINFO); + emit logProgress(0,0); + QCoreApplication::processEvents(); + + // read in Maps of paths - file/dirnames + emit logItem(tr("Reading Filelist..."),LOGINFO); + if(createTalkList(m_dir) == false) + { + emit logItem(tr("Talk file creation aborted"),LOGERROR); + doAbort(); + return false; + } + QCoreApplication::processEvents(); + + // generate entries + { + TalkGenerator generator(this); + connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool))); + connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int))); + connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int))); + connect(this,SIGNAL(aborted()),&generator,SLOT(abort())); + + if(generator.process(&m_talkList) == TalkGenerator::eERROR) + { + doAbort(); + return false; + } + } + + // Copying talk files + emit logItem(tr("Copying Talkfiles..."),LOGINFO); + if(copyTalkFiles(&errStr) == false) + { + emit logItem(errStr,LOGERROR); + doAbort(); + return false; + } + + // Deleting left overs + if( !cleanup()) + return false; + + emit logItem(tr("Finished creating Talk files"),LOGOK); + emit logProgress(1,1); + emit done(false); + + return true; +} + +//! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed +//! +//! \param filename The filename from which to strip the Extension +//! \returns the modified string +QString TalkFileCreator::stripExtension(QString filename) +{ + if(filename.lastIndexOf(".") != -1) + return filename.left(filename.lastIndexOf(".")); + else + return filename; +} + +//! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder +//! +void TalkFileCreator::doAbort() +{ + cleanup(); + emit logProgress(0,1); + emit done(true); +} +//! \brief creates a list of what to generate +//! +//! \param startDir The directory from which to start scanning +bool TalkFileCreator::createTalkList(QDir startDir) +{ + m_talkList.clear(); + + // create Iterator + QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags; + if(m_recursive) + flags = QDirIterator::Subdirectories; + + QDirIterator it(startDir,flags); + + //create temp directory + QDir tempDir(QDir::tempPath()+ "/talkfiles/"); + if(!tempDir.exists()) + tempDir.mkpath(QDir::tempPath()+ "/talkfiles/"); + + // read in Maps of paths - file/dirnames + while (it.hasNext()) + { + it.next(); + if(m_abort) + { + return false; + } + + QFileInfo fileInf = it.fileInfo(); + + // its a dir + if(fileInf.isDir()) + { + QDir dir = fileInf.dir(); + + // insert into List + if(!dir.dirName().isEmpty() && m_talkFolders) + { + TalkGenerator::TalkEntry entry; + entry.toSpeak = dir.dirName(); + entry.wavfilename = QDir::tempPath()+ "/talkfiles/" + QCryptographicHash::hash(entry.toSpeak.toUtf8(), + QCryptographicHash::Md5).toHex() + ".wav"; + entry.talkfilename = QDir::tempPath()+ "/talkfiles/" + QCryptographicHash::hash(entry.toSpeak.toUtf8(), + QCryptographicHash::Md5).toHex() + ".talk"; + entry.target = dir.path() + "/_dirname.talk"; + entry.voiced = false; + entry.encoded = false; + qDebug() << "toSpeak: " << entry.toSpeak << " target: " << entry.target << " intermediates: " << + entry.wavfilename << entry.talkfilename; + m_talkList.append(entry); + } + } + else // its a File + { + // insert into List + if( !fileInf.fileName().isEmpty() && !fileInf.fileName().endsWith(".talk") && m_talkFiles) + { + TalkGenerator::TalkEntry entry; + if(m_stripExtensions) + entry.toSpeak = stripExtension(fileInf.fileName()); + else + entry.toSpeak = fileInf.fileName(); + entry.wavfilename = QDir::tempPath()+ "/talkfiles/" + QCryptographicHash::hash(entry.toSpeak.toUtf8(), + QCryptographicHash::Md5).toHex() + ".wav"; + entry.talkfilename = QDir::tempPath()+ "/talkfiles/" + QCryptographicHash::hash(entry.toSpeak.toUtf8(), + QCryptographicHash::Md5).toHex() + ".talk"; + entry.target = fileInf.path() + "/" + fileInf.fileName() + ".talk"; + entry.voiced = false; + entry.encoded = false; + qDebug() << "toSpeak: " << entry.toSpeak << " target: " << entry.target << " intermediates: " << + entry.wavfilename << entry.talkfilename; + m_talkList.append(entry); + } + } + QCoreApplication::processEvents(); + } + return true; +} + + +//! \brief copys Talkfiles from the temp dir to the target. Progress and installlog is handled inside +//! +//! \param errString Pointer to a QString where the error cause is written. +//! \returns true on success, false on error or user abort +bool TalkFileCreator::copyTalkFiles(QString* errString) +{ + int progressMax = m_talkList.size(); + int m_progress = 0; + emit logProgress(m_progress,progressMax); + + QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0); + installlog.beginGroup("talkfiles"); + + for(int i=0; i < m_talkList.size(); i++) + { + if(m_abort) + { + *errString = tr("File copy aborted"); + return false; + } + + // skip not encoded files + if(m_talkList[i].encoded == false) + { + emit logProgress(++m_progress,progressMax); + continue; // this file was skipped in one of the previous steps + } + // remove target if it exists, and if we should overwrite it + if(m_overwriteTalk && QFile::exists(m_talkList[i].target)) + QFile::remove(m_talkList[i].target); + + // copying + qDebug() << "copying " << m_talkList[i].talkfilename << "to" << m_talkList[i].target; + if(!QFile::copy(m_talkList[i].talkfilename,m_talkList[i].target)) + { + *errString = tr("Copying of %1 to %2 failed").arg(m_talkList[i].talkfilename).arg(m_talkList[i].target); + return false; + } + + // add to installlog + QString now = QDate::currentDate().toString("yyyyMMdd"); + installlog.setValue(m_talkList[i].target.remove(0,m_mountpoint.length()),now); + + emit logProgress(++m_progress,progressMax); + QCoreApplication::processEvents(); + } + installlog.endGroup(); + installlog.sync(); + return true; +} + + +//! \brief Cleans up Files potentially left in the temp dir +//! +bool TalkFileCreator::cleanup() +{ + emit logItem(tr("Cleaning up.."),LOGINFO); + + for(int i=0; i < m_talkList.size(); i++) + { + if(QFile::exists(m_talkList[i].wavfilename)) + QFile::remove(m_talkList[i].wavfilename); + if(QFile::exists(m_talkList[i].talkfilename)) + QFile::remove(m_talkList[i].talkfilename); + + QCoreApplication::processEvents(); + } + emit logItem(tr("Finished"),LOGINFO); + return true; +} + +//! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position +//! +void TalkFileCreator::abort() +{ + m_abort = true; + emit aborted(); +} + diff --git a/rbutil/rbutilqt/base/talkfile.h b/rbutil/rbutilqt/base/talkfile.h new file mode 100644 index 0000000000..f82421416a --- /dev/null +++ b/rbutil/rbutilqt/base/talkfile.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2007 by Dominik Wenger + * $Id$ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#ifndef TALKFILE_H +#define TALKFILE_H + +#include +#include "progressloggerinterface.h" + +#include "talkgenerator.h" + +class TalkFileCreator :public QObject +{ + Q_OBJECT + +public: + TalkFileCreator(QObject* parent); + + bool createTalkFiles(); + + void setDir(QDir dir){m_dir = dir; } + void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; } + + void setOverwriteTalk(bool ov) {m_overwriteTalk = ov;} + void setRecursive(bool ov) {m_recursive = ov;} + void setStripExtensions(bool ov) {m_stripExtensions = ov;} + void setTalkFolders(bool ov) {m_talkFolders = ov;} + void setTalkFiles(bool ov) {m_talkFiles = ov;} + +public slots: + void abort(); + +signals: + void done(bool); + void aborted(); + void logItem(QString, int); //! set logger item + void logProgress(int, int); //! set progress bar. + +private: + bool cleanup(); + QString stripExtension(QString filename); + void doAbort(); + void resetProgress(int max); + bool copyTalkFiles(QString* errString); + + bool createTalkList(QDir startDir); + + QDir m_dir; + QString m_mountpoint; + + bool m_overwriteTalk; + bool m_recursive; + bool m_stripExtensions; + bool m_talkFolders; + bool m_talkFiles; + + bool m_abort; + + QList m_talkList; +}; + + +#endif + diff --git a/rbutil/rbutilqt/base/talkgenerator.cpp b/rbutil/rbutilqt/base/talkgenerator.cpp new file mode 100644 index 0000000000..93a52a922e --- /dev/null +++ b/rbutil/rbutilqt/base/talkgenerator.cpp @@ -0,0 +1,238 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2007 by Dominik Wenger + * $Id$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "talkgenerator.h" +#include "rbsettings.h" +#include "wavtrim.h" + +TalkGenerator::TalkGenerator(QObject* parent): QObject(parent) +{ + +} + +//! \brief Creates Talkfiles. +//! +TalkGenerator::Status TalkGenerator::process(QList* list,int wavtrimth) +{ + m_abort = false; + QString errStr; + bool warnings = false; + + //tts + emit logItem(tr("Starting TTS Engine"),LOGINFO); + m_tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString()); + if(!m_tts->start(&errStr)) + { + emit logItem(errStr.trimmed(),LOGERROR); + emit logItem(tr("Init of TTS engine failed"),LOGERROR); + emit done(true); + return eERROR; + } + QCoreApplication::processEvents(); + + // Encoder + emit logItem(tr("Starting Encoder Engine"),LOGINFO); + m_enc = EncBase::getEncoder(this,RbSettings::value(RbSettings::CurEncoder).toString()); + if(!m_enc->start()) + { + emit logItem(tr("Init of Encoder engine failed"),LOGERROR); + emit done(true); + m_tts->stop(); + return eERROR; + } + QCoreApplication::processEvents(); + + emit logProgress(0,0); + + // Voice entries + emit logItem(tr("Voicing entries..."),LOGINFO); + Status voiceStatus= voiceList(list,wavtrimth); + if(voiceStatus == eERROR) + { + m_tts->stop(); + m_enc->stop(); + emit done(true); + return eERROR; + } + else if( voiceStatus == eWARNING) + warnings = true; + + QCoreApplication::processEvents(); + + // Encoding Entries + emit logItem(tr("Encoding files..."),LOGINFO); + Status encoderStatus = encodeList(list); + if( encoderStatus == eERROR) + { + m_tts->stop(); + m_enc->stop(); + emit done(true); + return eERROR; + } + else if( voiceStatus == eWARNING) + warnings = true; + + QCoreApplication::processEvents(); + + m_tts->stop(); + m_enc->stop(); + emit logProgress(1,1); + + if(warnings) + return eWARNING; + return eOK; +} + +//! \brief Voices a List of string +//! +TalkGenerator::Status TalkGenerator::voiceList(QList* list,int wavtrimth) +{ + int progressMax = list->size(); + int m_progress = 0; + emit logProgress(m_progress,progressMax); + + QStringList errors; + QStringList dublicates; + + bool warnings = false; + for(int i=0; i < list->size(); i++) + { + if(m_abort) + { + emit logItem(tr("Voicing aborted"), LOGERROR); + return eERROR; + } + + // skip dublicated wav entrys + if(!dublicates.contains(list->at(i).wavfilename)) + dublicates.append(list->at(i).wavfilename); + else + { + qDebug() << "dublicate skipped"; + (*list)[i].voiced = true; + emit logProgress(++m_progress,progressMax); + continue; + } + + // skip already voiced entrys + if(list->at(i).voiced == true) + { + emit logProgress(++m_progress,progressMax); + continue; + } + // skip entry whith empty text + if(list->at(i).toSpeak == "") + { + emit logProgress(++m_progress,progressMax); + continue; + } + + // voice entry + QString error; + qDebug() << "voicing: " << list->at(i).toSpeak << "to" << list->at(i).wavfilename; + TTSStatus status = m_tts->voice(list->at(i).toSpeak,list->at(i).wavfilename, &error); + if(status == Warning) + { + warnings = true; + emit logItem(tr("Voicing of %1 failed: %2").arg(list->at(i).toSpeak).arg(error), + LOGWARNING); + } + else if (status == FatalError) + { + emit logItem(tr("Voicing of %1 failed: %2").arg(list->at(i).toSpeak).arg(error), + LOGERROR); + return eERROR; + } + else + (*list)[i].voiced = true; + + //wavetrim if needed + if(wavtrimth != -1) + { + char buffer[255]; + wavtrim(list->at(i).wavfilename.toLocal8Bit().data(),wavtrimth,buffer,255); + } + + emit logProgress(++m_progress,progressMax); + QCoreApplication::processEvents(); + } + if(warnings) + return eWARNING; + else + return eOK; +} + + +//! \brief Encodes a List of strings +//! +TalkGenerator::Status TalkGenerator::encodeList(QList* list) +{ + QStringList dublicates; + + int progressMax = list->size(); + int m_progress = 0; + emit logProgress(m_progress,progressMax); + + for(int i=0; i < list->size(); i++) + { + if(m_abort) + { + emit logItem(tr("Encoding aborted"), LOGERROR); + return eERROR; + } + + //skip non-voiced entrys + if(list->at(i).voiced == false) + { + qDebug() << "non voiced entry" << list->at(i).toSpeak <<"detected"; + emit logProgress(++m_progress,progressMax); + continue; + } + //skip dublicates + if(!dublicates.contains(list->at(i).talkfilename)) + dublicates.append(list->at(i).talkfilename); + else + { + qDebug() << "dublicate skipped"; + (*list)[i].encoded = true; + emit logProgress(++m_progress,progressMax); + continue; + } + + //encode entry + qDebug() << "encoding " << list->at(i).wavfilename << "to" << list->at(i).talkfilename; + if(!m_enc->encode(list->at(i).wavfilename,list->at(i).talkfilename)) + { + emit logItem(tr("Encoding of %1 failed").arg(list->at(i).wavfilename), LOGERROR); + return eERROR; + } + (*list)[i].encoded = true; + emit logProgress(++m_progress,progressMax); + QCoreApplication::processEvents(); + } + return eOK; +} + +//! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position +//! +void TalkGenerator::abort() +{ + m_abort = true; +} + diff --git a/rbutil/rbutilqt/base/talkgenerator.h b/rbutil/rbutilqt/base/talkgenerator.h new file mode 100644 index 0000000000..eb08df8d51 --- /dev/null +++ b/rbutil/rbutilqt/base/talkgenerator.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2007 by Dominik Wenger + * $Id$ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#ifndef TALKGENERATOR_H +#define TALKGENERATOR_H + +#include +#include "progressloggerinterface.h" + +#include "encoders.h" +#include "tts.h" + +//! \brief Talk generator, generates .wav and .talk files out of a list. +class TalkGenerator :public QObject +{ + Q_OBJECT +public: + enum Status + { + eOK, + eWARNING, + eERROR + }; + + struct TalkEntry + { + QString toSpeak; + QString wavfilename; + QString talkfilename; + QString target; + bool voiced; + bool encoded; + }; + + TalkGenerator(QObject* parent); + + Status process(QList* list,int wavtrimth = -1); + +public slots: + void abort(); + +signals: + void done(bool); + void logItem(QString, int); //! set logger item + void logProgress(int, int); //! set progress bar. + +private: + Status voiceList(QList* list,int wavetrimth); + Status encodeList(QList* list); + + TTSBase* m_tts; + EncBase* m_enc; + + bool m_abort; +}; + + +#endif + diff --git a/rbutil/rbutilqt/base/voicefile.cpp b/rbutil/rbutilqt/base/voicefile.cpp new file mode 100644 index 0000000000..3b80c1ff12 --- /dev/null +++ b/rbutil/rbutilqt/base/voicefile.cpp @@ -0,0 +1,246 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2007 by Dominik Wenger + * $Id$ + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "voicefile.h" +#include "utils.h" +#include "rbsettings.h" + +VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent) +{ + m_wavtrimThreshold=500; +} + +void VoiceFileCreator::abort() +{ + m_abort = true; + emit aborted(); +} + +bool VoiceFileCreator::createVoiceFile() +{ + m_talkList.clear(); + m_abort = false; + emit logItem(tr("Starting Voicefile generation"),LOGINFO); + + // test if tempdir exists + if(!QDir(QDir::tempPath()+"/rbvoice/").exists()) + { + QDir(QDir::tempPath()).mkdir("rbvoice"); + } + m_path = QDir::tempPath() + "/rbvoice/"; + + // read rockbox-info.txt + RockboxInfo info(m_mountpoint); + if(!info.open()) + { + emit logItem(tr("could not find rockbox-info.txt"),LOGERROR); + emit done(true); + return false; + } + + QString target = info.target(); + QString features = info.features(); + QString version = info.version(); + version = version.left(version.indexOf("-")).remove(0,1); + + //prepare download url + QUrl genlangUrl = RbSettings::value(RbSettings::GenlangUrl).toString() + +"?lang=" + m_lang + "&t=" + target + "&rev=" + version + "&f=" + features; + + qDebug() << "downloading " << genlangUrl; + + //download the correct genlang output + QTemporaryFile *downloadFile = new QTemporaryFile(this); + downloadFile->open(); + filename = downloadFile->fileName(); + downloadFile->close(); + // get the real file. + getter = new HttpGet(this); + getter->setFile(downloadFile); + + connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); + connect(getter, SIGNAL(dataReadProgress(int, int)), this, SIGNAL(logProgress(int, int))); + connect(this, SIGNAL(aborted()), getter, SLOT(abort())); + emit logItem(tr("Downloading voice info.."),LOGINFO); + getter->getFile(genlangUrl); + return true; + } + + +void VoiceFileCreator::downloadDone(bool error) +{ + qDebug() << "Voice creator::downloadDone, error:" << error; + + // update progress bar + emit logProgress(1,1); + if(getter->httpResponse() != 200 && !getter->isCached()) { + emit logItem(tr("Download error: received HTTP error %1.").arg(getter->httpResponse()),LOGERROR); + emit done(true); + return; + } + + if(getter->isCached()) + emit logItem(tr("Cached file used."), LOGINFO); + if(error) + { + emit logItem(tr("Download error: %1").arg(getter->errorString()),LOGERROR); + emit done(true); + return; + } + else + emit logItem(tr("Download finished."),LOGINFO); + + QCoreApplication::processEvents(); + + //open downloaded file + QFile genlang(filename); + if(!genlang.open(QIODevice::ReadOnly)) + { + emit logItem(tr("failed to open downloaded file"),LOGERROR); + emit done(true); + return; + } + + QCoreApplication::processEvents(); + + //read in downloaded file + emit logItem(tr("Reading strings..."),LOGINFO); + QTextStream in(&genlang); + in.setCodec("UTF-8"); + QString id, voice; + bool idfound = false; + bool voicefound=false; + while (!in.atEnd()) + { + QString line = in.readLine(); + if(line.contains("id:")) //ID found + { + id = line.remove("id:").remove('"').trimmed(); + idfound = true; + } + else if(line.contains("voice:")) // voice found + { + voice = line.remove("voice:").remove('"').trimmed(); + voicefound=true; + } + + if(idfound && voicefound) + { + TalkGenerator::TalkEntry entry; + entry.toSpeak = voice; + entry.wavfilename = m_path + "/" + id + ".wav"; + entry.talkfilename = m_path + "/" + id + ".mp3"; //voicefont wants them with .mp3 extension + entry.voiced = false; + entry.encoded = false; + if(id == "VOICE_PAUSE") + { + QFile::copy(":/builtin/VOICE_PAUSE.wav",m_path + "/VOICE_PAUSE.wav"); + entry.wavfilename = m_path + "/VOICE_PAUSE.wav"; + entry.voiced = true; + } + m_talkList.append(entry); + idfound=false; + voicefound=false; + } + } + genlang.close(); + + // check for empty list + if(m_talkList.size() == 0) + { + emit logItem(tr("The downloaded file was empty!"),LOGERROR); + emit done(true); + return; + } + + // generate files + { + TalkGenerator generator(this); + connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool))); + connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int))); + connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int))); + connect(this,SIGNAL(aborted()),&generator,SLOT(abort())); + + if(generator.process(&m_talkList) == TalkGenerator::eERROR) + { + cleanup(); + emit logProgress(0,1); + emit done(true); + return; + } + } + + //make voicefile + emit logItem(tr("Creating voicefiles..."),LOGINFO); + FILE* ids2 = fopen(filename.toLocal8Bit(), "r"); + if (ids2 == NULL) + { + cleanup(); + emit logItem(tr("Error opening downloaded file"),LOGERROR); + emit done(true); + return; + } + + FILE* output = fopen(QString(m_mountpoint + "/.rockbox/langs/" + m_lang + ".voice").toLocal8Bit(), "wb"); + if (output == NULL) + { + cleanup(); + emit logItem(tr("Error opening output file"),LOGERROR); + emit done(true); + return; + } + + voicefont(ids2,m_targetid,m_path.toLocal8Bit().data(), output); + + //cleanup + cleanup(); + + // Add Voice file to the install log + QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0); + installlog.beginGroup("selfcreated Voice"); + installlog.setValue("/.rockbox/langs/" + m_lang + ".voice",QDate::currentDate().toString("yyyyMMdd")); + installlog.endGroup(); + installlog.sync(); + + emit logProgress(1,1); + emit logItem(tr("successfully created."),LOGOK); + + emit done(false); +} + +//! \brief Cleans up Files potentially left in the temp dir +//! +void VoiceFileCreator::cleanup() +{ + emit logItem(tr("Cleaning up.."),LOGINFO); + + for(int i=0; i < m_talkList.size(); i++) + { + if(QFile::exists(m_talkList[i].wavfilename)) + QFile::remove(m_talkList[i].wavfilename); + if(QFile::exists(m_talkList[i].talkfilename)) + QFile::remove(m_talkList[i].talkfilename); + + QCoreApplication::processEvents(); + } + emit logItem(tr("Finished"),LOGINFO); + + return; +} + diff --git a/rbutil/rbutilqt/base/voicefile.h b/rbutil/rbutilqt/base/voicefile.h new file mode 100644 index 0000000000..26c4a408f7 --- /dev/null +++ b/rbutil/rbutilqt/base/voicefile.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2007 by Dominik Wenger + * $Id$ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#ifndef VOICEFILE_H +#define VOICEFILE_H + +#include +#include "progressloggerinterface.h" + +#include "httpget.h" +#include "voicefont.h" +#include "talkgenerator.h" + +class VoiceFileCreator :public QObject +{ + Q_OBJECT +public: + VoiceFileCreator(QObject* parent); + + //start creation + bool createVoiceFile(); + + void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; } + void setTargetId(int id){m_targetid = id;} + void setLang(QString name){m_lang =name;} + void setWavtrimThreshold(int th){m_wavtrimThreshold = th;} + +public slots: + void abort(); + +signals: + void done(bool); + void aborted(); + void logItem(QString, int); //! set logger item + void logProgress(int, int); //! set progress bar. + +private slots: + void downloadDone(bool error); + +private: + void cleanup(); + + HttpGet *getter; + QString filename; //the temporary file + QString m_mountpoint; //mountpoint of the device + QString m_path; //path where the wav and mp3 files are stored to + int m_targetid; //the target id + QString m_lang; // the language which will be spoken + int m_wavtrimThreshold; + + bool m_abort; + QList m_talkList; +}; + +#endif + diff --git a/rbutil/rbutilqt/createvoicewindow.cpp b/rbutil/rbutilqt/createvoicewindow.cpp index 01c9a256b7..268e9f50e7 100644 --- a/rbutil/rbutilqt/createvoicewindow.cpp +++ b/rbutil/rbutilqt/createvoicewindow.cpp @@ -60,7 +60,11 @@ void CreateVoiceWindow::accept() voicecreator->setWavtrimThreshold(wvThreshold); //start creating - voicecreator->createVoiceFile(logger); + connect(voicecreator, SIGNAL(done(bool)), logger, SLOT(setFinished())); + connect(voicecreator, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int))); + connect(voicecreator, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int))); + connect(logger,SIGNAL(aborted()),voicecreator,SLOT(abort())); + voicecreator->createVoiceFile(); } diff --git a/rbutil/rbutilqt/installtalkwindow.cpp b/rbutil/rbutilqt/installtalkwindow.cpp index 6277313d3a..f225632f22 100644 --- a/rbutil/rbutilqt/installtalkwindow.cpp +++ b/rbutil/rbutilqt/installtalkwindow.cpp @@ -103,7 +103,12 @@ void InstallTalkWindow::accept() talkcreator->setTalkFolders(ui.talkFolders->isChecked()); talkcreator->setTalkFiles(ui.talkFiles->isChecked()); - talkcreator->createTalkFiles(logger); + connect(talkcreator, SIGNAL(done(bool)), logger, SLOT(setFinished())); + connect(talkcreator, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int))); + connect(talkcreator, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int))); + connect(logger,SIGNAL(aborted()),talkcreator,SLOT(abort())); + + talkcreator->createTalkFiles(); } diff --git a/rbutil/rbutilqt/rbutilqt.pro b/rbutil/rbutilqt/rbutilqt.pro index 3edcbdc11b..3223b91828 100644 --- a/rbutil/rbutilqt/rbutilqt.pro +++ b/rbutil/rbutilqt/rbutilqt.pro @@ -53,7 +53,8 @@ SOURCES += rbutilqt.cpp \ base/zipinstaller.cpp \ progressloggergui.cpp \ installtalkwindow.cpp \ - talkfile.cpp \ + base/talkfile.cpp \ + base/talkgenerator.cpp \ base/autodetection.cpp \ ../ipodpatcher/ipodpatcher.c \ ../sansapatcher/sansapatcher.c \ @@ -69,7 +70,7 @@ SOURCES += rbutilqt.cpp \ base/tts.cpp \ ../../tools/wavtrim.c \ ../../tools/voicefont.c \ - voicefile.cpp \ + base/voicefile.cpp \ createvoicewindow.cpp \ base/rbsettings.cpp \ base/rbunzip.cpp \ @@ -97,7 +98,8 @@ HEADERS += rbutilqt.h \ version.h \ base/zipinstaller.h \ installtalkwindow.h \ - talkfile.h \ + base/talkfile.h \ + base/talkgenerator.h \ base/autodetection.h \ progressloggerinterface.h \ progressloggergui.h \ @@ -121,7 +123,7 @@ HEADERS += rbutilqt.h \ base/tts.h \ ../../tools/wavtrim.h \ ../../tools/voicefont.h \ - voicefile.h \ + base/voicefile.h \ createvoicewindow.h \ base/rbsettings.h \ base/rbunzip.h \ diff --git a/rbutil/rbutilqt/talkfile.cpp b/rbutil/rbutilqt/talkfile.cpp deleted file mode 100644 index 815c2824fb..0000000000 --- a/rbutil/rbutilqt/talkfile.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 by Dominik Wenger - * $Id$ - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "talkfile.h" -#include "rbsettings.h" - -TalkFileCreator::TalkFileCreator(QObject* parent): QObject(parent) -{ - -} - -//! \brief Creates Talkfiles. -//! -//! \param logger A pointer to a Loggerobject -bool TalkFileCreator::createTalkFiles(ProgressloggerInterface* logger) -{ - m_abort = false; - m_logger = logger; - - QMultiMap fileList; - QMultiMap dirList; - QStringList toSpeakList, voicedEntries, encodedEntries; - QString errStr; - - m_logger->addItem(tr("Starting Talk file generation"),LOGINFO); - - //tts - m_tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString()); - - if(!m_tts->start(&errStr)) - { - m_logger->addItem(errStr.trimmed(),LOGERROR); - m_logger->addItem(tr("Init of TTS engine failed"),LOGERROR); - m_logger->setFinished(); - return false; - } - - // Encoder - m_enc = EncBase::getEncoder(this,RbSettings::value(RbSettings::CurEncoder).toString()); - - if(!m_enc->start()) - { - m_logger->addItem(tr("Init of Encoder engine failed"),LOGERROR); - m_logger->setFinished(); - m_tts->stop(); - return false; - } - - QCoreApplication::processEvents(); - - connect(logger,SIGNAL(aborted()),this,SLOT(abort())); - m_logger->setProgressMax(0); - - // read in Maps of paths - file/dirnames - m_logger->addItem(tr("Reading Filelist..."),LOGINFO); - if(createDirAndFileMaps(m_dir,&dirList,&fileList) == false) - { - m_logger->addItem(tr("Talk file creation aborted"),LOGERROR); - doAbort(toSpeakList); - return false; - } - - // create List of all Files/Dirs to speak - QMapIterator dirIt(dirList); - while (dirIt.hasNext()) - { - dirIt.next(); - // insert only non dublicate dir entries into list - if(!toSpeakList.contains(dirIt.value())) - { - qDebug() << "toSpeaklist dir:" << dirIt.value(); - toSpeakList.append(dirIt.value()); - } - } - QMapIterator fileIt(fileList); - while (fileIt.hasNext()) - { - fileIt.next(); - // insert only non- dublictae file entries into list - if(!toSpeakList.contains(fileIt.value())) - { - if(m_stripExtensions) - toSpeakList.append(stripExtension(fileIt.value())); - else - toSpeakList.append(fileIt.value()); - } - } - - // Voice entries - m_logger->addItem(tr("Voicing entries..."),LOGINFO); - TTSStatus voiceStatus= voiceList(toSpeakList,voicedEntries); - if(voiceStatus == FatalError) - { - doAbort(toSpeakList); - return false; - } - - // Encoding Entries - m_logger->addItem(tr("Encoding files..."),LOGINFO); - if(encodeList(voicedEntries,encodedEntries) == false) - { - doAbort(toSpeakList); - return false; - } - - // Copying talk files - m_logger->addItem(tr("Copying Talkfile for Dirs..."),LOGINFO); - if(copyTalkDirFiles(dirList,&errStr) == false) - { - m_logger->addItem(errStr,LOGERROR); - doAbort(toSpeakList); - return false; - } - - //Copying file talk files - m_logger->addItem(tr("Copying Talkfile for Files..."),LOGINFO); - if(copyTalkFileFiles(fileList,&errStr) == false) - { - m_logger->addItem(errStr,LOGERROR); - doAbort(toSpeakList); - return false; - } - - // Deleting left overs - if( !cleanup(toSpeakList)) - return false; - - m_tts->stop(); - m_enc->stop(); - m_logger->addItem(tr("Finished creating Talk files"),LOGOK); - m_logger->setProgressMax(1); - m_logger->setProgressValue(1); - m_logger->setFinished(); - - return true; -} - -//! \brief resets the internal progress counter, and sets the Progressbar in the Logger -//! -//! \param max The maximum to shich the Progressbar is set. -void TalkFileCreator::resetProgress(int max) -{ - m_progress = 0; - m_logger->setProgressMax(max); - m_logger->setProgressValue(m_progress); -} - -//! \brief Strips everything after and including the last dot in a string. If there is no dot, nothing is changed -//! -//! \param filename The filename from which to strip the Extension -//! \returns the modified string -QString TalkFileCreator::stripExtension(QString filename) -{ - if(filename.lastIndexOf(".") != -1) - return filename.left(filename.lastIndexOf(".")); - else - return filename; -} - -//! \brief Does needed Tasks when we need to abort. Cleans up Files. Stops the Logger, Stops TTS and Encoder -//! -//! \param cleanupList List of filenames to give to cleanup() -void TalkFileCreator::doAbort(QStringList cleanupList) -{ - cleanup(cleanupList); - m_logger->setProgressMax(1); - m_logger->setProgressValue(0); - m_logger->setFinished(); - m_tts->stop(); - m_enc->stop(); -} - -//! \brief Creates MultiMaps (paths -> File/dir names) of all Dirs and Files in a Folder. -//! Depending on settings, either Dirs or Files can be ignored. -//! Also recursion is controlled by settings -//! -//! \param startDir The dir where it beginns scanning -//! \param dirMap The MulitMap where the dirs are stored -//! \param filMap The MultiMap where Files are stored -//! \returns true on Success, false if User aborted. -bool TalkFileCreator::createDirAndFileMaps(QDir startDir,QMultiMap *dirMap,QMultiMap *fileMap) -{ - // create Iterator - QDirIterator::IteratorFlags flags = QDirIterator::NoIteratorFlags; - if(m_recursive) - flags = QDirIterator::Subdirectories; - - QDirIterator it(startDir,flags); - - // read in Maps of paths - file/dirnames - while (it.hasNext()) - { - it.next(); - if(m_abort) - { - return false; - } - - QFileInfo fileInf = it.fileInfo(); - - // its a dir - if(fileInf.isDir()) - { - QDir dir = fileInf.dir(); - - // insert into List - if(!dir.dirName().isEmpty() && m_talkFolders) - { - qDebug() << "Dir: " << dir.dirName() << " - " << dir.path(); - dirMap->insert(dir.path(),dir.dirName()); - } - } - else // its a File - { - // insert into List - if( !fileInf.fileName().isEmpty() && !fileInf.fileName().endsWith(".talk") && m_talkFiles) - { - qDebug() << "File: " << fileInf.fileName() << " - " << fileInf.path(); - fileMap->insert(fileInf.path(),fileInf.fileName()); - } - } - QCoreApplication::processEvents(); - } - return true; -} - -//! \brief Voices a List of string to the temp dir. Progress is handled inside. -//! -//! \param toSpeak QStringList with the Entries to voice. -//! \param errString pointer to where the Error cause is written -//! \returns true on success, false on error or user abort -TTSStatus TalkFileCreator::voiceList(QStringList toSpeak,QStringList& voicedEntries) -{ - resetProgress(toSpeak.size()); - QStringList errors; - - bool warnings = false; - for(int i=0; i < toSpeak.size(); i++) - { - if(m_abort) - { - m_logger->addItem(tr("Talk file creation aborted"), LOGERROR); - return FatalError; - } - - QString filename = QDir::tempPath()+ "/"+ toSpeak[i] + ".wav"; - - QString error; - TTSStatus status = m_tts->voice(toSpeak[i],filename, &error); - if(status == Warning) - { - warnings = true; - m_logger->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak[i]).arg(error), - LOGWARNING); - } - else if (status == FatalError) - { - m_logger->addItem(tr("Voicing of %1 failed: %2").arg(toSpeak[i]).arg(error), - LOGERROR); - return FatalError; - } - else - voicedEntries.append(toSpeak[i]); - m_logger->setProgressValue(++m_progress); - QCoreApplication::processEvents(); - } - if(warnings) - return Warning; - else - return NoError; -} - - -//! \brief Encodes a List of strings from/to the temp dir. Progress is handled inside. -//! It expects the inputfile in the temp dir with the name in the List appended with ".wav" -//! -//! \param toSpeak QStringList with the Entries to encode. -//! \param errString pointer to where the Error cause is written -//! \returns true on success, false on error or user abort -bool TalkFileCreator::encodeList(QStringList toEncode,QStringList& encodedEntries) -{ - resetProgress(toEncode.size()); - for(int i=0; i < toEncode.size(); i++) - { - if(m_abort) - { - m_logger->addItem(tr("Talk file creation aborted"), LOGERROR); - return false; - } - - QString wavfilename = QDir::tempPath()+ "/"+ toEncode[i] + ".wav"; - QString filename = QDir::tempPath()+ "/"+ toEncode[i] + ".talk"; - - if(!m_enc->encode(wavfilename,filename)) - { - m_logger->addItem(tr("Encoding of %1 failed").arg(filename), LOGERROR); - return false; - } - encodedEntries.append(toEncode[i]); - m_logger->setProgressValue(++m_progress); - QCoreApplication::processEvents(); - } - return true; -} - -//! \brief copys Talkfile for Dirs from the temp dir to the target. Progress and installlog is handled inside -//! -//! \param dirMap a MultiMap of Paths -> Dirnames -//! \param errString Pointer to a QString where the error cause is written. -//! \returns true on success, false on error or user abort -bool TalkFileCreator::copyTalkDirFiles(QMultiMap dirMap,QString* errString) -{ - resetProgress(dirMap.size()); - - QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0); - installlog.beginGroup("talkfiles"); - - QMapIterator it(dirMap); - while (it.hasNext()) - { - it.next(); - if(m_abort) - { - *errString = tr("Talk file creation aborted"); - return false; - } - - QString source = QDir::tempPath()+ "/"+ it.value() + ".talk"; - - if(!QFileInfo(source).exists()) - continue; // this file was skipped in one of the previous steps - - QString target = it.key() + "/" + "_dirname.talk"; - - // remove target if it exists, and if we should overwrite it - if(m_overwriteTalk && QFile::exists(target)) - QFile::remove(target); - - // copying - if(!QFile::copy(source,target)) - { - *errString = tr("Copying of %1 to %2 failed").arg(source).arg(target); - return false; - } - - // add to installlog - QString now = QDate::currentDate().toString("yyyyMMdd"); - installlog.setValue(target.remove(0,m_mountpoint.length()),now); - - m_logger->setProgressValue(++m_progress); - QCoreApplication::processEvents(); - } - installlog.endGroup(); - installlog.sync(); - return true; -} - -//! \brief copys Talkfile for Files from the temp dir to the target. Progress and installlog is handled inside -//! -//! \param fileMap a MultiMap of Paths -> Filenames -//! \param errString Pointer to a QString where the error cause is written. -//! \returns true on success, false on error or user abort -bool TalkFileCreator::copyTalkFileFiles(QMultiMap fileMap,QString* errString) -{ - resetProgress(fileMap.size()); - - QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0); - installlog.beginGroup("talkfiles"); - - QMapIterator it(fileMap); - while (it.hasNext()) - { - it.next(); - if(m_abort) - { - *errString = tr("Talk file creation aborted"); - return false; - } - - QString source; - QString target = it.key() + "/" + it.value() + ".talk"; - - // correct source if we hav stripExtension enabled - if(m_stripExtensions) - source = QDir::tempPath()+ "/"+ stripExtension(it.value()) + ".talk"; - else - source = QDir::tempPath()+ "/"+ it.value() + ".talk"; - - if(!QFileInfo(source).exists()) - continue; // this file was skipped in one of the previous steps - - // remove target if it exists, and if we should overwrite it - if(m_overwriteTalk && QFile::exists(target)) - QFile::remove(target); - - // copy file - qDebug() << "copying: " << source << " to " << target; - if(!QFile::copy(source,target)) - { - *errString = tr("Copying of %1 to %2 failed").arg(source).arg(target); - return false; - } - - // add to Install log - QString now = QDate::currentDate().toString("yyyyMMdd"); - installlog.setValue(target.remove(0,m_mountpoint.length()),now); - - m_logger->setProgressValue(++m_progress); - QCoreApplication::processEvents(); - } - installlog.endGroup(); - installlog.sync(); - return true; -} - - -//! \brief Cleans up Files potentially left in the temp dir -//! -//! \param list List of file to try to delete in the temp dir. Function appends ".wav" and ".talk" to the filenames -bool TalkFileCreator::cleanup(QStringList list) -{ - m_logger->addItem(tr("Cleaning up.."),LOGINFO); - - for(int i=0; i < list.size(); i++) - { - if(QFile::exists(QDir::tempPath()+ "/"+ list[i] + ".wav")) - QFile::remove(QDir::tempPath()+ "/"+ list[i] + ".wav"); - if(QFile::exists(QDir::tempPath()+ "/"+ list[i] + ".talk")) - QFile::remove(QDir::tempPath()+ "/"+ list[i] + ".talk"); - - QCoreApplication::processEvents(); - } - return true; -} - -//! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position -//! -void TalkFileCreator::abort() -{ - m_abort = true; -} - diff --git a/rbutil/rbutilqt/talkfile.h b/rbutil/rbutilqt/talkfile.h deleted file mode 100644 index a6b9bb5490..0000000000 --- a/rbutil/rbutilqt/talkfile.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 by Dominik Wenger - * $Id$ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -#ifndef TALKFILE_H -#define TALKFILE_H - -#include -#include "progressloggerinterface.h" - -#include "encoders.h" -#include "tts.h" - -class TalkFileCreator :public QObject -{ - Q_OBJECT - -public: - TalkFileCreator(QObject* parent); - - bool createTalkFiles(ProgressloggerInterface* logger); - - void setDir(QDir dir){m_dir = dir; } - void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; } - - void setOverwriteTalk(bool ov) {m_overwriteTalk = ov;} - void setRecursive(bool ov) {m_recursive = ov;} - void setStripExtensions(bool ov) {m_stripExtensions = ov;} - void setTalkFolders(bool ov) {m_talkFolders = ov;} - void setTalkFiles(bool ov) {m_talkFiles = ov;} - -private slots: - void abort(); - -private: - bool cleanup(QStringList list); - QString stripExtension(QString filename); - void doAbort(QStringList cleanupList); - void resetProgress(int max); - bool createDirAndFileMaps(QDir startDir,QMultiMap *dirMap,QMultiMap *fileMap); - TTSStatus voiceList(QStringList toSpeak,QStringList& voicedEntries); - bool encodeList(QStringList toEncode,QStringList& encodedEntries); - bool copyTalkDirFiles(QMultiMap dirMap,QString* errString); - bool copyTalkFileFiles(QMultiMap fileMap,QString* errString); - - TTSBase* m_tts; - EncBase* m_enc; - - QDir m_dir; - QString m_mountpoint; - int m_progress; - - bool m_overwriteTalk; - bool m_recursive; - bool m_stripExtensions; - bool m_talkFolders; - bool m_talkFiles; - - ProgressloggerInterface* m_logger; - - bool m_abort; -}; - - -#endif - diff --git a/rbutil/rbutilqt/voicefile.cpp b/rbutil/rbutilqt/voicefile.cpp deleted file mode 100644 index 4de9b87f34..0000000000 --- a/rbutil/rbutilqt/voicefile.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 by Dominik Wenger - * $Id$ - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "voicefile.h" -#include "utils.h" -#include "rbsettings.h" - -#define STATE_INVALID 0 -#define STATE_PHRASE 1 -#define STATE_VOICE 2 - - -VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent) -{ - m_wavtrimThreshold=500; -} - -void VoiceFileCreator::abort() -{ - m_abort = true; -} - -bool VoiceFileCreator::createVoiceFile(ProgressloggerInterface* logger) -{ - m_abort = false; - m_logger = logger; - m_logger->addItem(tr("Starting Voicefile generation"),LOGINFO); - - // test if tempdir exists - if(!QDir(QDir::tempPath()+"/rbvoice/").exists()) - { - QDir(QDir::tempPath()).mkdir("rbvoice"); - } - - m_path = QDir::tempPath() + "/rbvoice/"; - - // read rockbox-info.txt - RockboxInfo info(m_mountpoint); - if(!info.open()) - { - m_logger->addItem(tr("could not find rockbox-info.txt"),LOGERROR); - m_logger->setFinished(); - emit done(false); - return false; - } - - QString target = info.target(); - QString features = info.features(); - QString version = info.version(); - version = version.left(version.indexOf("-")).remove(0,1); - - //prepare download url - QUrl genlangUrl = RbSettings::value(RbSettings::GenlangUrl).toString() - +"?lang=" + m_lang + "&t=" + target + "&rev=" + version + "&f=" + features; - - qDebug() << "downloading " << genlangUrl; - - //download the correct genlang output - QTemporaryFile *downloadFile = new QTemporaryFile(this); - downloadFile->open(); - filename = downloadFile->fileName(); - downloadFile->close(); - // get the real file. - getter = new HttpGet(this); - getter->setFile(downloadFile); - - connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); - connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int))); - connect(m_logger, SIGNAL(aborted()), getter, SLOT(abort())); - - getter->getFile(genlangUrl); - return true; - } - - -void VoiceFileCreator::downloadDone(bool error) -{ - qDebug() << "Voice creator::downloadDone, error:" << error; - - // update progress bar - int max = m_logger->getProgressMax(); - if(max == 0) { - max = 100; - m_logger->setProgressMax(max); - } - m_logger->setProgressValue(max); - if(getter->httpResponse() != 200 && !getter->isCached()) { - m_logger->addItem(tr("Download error: received HTTP error %1.").arg(getter->httpResponse()),LOGERROR); - m_logger->setFinished(); - emit done(false); - return; - } - if(getter->isCached()) m_logger->addItem(tr("Cached file used."), LOGINFO); - if(error) { - m_logger->addItem(tr("Download error: %1").arg(getter->errorString()),LOGERROR); - m_logger->setFinished(); - emit done(false); - return; - } - else m_logger->addItem(tr("Download finished."),LOGOK); - QCoreApplication::processEvents(); - - - m_logger->setProgressMax(0); - //open downloaded file - QFile genlang(filename); - if(!genlang.open(QIODevice::ReadOnly)) - { - m_logger->addItem(tr("failed to open downloaded file"),LOGERROR); - m_logger->setFinished(); - emit done(false); - return; - } - - //tts - m_tts = TTSBase::getTTS(this,RbSettings::value(RbSettings::Tts).toString()); - - QString errStr; - if(!m_tts->start(&errStr)) - { - m_logger->addItem(errStr,LOGERROR); - m_logger->addItem(tr("Init of TTS engine failed"),LOGERROR); - m_logger->setFinished(); - emit done(false); - return; - } - - // Encoder - m_enc = EncBase::getEncoder(this,RbSettings::value(RbSettings::CurEncoder).toString()); - - if(!m_enc->start()) - { - m_logger->addItem(tr("Init of Encoder engine failed"),LOGERROR); - m_tts->stop(); - m_logger->setFinished(); - emit done(false); - return; - } - - QCoreApplication::processEvents(); - connect(m_logger,SIGNAL(aborted()),this,SLOT(abort())); - - //read in downloaded file - QList > voicepairs; - QTextStream in(&genlang); - in.setCodec("UTF-8"); - QString id, voice; - bool idfound = false; - bool voicefound=false; - while (!in.atEnd()) - { - QString line = in.readLine(); - if(line.contains("id:")) //ID found - { - id = line.remove("id:").remove('"').trimmed(); - idfound = true; - } - else if(line.contains("voice:")) // voice found - { - voice = line.remove("voice:").remove('"').trimmed(); - voicefound=true; - } - - if(idfound && voicefound) - { - voicepairs.append(QPair(id,voice)); - idfound=false; - voicefound=false; - } - } - genlang.close(); - - // check for empty list - if(voicepairs.size() == 0) - { - m_logger->addItem(tr("The downloaded file was empty!"),LOGERROR); - m_logger->setFinished(); - m_tts->stop(); - emit done(false); - return; - } - - m_logger->setProgressMax(voicepairs.size()); - m_logger->setProgressValue(0); - - // create voice clips - QStringList mp3files; - for(int i=0; i< voicepairs.size(); i++) - { - if(m_abort) - { - m_logger->addItem("aborted.",LOGERROR); - m_logger->setFinished(); - m_tts->stop(); - emit done(false); - return; - } - - m_logger->setProgressValue(i); - - QString wavname = m_path + "/" + voicepairs.at(i).first + ".wav"; - QString toSpeak = voicepairs.at(i).second; - QString encodedname = m_path + "/" + voicepairs.at(i).first +".mp3"; - - // todo PAUSE - if(voicepairs.at(i).first == "VOICE_PAUSE") - { - QFile::copy(":/builtin/builtin/VOICE_PAUSE.wav",m_path + "/VOICE_PAUSE.wav"); - - } - else - { - if(toSpeak == "") continue; - - m_logger->addItem(tr("creating ")+toSpeak,LOGINFO); - QCoreApplication::processEvents(); - - // TODO: add support for aborting the operation - QString errStr; - m_tts->voice(toSpeak,wavname, &errStr); // generate wav - } - - // todo strip - char buffer[255]; - - wavtrim((char*)qPrintable(wavname),m_wavtrimThreshold,buffer,255); - - // encode wav - m_enc->encode(wavname,encodedname); - // remove the wav file - QFile::remove(wavname); - // remember the mp3 file for later removing - mp3files << encodedname; - } - - - //make voicefile - FILE* ids2 = fopen(filename.toUtf8(), "r"); - if (ids2 == NULL) - { - m_logger->addItem(tr("Error opening downloaded file"),LOGERROR); - m_logger->setFinished(); - emit done(false); - return; - } - - FILE* output = fopen(QString(m_mountpoint + "/.rockbox/langs/" + m_lang + ".voice").toUtf8(), "wb"); - if (output == NULL) - { - m_logger->addItem(tr("Error opening output file"),LOGERROR); - emit done(false); - return; - } - - voicefont(ids2,m_targetid,(char*)(const char*)m_path.toUtf8(), output); - - //remove .mp3 files - for(int i=0;i< mp3files.size(); i++) - { - QFile::remove(mp3files.at(i)); - } - - // Add Voice file to the install log - QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0); - installlog.beginGroup("selfcreated Voice"); - installlog.setValue("/.rockbox/langs/" + m_lang + ".voice",QDate::currentDate().toString("yyyyMMdd")); - installlog.endGroup(); - installlog.sync(); - - m_logger->setProgressMax(100); - m_logger->setProgressValue(100); - m_logger->addItem(tr("successfully created."),LOGOK); - m_logger->setFinished(); - - emit done(true); -} - -void VoiceFileCreator::updateDataReadProgress(int read, int total) -{ - m_logger->setProgressMax(total); - m_logger->setProgressValue(read); - //qDebug() << "progress:" << read << "/" << total; - -} - diff --git a/rbutil/rbutilqt/voicefile.h b/rbutil/rbutilqt/voicefile.h deleted file mode 100644 index 0bc4df8312..0000000000 --- a/rbutil/rbutilqt/voicefile.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 by Dominik Wenger - * $Id$ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -#ifndef VOICEFILE_H -#define VOICEFILE_H - -#include -#include "progressloggerinterface.h" - -#include "encoders.h" -#include "tts.h" -#include "httpget.h" - -#include "wavtrim.h" -#include "voicefont.h" - -class VoiceFileCreator :public QObject -{ - Q_OBJECT -public: - VoiceFileCreator(QObject* parent); - - //start creation - bool createVoiceFile(ProgressloggerInterface* logger); - - void setMountPoint(QString mountpoint) {m_mountpoint =mountpoint; } - void setTargetId(int id){m_targetid = id;} - void setLang(QString name){m_lang =name;} - void setWavtrimThreshold(int th){m_wavtrimThreshold = th;} - -signals: - void done(bool error); - -private slots: - void abort(); - void downloadDone(bool error); - void updateDataReadProgress(int read, int total); - -private: - - // ptr to encoder, tts and settings - TTSBase* m_tts; - EncBase* m_enc; - HttpGet *getter; - - QString filename; //the temporary file - - QString m_mountpoint; //mountpoint of the device - QString m_path; //path where the wav and mp3 files are stored to - int m_targetid; //the target id - QString m_lang; // the language which will be spoken - int m_wavtrimThreshold; - - ProgressloggerInterface* m_logger; - - bool m_abort; -}; - -#endif - -- cgit v1.2.3