25 #include "ssmlconvert.moc"
28 #include <QtXml/qdom.h>
29 #include <QtCore/QFile>
30 #include <QtCore/QTextStream>
33 #include <kdeversion.h>
34 #include <kstandarddirs.h>
36 #include <QStringList>
37 #include <ktemporaryfile.h>
42 m_talkers = QStringList();
57 if (!m_inFilename.isEmpty()) QFile::remove(m_inFilename);
58 if (!m_outFilename.isEmpty()) QFile::remove(m_outFilename);
67 QString t = talkercode.section(QLatin1String(
"synthesizer=" ), 1, 1);
68 t = t.section(QLatin1Char(
'"' ), 1, 1);
69 if(t.contains(QLatin1String(
"flite" )))
70 return QLatin1String(
"flite" );
72 return t.left(t.indexOf(QLatin1String(
" " ))).toLower();
108 ssml.setContent(text,
false);
110 QStringList matches = m_talkers;
113 QDomElement root = ssml.documentElement();
114 if(root.tagName() != QLatin1String(
"speak" )) {
125 QString talklang, talkvoice, talkgender, talkvolume, talkrate, talkname;
127 kDebug() <<
"SSMLConvert::appropriateTalker: BEFORE LANGUAGE SEARCH: " << matches.join(QLatin1String(
" " ));;
131 if(root.hasAttribute(QLatin1String(
"xml:lang" ))) {
132 QString lang = root.attribute(QLatin1String(
"xml:lang" ));
133 kDebug() <<
"SSMLConvert::appropriateTalker: xml:lang found (" << lang <<
")";
135 if(lang.contains(QLatin1String(
"en-" ))) {
136 kDebug() <<
"SSMLConvert::appropriateTalker: English";
137 lang = QLatin1String(
"en" );
141 matches = matches.filter(QLatin1String(
"lang=\"" ) + lang);
144 kDebug() <<
"SSMLConvert::appropriateTalker: no xml:lang found. Defaulting to en..";
145 matches = matches.filter(QLatin1String(
"lang=\"en" ));
148 kDebug() <<
"SSMLConvert::appropriateTalker: AFTER LANGUAGE SEARCH: " << matches.join(QLatin1String(
" " ));;
155 if(root.hasAttribute(QLatin1String(
"gender" ))) {
156 QString gender = root.attribute(QLatin1String(
"gender" ));
157 kDebug() <<
"SSMLConvert::appropriateTalker: gender found (" << gender <<
")";
159 if(!(gender == QLatin1String(
"male" ) || gender == QLatin1String(
"female" ))) {
161 if(matches.filter(QLatin1String(
"gender=\"" ) + gender).count() >= 1)
162 matches = matches.filter(QLatin1String(
"gender=\"" ) + gender);
166 kDebug() <<
"SSMLConvert::appropriateTalker: no gender found.";
175 if(matches.filter(QLatin1String(
"synthesizer=\"Festival Interactive" )).count() >= 1 ||
178 matches.filter(QLatin1String(
"synthesizer=\"Hadifix" )).count() >= 1) {
180 kDebug() <<
"SSMLConvert::appropriateTalker: Prosody allowed";
181 QStringList tmpmatches = matches.filter(QLatin1String(
"synthesizer=\"Festival Interactive" ));
182 matches = matches.filter(QLatin1String(
"synthesizer=\"Hadifix" ));
183 matches = tmpmatches + matches;
186 kDebug() <<
"SSMLConvert::appropriateTalker: No prosody-supporting talkers found";
207 m_xsltFilename = xsltFilename;
209 KTemporaryFile inFile;
210 inFile.setPrefix(QLatin1String(
"kttsd-" ));
211 inFile.setSuffix(QLatin1String(
".ssml" ));
212 inFile.setAutoRemove(
false);
214 m_inFilename = inFile.fileName();
215 QTextStream wstream (&inFile);
224 KTemporaryFile outFile;
225 outFile.setPrefix(QLatin1String(
"kttsd-" ));
226 outFile.setSuffix(QLatin1String(
".output" ));
227 outFile.setAutoRemove(
false);
229 m_outFilename = outFile.fileName();
233 m_xsltProc =
new QProcess;
234 args << QLatin1String(
"-o" ) << m_outFilename << QLatin1String(
"--novalid" )
235 << m_xsltFilename << m_inFilename;
240 connect(m_xsltProc, SIGNAL(finished(
int,QProcess::ExitStatus)),
241 this, SLOT(slotProcessExited()));
242 if (!m_xsltProc->execute(QLatin1String(
"xsltproc"), args))
244 kDebug() <<
"SSMLConvert::transform: Error starting xsltproc";
251 void SSMLConvert::slotProcessExited()
253 m_xsltProc->deleteLater();
270 QFile readfile(m_outFilename);
271 if(!readfile.open(QIODevice::ReadOnly)) {
273 kDebug() <<
"SSMLConvert::slotProcessExited: Could not read file " << m_outFilename;
276 QTextStream rstream(&readfile);
277 QString convertedData = rstream.readAll();
283 QFile::remove(m_inFilename);
284 m_inFilename.clear();
285 QFile::remove(m_outFilename);
286 m_outFilename.clear();
291 return convertedData;
SSMLConvert()
Constructors.
bool transform(const QString &text, const QString &xsltFilename)
Applies the spreadsheet for a talker to the SSML and returns the talker-native output.
int getState()
Returns current processing state.
virtual ~SSMLConvert()
Destructor.
QString appropriateTalker(const QString &text) const
Returns the most appropriate talker for the text to synth's talker code.
QString getOutput()
Returns the output from call to transform.
void setTalkers(const QStringList &talkers)
Set the talker codes to be used.
void transformFinished()
Emitted whenever tranforming is completed.
QString extractTalker(const QString &talkercode)
Extract the synth name from a talker code (i.e festival, flite, freetts).