New game plugin by Joshua Simmons FS#7369: Goban plugin, Go/Igo/Weiqi/Baduk game...
[kugel-rb.git] / rbutil / rbutilqt / voicefile.cpp
blob1488ead7421312a8d0921968ed4380a60b2843f8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
10 * $Id$
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 ****************************************************************************/
20 #include "voicefile.h"
22 #define STATE_INVALID 0
23 #define STATE_PHRASE 1
24 #define STATE_VOICE 2
27 VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent)
29 m_wavtrimThreshold=500;
32 void VoiceFileCreator::abort()
34 m_abort = true;
37 bool VoiceFileCreator::createVoiceFile(ProgressloggerInterface* logger)
39 m_abort = false;
40 m_logger = logger;
41 m_logger->addItem(tr("Starting Voicefile generation"),LOGINFO);
43 // test if tempdir exists
44 if(!QDir(QDir::tempPath()+"/rbvoice/").exists())
46 QDir(QDir::tempPath()).mkdir("rbvoice");
49 m_path = QDir::tempPath() + "/rbvoice/";
51 // read rockbox-info.txt
52 QFile info(m_mountpoint+"/.rockbox/rockbox-info.txt");
53 if(!info.open(QIODevice::ReadOnly))
55 m_logger->addItem(tr("failed to open rockbox-info.txt"),LOGERROR);
56 m_logger->abort();
57 emit done(false);
58 return false;
61 QString target, features,version;
62 while (!info.atEnd()) {
63 QString line = info.readLine();
65 if(line.contains("Target:"))
67 target = line.remove("Target:").trimmed();
69 else if(line.contains("Features:"))
71 features = line.remove("Features:").trimmed();
73 else if(line.contains("Version:"))
75 version = line.remove("Version:").trimmed();
76 version = version.left(version.indexOf("-")).remove(0,1);
79 info.close();
81 //prepare download url
82 QUrl genlangUrl = settings->genlangUrl() +"?lang=" +m_lang+"&t="+target+"&rev="+version+"&f="+features;
84 qDebug() << "downloading " << genlangUrl;
86 //download the correct genlang output
87 QTemporaryFile *downloadFile = new QTemporaryFile(this);
88 downloadFile->open();
89 filename = downloadFile->fileName();
90 downloadFile->close();
91 // get the real file.
92 getter = new HttpGet(this);
93 getter->setFile(downloadFile);
95 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
96 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateDataReadProgress(int, int)));
97 connect(m_logger, SIGNAL(aborted()), getter, SLOT(abort()));
99 getter->getFile(genlangUrl);
100 return true;
104 void VoiceFileCreator::downloadDone(bool error)
106 qDebug() << "Voice creator::downloadDone, error:" << error;
108 // update progress bar
109 int max = m_logger->getProgressMax();
110 if(max == 0) {
111 max = 100;
112 m_logger->setProgressMax(max);
114 m_logger->setProgressValue(max);
115 if(getter->httpResponse() != 200 && !getter->isCached()) {
116 m_logger->addItem(tr("Download error: received HTTP error %1.").arg(getter->httpResponse()),LOGERROR);
117 m_logger->abort();
118 emit done(false);
119 return;
121 if(getter->isCached()) m_logger->addItem(tr("Cached file used."), LOGINFO);
122 if(error) {
123 m_logger->addItem(tr("Download error: %1").arg(getter->errorString()),LOGERROR);
124 m_logger->abort();
125 emit done(false);
126 return;
128 else m_logger->addItem(tr("Download finished."),LOGOK);
129 QCoreApplication::processEvents();
132 m_logger->setProgressMax(0);
133 //open downloaded file
134 QFile genlang(filename);
135 if(!genlang.open(QIODevice::ReadOnly))
137 m_logger->addItem(tr("failed to open downloaded file"),LOGERROR);
138 m_logger->abort();
139 emit done(false);
140 return;
143 //tts
144 m_tts = TTSBase::getTTS(settings->curTTS());
145 m_tts->setCfg(settings);
147 QString errStr;
148 if(!m_tts->start(&errStr))
150 m_logger->addItem(errStr,LOGERROR);
151 m_logger->addItem(tr("Init of TTS engine failed"),LOGERROR);
152 m_logger->abort();
153 emit done(false);
154 return;
157 // Encoder
158 m_enc = EncBase::getEncoder(settings->curEncoder());
159 m_enc->setCfg(settings);
161 if(!m_enc->start())
163 m_logger->addItem(tr("Init of Encoder engine failed"),LOGERROR);
164 m_tts->stop();
165 m_logger->abort();
166 emit done(false);
167 return;
170 QCoreApplication::processEvents();
171 connect(m_logger,SIGNAL(aborted()),this,SLOT(abort()));
173 //read in downloaded file
174 QList<QPair<QString,QString> > voicepairs;
175 QTextStream in(&genlang);
176 in.setCodec("UTF-8");
177 QString id, voice;
178 bool idfound = false;
179 bool voicefound=false;
180 while (!in.atEnd())
182 QString line = in.readLine();
183 if(line.contains("id:")) //ID found
185 id = line.remove("id:").remove('"').trimmed();
186 idfound = true;
188 else if(line.contains("voice:")) // voice found
190 voice = line.remove("voice:").remove('"').trimmed();
191 voicefound=true;
194 if(idfound && voicefound)
196 voicepairs.append(QPair<QString,QString>(id,voice));
197 idfound=false;
198 voicefound=false;
201 genlang.close();
203 // check for empty list
204 if(voicepairs.size() == 0)
206 m_logger->addItem(tr("The downloaded file was empty!"),LOGERROR);
207 m_logger->abort();
208 m_tts->stop();
209 emit done(false);
210 return;
213 m_logger->setProgressMax(voicepairs.size());
214 m_logger->setProgressValue(0);
216 // create voice clips
217 QStringList mp3files;
218 for(int i=0; i< voicepairs.size(); i++)
220 if(m_abort)
222 m_logger->addItem("aborted.",LOGERROR);
223 m_logger->abort();
224 m_tts->stop();
225 emit done(false);
226 return;
229 m_logger->setProgressValue(i);
231 QString wavname = m_path + "/" + voicepairs.at(i).first + ".wav";
232 QString toSpeak = voicepairs.at(i).second;
233 QString encodedname = m_path + "/" + voicepairs.at(i).first +".mp3";
235 // todo PAUSE
236 if(voicepairs.at(i).first == "VOICE_PAUSE")
238 QFile::copy(":/builtin/builtin/VOICE_PAUSE.wav",m_path + "/VOICE_PAUSE.wav");
241 else
243 if(toSpeak == "") continue;
245 m_logger->addItem(tr("creating ")+toSpeak,LOGINFO);
246 QCoreApplication::processEvents();
247 m_tts->voice(toSpeak,wavname); // generate wav
250 // todo strip
251 char buffer[255];
253 wavtrim((char*)qPrintable(wavname),m_wavtrimThreshold,buffer,255);
255 // encode wav
256 m_enc->encode(wavname,encodedname);
257 // remove the wav file
258 QFile::remove(wavname);
259 // remember the mp3 file for later removing
260 mp3files << encodedname;
264 //make voicefile
265 FILE* ids2 = fopen(filename.toUtf8(), "r");
266 if (ids2 == NULL)
268 m_logger->addItem(tr("Error opening downloaded file"),LOGERROR);
269 m_logger->abort();
270 emit done(false);
271 return;
274 FILE* output = fopen(QString(m_mountpoint + "/.rockbox/langs/" + m_lang + ".voice").toUtf8(), "wb");
275 if (output == NULL)
277 m_logger->addItem(tr("Error opening output file"),LOGERROR);
278 emit done(false);
279 return;
282 voicefont(ids2,m_targetid,(char*)(const char*)m_path.toUtf8(), output);
284 //remove .mp3 files
285 for(int i=0;i< mp3files.size(); i++)
287 QFile::remove(mp3files.at(i));
290 // Add Voice file to the install log
291 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
292 installlog.beginGroup("selfcreated Voice");
293 installlog.setValue("/.rockbox/langs/" + m_lang + ".voice",QDate::currentDate().toString("yyyyMMdd"));
294 installlog.endGroup();
295 installlog.sync();
297 m_logger->setProgressMax(100);
298 m_logger->setProgressValue(100);
299 m_logger->addItem(tr("successfully created."),LOGOK);
300 m_logger->abort();
302 emit done(true);
305 void VoiceFileCreator::updateDataReadProgress(int read, int total)
307 m_logger->setProgressMax(total);
308 m_logger->setProgressValue(read);
309 //qDebug() << "progress:" << read << "/" << total;