summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2012-06-09 23:39:57 +0200
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2012-06-09 23:39:57 +0200
commit900cf6d52bd806bd54ad2118e245cd3465ea6815 (patch)
treecf07689f7038e3cae563a5605641d7b2ed85e67e
parent551ea5eaa445bed75c4db157c9394f990306a271 (diff)
downloadrockbox-900cf6d52bd806bd54ad2118e245cd3465ea6815.tar.gz
rockbox-900cf6d52bd806bd54ad2118e245cd3465ea6815.zip
Rockbox Utility: support reading voice strings from target.
If the Rockbox installation has voice strings included use them when generating voice files. Fall back to querying the server if no voice strings are found or the found strings are incompatible. Change-Id: I9883829ab1757e55b1da9a434221a8dbfc702dd4
-rw-r--r--rbutil/rbutilqt/base/voicefile.cpp96
1 files changed, 89 insertions, 7 deletions
diff --git a/rbutil/rbutilqt/base/voicefile.cpp b/rbutil/rbutilqt/base/voicefile.cpp
index b7a5f8f760..70c0f7b653 100644
--- a/rbutil/rbutilqt/base/voicefile.cpp
+++ b/rbutil/rbutilqt/base/voicefile.cpp
@@ -16,11 +16,13 @@
16 * 16 *
17 ****************************************************************************/ 17 ****************************************************************************/
18 18
19#include <QtCore>
19#include "voicefile.h" 20#include "voicefile.h"
20#include "utils.h" 21#include "utils.h"
21#include "rockboxinfo.h" 22#include "rockboxinfo.h"
22#include "rbsettings.h" 23#include "rbsettings.h"
23#include "systeminfo.h" 24#include "systeminfo.h"
25#include "ziputil.h"
24 26
25VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent) 27VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent)
26{ 28{
@@ -54,7 +56,6 @@ bool VoiceFileCreator::createVoiceFile()
54 emit done(true); 56 emit done(true);
55 return false; 57 return false;
56 } 58 }
57
58 QString target = info.target(); 59 QString target = info.target();
59 QString features = info.features(); 60 QString features = info.features();
60 m_targetid = info.targetID().toInt(); 61 m_targetid = info.targetID().toInt();
@@ -62,14 +63,97 @@ bool VoiceFileCreator::createVoiceFile()
62 m_voiceformat = info.voicefmt(); 63 m_voiceformat = info.voicefmt();
63 QString version = m_versionstring.left(m_versionstring.indexOf("-")).remove("r"); 64 QString version = m_versionstring.left(m_versionstring.indexOf("-")).remove("r");
64 65
65 //prepare download url 66 // check if voicefile is present on target
67 QString fn = m_mountpoint + "/.rockbox/langs/voicestrings.zip";
68 qDebug() << "[VoiceFile] searching for zipped voicestrings at" << fn;
69 if(QFileInfo(fn).isFile()) {
70 // search for binary voice strings file in archive
71 ZipUtil z(this);
72 if(z.open(fn)) {
73 QStringList contents = z.files();
74 int index;
75 for(index = 0; index < contents.size(); ++index) {
76 // strip any path, we don't know the structure in the zip
77 if(QFileInfo(contents.at(index)).baseName() == m_lang) {
78 break;
79 }
80 }
81 if(index < contents.size()) {
82 qDebug() << "[VoiceFile] extracting strings file from zip";
83 // extract strings
84 QTemporaryFile stringsfile;
85 stringsfile.open();
86 QString sfn = stringsfile.fileName();
87 // ZipUtil::extractArchive() only compares the filename.
88 if(z.extractArchive(sfn, QFileInfo(contents.at(index)).fileName())) {
89 emit logItem(tr("Extracted voice strings from installation"), LOGINFO);
90
91 stringsfile.seek(0);
92 QByteArray data = stringsfile.readAll();
93 const char* buf = data.constData();
94 // check file header
95 // header (4 bytes): cookie = 9a, version = 06, targetid, options
96 // subheader for each user. Only "core" for now.
97 // subheader (6 bytes): count (2bytes), size (2bytes), offset (2bytes)
98 if(buf[0] != (char)0x9a || buf[1] != 0x06 || buf[2] != m_targetid) {
99 emit logItem(tr("Extracted voice strings incompatible"), LOGINFO);
100 }
101 else {
102 QMap<int, QString> voicestrings;
103
104 /* skip header */
105 int idx = 10;
106 do {
107 unsigned int id = ((unsigned char)buf[idx])<<8
108 | ((unsigned char)buf[idx+1]);
109 // need to use strlen here, since QString::size()
110 // returns number of characters, not bytes.
111 int len = strlen(&buf[idx + 2]);
112 voicestrings[id] = QString::fromUtf8(&buf[idx+2]);
113 idx += 2 + len + 1;
114
115 } while(idx < data.size());
116
117 stringsfile.close();
118
119 // create input file suitable for voicefont from strings.
120 QTemporaryFile voicefontlist;
121 voicefontlist.open();
122 m_filename = voicefontlist.fileName();
123 for(int i = 0; i < voicestrings.size(); ++i) {
124 QByteArray qba;
125 qba = QString("id: %1_%2\n")
126 .arg(voicestrings.keys().at(i) < 0x8000 ? "LANG" : "VOICE")
127 .arg(voicestrings.keys().at(i)).toUtf8();
128 voicefontlist.write(qba);
129 qba = QString("voice: \"%1\"\n").arg(
130 voicestrings[voicestrings.keys().at(i)]).toUtf8();
131 voicefontlist.write(qba);
132 }
133 voicefontlist.close();
134
135 // everything successful, now create the actual voice file.
136 create();
137 return true;
138 }
139
140 }
141 }
142 }
143 }
144 emit logItem(tr("Could not retrieve strings from installation, downloading"), LOGINFO);
145 // if either no zip with voice strings is found or something went wrong
146 // retrieving the necessary files we'll end up here, trying to get the
147 // genlang output as previously from the webserver.
148
149 // prepare download url
66 QString genlang = SystemInfo::value(SystemInfo::GenlangUrl).toString(); 150 QString genlang = SystemInfo::value(SystemInfo::GenlangUrl).toString();
67 genlang.replace("%LANG%", m_lang); 151 genlang.replace("%LANG%", m_lang);
68 genlang.replace("%TARGET%", target); 152 genlang.replace("%TARGET%", target);
69 genlang.replace("%REVISION%", version); 153 genlang.replace("%REVISION%", version);
70 genlang.replace("%FEATURES%", features); 154 genlang.replace("%FEATURES%", features);
71 QUrl genlangUrl(genlang); 155 QUrl genlangUrl(genlang);
72 qDebug() << "[VoiceFileCreator] downloading " << genlangUrl; 156 qDebug() << "[VoiceFileCreator] downloading" << genlangUrl;
73 157
74 //download the correct genlang output 158 //download the correct genlang output
75 QTemporaryFile *downloadFile = new QTemporaryFile(this); 159 QTemporaryFile *downloadFile = new QTemporaryFile(this);
@@ -129,8 +213,6 @@ void VoiceFileCreator::create(void)
129 return; 213 return;
130 } 214 }
131 215
132 QCoreApplication::processEvents();
133
134 //read in downloaded file 216 //read in downloaded file
135 emit logItem(tr("Reading strings..."),LOGINFO); 217 emit logItem(tr("Reading strings..."),LOGINFO);
136 QTextStream in(&genlang); 218 QTextStream in(&genlang);
@@ -200,7 +282,7 @@ void VoiceFileCreator::create(void)
200 connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int))); 282 connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int)));
201 connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int))); 283 connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int)));
202 connect(this,SIGNAL(aborted()),&generator,SLOT(abort())); 284 connect(this,SIGNAL(aborted()),&generator,SLOT(abort()));
203 285
204 if(generator.process(&m_talkList, m_wavtrimThreshold) == TalkGenerator::eERROR) 286 if(generator.process(&m_talkList, m_wavtrimThreshold) == TalkGenerator::eERROR)
205 { 287 {
206 cleanup(); 288 cleanup();
@@ -209,7 +291,7 @@ void VoiceFileCreator::create(void)
209 return; 291 return;
210 } 292 }
211 } 293 }
212 294
213 //make voicefile 295 //make voicefile
214 emit logItem(tr("Creating voicefiles..."),LOGINFO); 296 emit logItem(tr("Creating voicefiles..."),LOGINFO);
215 FILE* ids2 = fopen(m_filename.toLocal8Bit(), "r"); 297 FILE* ids2 = fopen(m_filename.toLocal8Bit(), "r");