Voicefile: remove < and > from voice strings before speaking.
[maemo-rb.git] / rbutil / rbutilqt / base / voicefile.cpp
blobcb9130c41a86ba164b770db3050f0a07bca29ae5
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Wenger
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
19 #include "voicefile.h"
20 #include "utils.h"
21 #include "rockboxinfo.h"
22 #include "rbsettings.h"
23 #include "systeminfo.h"
25 VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent)
27 m_wavtrimThreshold=500;
30 void VoiceFileCreator::abort()
32 m_abort = true;
33 emit aborted();
36 bool VoiceFileCreator::createVoiceFile()
38 m_talkList.clear();
39 m_abort = false;
40 emit logItem(tr("Starting Voicefile generation"),LOGINFO);
42 // test if tempdir exists
43 if(!QDir(QDir::tempPath()+"/rbvoice/").exists())
45 QDir(QDir::tempPath()).mkdir("rbvoice");
47 m_path = QDir::tempPath() + "/rbvoice/";
49 // read rockbox-info.txt
50 RockboxInfo info(m_mountpoint);
51 if(!info.success())
53 emit logItem(tr("could not find rockbox-info.txt"),LOGERROR);
54 emit done(true);
55 return false;
58 QString target = info.target();
59 QString features = info.features();
60 QString version = info.version();
61 m_targetid = info.targetID().toInt();
62 version = version.left(version.indexOf("-")).remove("r");
64 //prepare download url
65 QString genlang = SystemInfo::value(SystemInfo::GenlangUrl).toString();
66 genlang.replace("%LANG%", m_lang);
67 genlang.replace("%TARGET%", target);
68 genlang.replace("%REVISION%", version);
69 genlang.replace("%FEATURES%", features);
70 QUrl genlangUrl(genlang);
71 qDebug() << "[VoiceFileCreator] downloading " << genlangUrl;
73 //download the correct genlang output
74 QTemporaryFile *downloadFile = new QTemporaryFile(this);
75 downloadFile->open();
76 filename = downloadFile->fileName();
77 downloadFile->close();
78 // get the real file.
79 getter = new HttpGet(this);
80 getter->setFile(downloadFile);
82 connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
83 connect(getter, SIGNAL(dataReadProgress(int, int)), this, SIGNAL(logProgress(int, int)));
84 connect(this, SIGNAL(aborted()), getter, SLOT(abort()));
85 emit logItem(tr("Downloading voice info..."),LOGINFO);
86 getter->getFile(genlangUrl);
87 return true;
91 void VoiceFileCreator::downloadDone(bool error)
93 qDebug() << "[VoiceFileCreator] download done, error:" << error;
95 // update progress bar
96 emit logProgress(1,1);
97 if(getter->httpResponse() != 200 && !getter->isCached()) {
98 emit logItem(tr("Download error: received HTTP error %1.").arg(getter->httpResponse()),LOGERROR);
99 emit done(true);
100 return;
103 if(getter->isCached())
104 emit logItem(tr("Cached file used."), LOGINFO);
105 if(error)
107 emit logItem(tr("Download error: %1").arg(getter->errorString()),LOGERROR);
108 emit done(true);
109 return;
111 else
112 emit logItem(tr("Download finished."),LOGINFO);
114 QCoreApplication::processEvents();
116 //open downloaded file
117 QFile genlang(filename);
118 if(!genlang.open(QIODevice::ReadOnly))
120 emit logItem(tr("failed to open downloaded file"),LOGERROR);
121 emit done(true);
122 return;
125 QCoreApplication::processEvents();
127 //read in downloaded file
128 emit logItem(tr("Reading strings..."),LOGINFO);
129 QTextStream in(&genlang);
130 in.setCodec("UTF-8");
131 QString id, voice;
132 bool idfound = false;
133 bool voicefound=false;
134 bool useCorrection = RbSettings::value(RbSettings::UseTtsCorrections).toBool();
135 while (!in.atEnd())
137 QString line = in.readLine();
138 if(line.contains("id:")) //ID found
140 id = line.remove("id:").remove('"').trimmed();
141 idfound = true;
143 else if(line.contains("voice:")) // voice found
145 voice = line.remove("voice:").remove('"').trimmed();
146 voice = voice.remove("<").remove(">");
147 voicefound=true;
150 if(idfound && voicefound)
152 TalkGenerator::TalkEntry entry;
153 entry.toSpeak = voice;
154 entry.wavfilename = m_path + "/" + id + ".wav";
155 //voicefont wants them with .mp3 extension
156 entry.talkfilename = m_path + "/" + id + ".mp3";
157 entry.voiced = false;
158 entry.encoded = false;
159 if(id == "VOICE_PAUSE")
161 QFile::copy(":/builtin/VOICE_PAUSE.wav",m_path + "/VOICE_PAUSE.wav");
162 entry.wavfilename = m_path + "/VOICE_PAUSE.wav";
163 entry.voiced = true;
164 m_talkList.append(entry);
166 else if(entry.toSpeak.isEmpty()) {
167 qDebug() << "[Voicefile] Empty voice string for ID" << id;
169 else {
170 m_talkList.append(entry);
172 idfound=false;
173 voicefound=false;
176 genlang.close();
178 // check for empty list
179 if(m_talkList.size() == 0)
181 emit logItem(tr("The downloaded file was empty!"),LOGERROR);
182 emit done(true);
183 return;
186 // generate files
188 TalkGenerator generator(this);
189 // set language for string correction. If not set no correction will be made.
190 if(useCorrection)
191 generator.setLang(m_lang);
192 connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool)));
193 connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int)));
194 connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int)));
195 connect(this,SIGNAL(aborted()),&generator,SLOT(abort()));
197 if(generator.process(&m_talkList, m_wavtrimThreshold) == TalkGenerator::eERROR)
199 cleanup();
200 emit logProgress(0,1);
201 emit done(true);
202 return;
206 //make voicefile
207 emit logItem(tr("Creating voicefiles..."),LOGINFO);
208 FILE* ids2 = fopen(filename.toLocal8Bit(), "r");
209 if (ids2 == NULL)
211 cleanup();
212 emit logItem(tr("Error opening downloaded file"),LOGERROR);
213 emit done(true);
214 return;
217 FILE* output = fopen(QString(m_mountpoint + "/.rockbox/langs/" + m_lang
218 + ".voice").toLocal8Bit(), "wb");
219 if (output == NULL)
221 cleanup();
222 fclose(ids2);
223 emit logItem(tr("Error opening output file"),LOGERROR);
224 emit done(true);
225 return;
228 voicefont(ids2,m_targetid,m_path.toLocal8Bit().data(), output);
229 // ids2 and output are closed by voicefont().
231 //cleanup
232 cleanup();
234 // Add Voice file to the install log
235 QSettings installlog(m_mountpoint + "/.rockbox/rbutil.log", QSettings::IniFormat, 0);
236 installlog.beginGroup("selfcreated Voice");
237 installlog.setValue("/.rockbox/langs/" + m_lang + ".voice",
238 QDate::currentDate().toString("yyyyMMdd"));
239 installlog.endGroup();
240 installlog.sync();
242 emit logProgress(1,1);
243 emit logItem(tr("successfully created."),LOGOK);
245 emit done(false);
248 //! \brief Cleans up Files potentially left in the temp dir
250 void VoiceFileCreator::cleanup()
252 emit logItem(tr("Cleaning up..."),LOGINFO);
254 for(int i=0; i < m_talkList.size(); i++)
256 if(QFile::exists(m_talkList[i].wavfilename))
257 QFile::remove(m_talkList[i].wavfilename);
258 if(QFile::exists(m_talkList[i].talkfilename))
259 QFile::remove(m_talkList[i].talkfilename);
261 QCoreApplication::processEvents();
263 emit logItem(tr("Finished"),LOGINFO);
265 return;