6b5780dae3
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16111 a1c6a512-1295-4272-9138-f99709370657
302 lines
8.8 KiB
C++
302 lines
8.8 KiB
C++
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
*
|
|
* Copyright (C) 2007 by Dominik Wenger
|
|
* $Id: voicefile.h 15932 2007-12-15 13:13:57Z domonoky $
|
|
*
|
|
* 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"
|
|
|
|
#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
|
|
QFile info(m_mountpoint+"/.rockbox/rockbox-info.txt");
|
|
if(!info.open(QIODevice::ReadOnly))
|
|
{
|
|
m_logger->addItem(tr("failed to open rockbox-info.txt"),LOGERROR);
|
|
return false;
|
|
}
|
|
|
|
QString target, features,version;
|
|
while (!info.atEnd()) {
|
|
QString line = info.readLine();
|
|
|
|
if(line.contains("Target:"))
|
|
{
|
|
target = line.remove("Target:").trimmed();
|
|
}
|
|
else if(line.contains("Features:"))
|
|
{
|
|
features = line.remove("Features:").trimmed();
|
|
}
|
|
else if(line.contains("Version:"))
|
|
{
|
|
version = line.remove("Version:").trimmed();
|
|
version = version.left(version.indexOf("-")).remove(0,1);
|
|
}
|
|
}
|
|
info.close();
|
|
|
|
//prepare download url
|
|
QUrl genlangUrl = deviceSettings->value("genlang_url").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->setProxy(m_proxy);
|
|
getter->setFile(downloadFile);
|
|
getter->getFile(genlangUrl);
|
|
|
|
connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
|
|
connect(getter, SIGNAL(downloadDone(int, bool)), this, SLOT(downloadRequestFinished(int, bool)));
|
|
connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
|
|
connect(m_logger, SIGNAL(aborted()), getter, SLOT(abort()));
|
|
return true;
|
|
}
|
|
|
|
|
|
void VoiceFileCreator::downloadRequestFinished(int id, bool error)
|
|
{
|
|
qDebug() << "Install::downloadRequestFinished" << id << error;
|
|
qDebug() << "error:" << getter->errorString();
|
|
|
|
downloadDone(error);
|
|
}
|
|
|
|
|
|
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->abort();
|
|
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->abort();
|
|
return;
|
|
}
|
|
else m_logger->addItem(tr("Download finished."),LOGOK);
|
|
QApplication::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->abort();
|
|
return;
|
|
}
|
|
|
|
//tts
|
|
m_tts = getTTS(userSettings->value("tts").toString());
|
|
m_tts->setCfg(userSettings,deviceSettings);
|
|
|
|
QString errStr;
|
|
if(!m_tts->start(&errStr))
|
|
{
|
|
m_logger->addItem(errStr,LOGERROR);
|
|
m_logger->addItem(tr("Init of TTS engine failed"),LOGERROR);
|
|
m_logger->abort();
|
|
return;
|
|
}
|
|
|
|
// Encoder
|
|
m_enc = getEncoder(userSettings->value("encoder").toString());
|
|
m_enc->setUserCfg(userSettings);
|
|
|
|
if(!m_enc->start())
|
|
{
|
|
m_logger->addItem(tr("Init of Encoder engine failed"),LOGERROR);
|
|
m_tts->stop();
|
|
m_logger->abort();
|
|
return;
|
|
}
|
|
|
|
QApplication::processEvents();
|
|
connect(m_logger,SIGNAL(aborted()),this,SLOT(abort()));
|
|
|
|
//read in downloaded file
|
|
QList<QPair<QString,QString> > 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<QString,QString>(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->abort();
|
|
m_tts->stop();
|
|
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->abort();
|
|
m_tts->stop();
|
|
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);
|
|
QApplication::processEvents();
|
|
m_tts->voice(toSpeak,wavname); // 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->abort();
|
|
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);
|
|
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));
|
|
}
|
|
|
|
m_logger->setProgressMax(100);
|
|
m_logger->setProgressValue(100);
|
|
m_logger->addItem(tr("successfully created."),LOGOK);
|
|
m_logger->abort();
|
|
}
|
|
|
|
void VoiceFileCreator::updateDataReadProgress(int read, int total)
|
|
{
|
|
m_logger->setProgressMax(total);
|
|
m_logger->setProgressValue(read);
|
|
//qDebug() << "progress:" << read << "/" << total;
|
|
|
|
}
|
|
|