diff options
-rw-r--r-- | rbutil/rbutilqt/base/voicefile.cpp | 96 |
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 | ||
25 | VoiceFileCreator::VoiceFileCreator(QObject* parent) :QObject(parent) | 27 | VoiceFileCreator::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"); |