SVN_SILENT made messages (.desktop file)
[kdeaccessibility.git] / kttsd / plugins / freetts / freettsproc.cpp
blob438767237ee3c9cd80241965ca290fa1134ef2c9
1 /****************************************************************************
2 Main speaking functions for the FreeTTS Plug in
3 -------------------
4 Copyright : (C) 2004 Paul Giannaros
5 -------------------
6 Original author: Paul Giannaros <ceruleanblaze@gmail.com>
7 Current Maintainer: Paul Giannaros <ceruleanblaze@gmail.com>
8 ******************************************************************************/
10 /*******************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; version 2 of the License. *
15 * *
16 ******************************************************************************/
18 #include <QtCore/QFileInfo>
20 #include <kdebug.h>
21 #include <kconfig.h>
22 #include <kconfiggroup.h>
23 #include <kstandarddirs.h>
24 #include <k3process.h>
26 #include "freettsproc.h"
28 /** Constructor */
29 FreeTTSProc::FreeTTSProc( QObject* parent, const QStringList& /*args*/) :
30 PlugInProc( parent, "freettsproc" ) {
31 kDebug() << "Running: FreeTTSProc::FreeTTSProc";
32 m_state = psIdle;
33 m_waitingStop = false;
34 m_freettsProc = 0;
37 /** Desctructor */
38 FreeTTSProc::~FreeTTSProc() {
39 kDebug() << "Running: FreeTTSProc::~FreeTTSProc";
40 if (m_freettsProc) {
41 stopText();
42 delete m_freettsProc;
46 /** Initializate the speech */
47 bool FreeTTSProc::init(KConfig *config, const QString &configGroup) {
48 kDebug() << "Running: FreeTTSProc::init()";
49 kDebug() << "Initializing plug in: FreeTTS";
50 KConfigGroup group = config->group(configGroup);
51 m_freettsJarPath = group.readEntry("FreeTTSJarPath", "freetts.jar");
52 kDebug() << "FreeTTSProc::init: path to freetts.jar: " << m_freettsJarPath;
53 return true;
56 /**
57 * Say a text. Synthesize and audibilize it.
58 * @param text The text to be spoken.
60 * If the plugin supports asynchronous operation, it should return immediately.
62 void FreeTTSProc::sayText(const QString &text) {
63 synth(text, QString(), m_freettsJarPath);
66 /**
67 * Synthesize text into an audio file, but do not send to the audio device.
68 * @param text The text to be synthesized.
69 * @param suggestedFilename Full pathname of file to create. The plugin
70 * may ignore this parameter and choose its own
71 * filename. KTTSD will query the generated
72 * filename using getFilename().
74 * If the plugin supports asynchronous operation, it should return immediately.
76 void FreeTTSProc::synthText(const QString& text, const QString& suggestedFilename) {
77 kDebug() << "Running: FreeTTSProc::synthText";
78 synth(text, suggestedFilename, m_freettsJarPath);
81 void FreeTTSProc::synth(
82 const QString &text,
83 const QString &synthFilename,
84 const QString& freettsJarPath) {
86 kDebug() << "Running: FreeTTSProc::synth";
88 if (m_freettsProc) {
89 if (m_freettsProc->isRunning()) m_freettsProc->kill();
90 delete m_freettsProc;
91 m_freettsProc = 0;
94 m_freettsProc = new K3Process;
95 connect(m_freettsProc, SIGNAL(processExited(K3Process*)),
96 this, SLOT(slotProcessExited(K3Process*)));
97 connect(m_freettsProc, SIGNAL(receivedStdout(K3Process*, char*, int)),
98 this, SLOT(slotReceivedStdout(K3Process*, char*, int)));
99 connect(m_freettsProc, SIGNAL(receivedStderr(K3Process*, char*, int)),
100 this, SLOT(slotReceivedStderr(K3Process*, char*, int)));
101 connect(m_freettsProc, SIGNAL(wroteStdin(K3Process*)),
102 this, SLOT(slotWroteStdin(K3Process* )));
103 if (synthFilename.isNull())
104 m_state = psSaying;
105 else
106 m_state = psSynthing;
109 QString saidText = text;
110 saidText += '\n';
112 /// As freetts.jar doesn't seem to like being called from an absolute path,
113 /// we need to strip off the path to freetts.jar and pass it to
114 /// K3Process::setWorkingDirectory()
115 /// We could just strip off 11 characters from the end of the path to freetts.jar, but thats
116 /// not exactly very portable...
117 QString filename = QFileInfo(freettsJarPath).baseName().append(QString(".").append(QFileInfo(freettsJarPath).suffix()));
118 QString freettsJarDir = freettsJarPath.left((freettsJarPath.length() - filename.length()) - 1);
120 m_freettsProc->setWorkingDirectory(freettsJarDir);
121 kDebug() << "FreeTTSProc::synthText: moved to directory '" << freettsJarDir << "'";
122 kDebug() << "FreeTTSProc::synthText: Running file: '" << filename << "'";
123 *m_freettsProc << "java" << "-jar" << filename;
125 /// Dump audio into synthFilename
127 if (!synthFilename.isNull()) *m_freettsProc << "-dumpAudio" << synthFilename;
129 m_synthFilename = synthFilename;
131 kDebug() << "FreeTTSProc::synth: Synthing text: '" << saidText << "' using FreeTTS plug in";
132 if (!m_freettsProc->start(K3Process::NotifyOnExit, K3Process::All)) {
133 kDebug() << "FreeTTSProc::synth: Error starting FreeTTS process. Is freetts.jar in the PATH?";
134 m_state = psIdle;
135 kDebug() << "K3Process args: " << m_freettsProc->args();
136 return;
138 kDebug()<< "FreeTTSProc:synth: FreeTTS initialized";
139 m_freettsProc->writeStdin(saidText.toLatin1(), saidText.length());
143 * Returning the filename of the synth'd text
144 * @returns The filename of the last synth'd text
146 QString FreeTTSProc::getFilename() {
147 kDebug() << "FreeTTSProc::getFilename: returning " << m_synthFilename;
148 return m_synthFilename;
152 * Stop current operation (saying or synthesizing text).
153 * Important: This function may be called from a thread different from the
154 * one that called sayText or synthText.
155 * If the plugin cannot stop an in-progress @ref sayText or
156 * @ref synthText operation, it must not block waiting for it to complete.
157 * Instead, return immediately.
159 * If a plugin returns before the operation has actually been stopped,
160 * the plugin must emit the @ref stopped signal when the operation has
161 * actually stopped.
163 * The plugin should change to the psIdle state after stopping the
164 * operation.
166 void FreeTTSProc::stopText() {
167 kDebug() << "FreeTTSProc::stopText:: Running";
168 if (m_freettsProc) {
169 if (m_freettsProc->isRunning()) {
170 kDebug() << "FreeTTSProc::stopText: killing FreeTTS.";
171 m_waitingStop = true;
172 m_freettsProc->kill();
174 else m_state = psIdle;
176 else m_state = psIdle;
177 kDebug() << "FreeTTSProc::stopText: FreeTTS stopped.";
180 void FreeTTSProc::slotProcessExited(K3Process*) {
181 kDebug() << "FreeTTSProc:slotProcessExited: FreeTTS process has exited.";
182 pluginState prevState = m_state;
183 if (m_waitingStop) {
184 m_waitingStop = false;
185 m_state = psIdle;
186 emit stopped();
188 else {
189 m_state = psFinished;
190 if (prevState == psSaying)
191 emit sayFinished();
192 else if (prevState == psSynthing)
193 emit synthFinished();
197 void FreeTTSProc::slotReceivedStdout(K3Process*, char* buffer, int buflen) {
198 QString buf = QString::fromLatin1(buffer, buflen);
199 kDebug() << "FreeTTSProc::slotReceivedStdout: Received output from FreeTTS: " << buf;
202 void FreeTTSProc::slotReceivedStderr(K3Process*, char* buffer, int buflen) {
203 QString buf = QString::fromLatin1(buffer, buflen);
204 kDebug() << "FreeTTSProc::slotReceivedStderr: Received error from FreeTTS: " << buf;
207 void FreeTTSProc::slotWroteStdin(K3Process*) {
208 kDebug() << "FreeTTSProc::slotWroteStdin: closing Stdin";
209 m_freettsProc->closeStdin();
213 * Return the current state of the plugin.
214 * This function only makes sense in asynchronous mode.
215 * @return The pluginState of the plugin.
217 * @see pluginState
219 pluginState FreeTTSProc::getState() {
220 return m_state;
224 * Acknowledges a finished state and resets the plugin state to psIdle.
226 * If the plugin is not in state psFinished, nothing happens.
227 * The plugin may use this call to do any post-processing cleanup,
228 * for example, blanking the stored filename (but do not delete the file).
229 * Calling program should call getFilename prior to ackFinished.
231 void FreeTTSProc::ackFinished() {
232 if (m_state == psFinished) {
233 m_state = psIdle;
234 m_synthFilename.clear();
239 * Returns True if the plugin supports asynchronous processing,
240 * i.e., returns immediately from sayText or synthText.
241 * @return True if this plugin supports asynchronous processing.
243 * If the plugin returns True, it must also implement @ref getState .
244 * It must also emit @ref sayFinished or @ref synthFinished signals when
245 * saying or synthesis is completed.
247 bool FreeTTSProc::supportsAsync() {
248 // return true;
249 return true;
253 * Returns True if the plugIn supports synthText method,
254 * i.e., is able to synthesize text to a sound file without
255 * audibilizing the text.
256 * @return True if this plugin supports synthText method.
258 bool FreeTTSProc::supportsSynth() {
259 // return true;
260 return true;
264 #include "freettsproc.moc"