summaryrefslogtreecommitdiffstats
path: root/kttsd/plugins/freetts
diff options
context:
space:
mode:
Diffstat (limited to 'kttsd/plugins/freetts')
-rw-r--r--kttsd/plugins/freetts/Makefile.am18
-rw-r--r--kttsd/plugins/freetts/README6
-rw-r--r--kttsd/plugins/freetts/configure.in.bot15
-rw-r--r--kttsd/plugins/freetts/configure.in.in22
-rw-r--r--kttsd/plugins/freetts/freettsconf.cpp230
-rw-r--r--kttsd/plugins/freetts/freettsconf.h122
-rw-r--r--kttsd/plugins/freetts/freettsconfigwidget.ui200
-rw-r--r--kttsd/plugins/freetts/freettsplugin.cpp26
-rw-r--r--kttsd/plugins/freetts/freettsproc.cpp275
-rw-r--r--kttsd/plugins/freetts/freettsproc.h180
-rw-r--r--kttsd/plugins/freetts/kttsd_freettsplugin.desktop51
11 files changed, 1145 insertions, 0 deletions
diff --git a/kttsd/plugins/freetts/Makefile.am b/kttsd/plugins/freetts/Makefile.am
new file mode 100644
index 0000000..be9312b
--- /dev/null
+++ b/kttsd/plugins/freetts/Makefile.am
@@ -0,0 +1,18 @@
+INCLUDES = \
+ -I$(top_srcdir)/kttsd/libkttsd -I$(top_builddir)/kttsd/libkttsd \
+ $(all_includes)
+
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = libkttsd_freettsplugin.la
+
+libkttsd_freettsplugin_la_SOURCES = \
+ freettsconfigwidget.ui \
+ freettsconf.cpp \
+ freettsproc.cpp \
+ freettsplugin.cpp
+libkttsd_freettsplugin_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries)
+libkttsd_freettsplugin_la_LIBADD = $(top_builddir)/kttsd/libkttsd/libkttsd.la
+
+services_DATA = kttsd_freettsplugin.desktop
+servicesdir = $(kde_servicesdir)
diff --git a/kttsd/plugins/freetts/README b/kttsd/plugins/freetts/README
new file mode 100644
index 0000000..54d9dc2
--- /dev/null
+++ b/kttsd/plugins/freetts/README
@@ -0,0 +1,6 @@
+This is the directory containing the FreeTTS plug in.
+If you intend to edit the GUI (freettsconfig.ui) you will have to first
+copy kttsd/libkttsd/pluginconf.h to a standard include directory
+like $KDEDIR/include/ since the interface has been tweaked to derive
+from PlugInConf instead of QWidget and Qt Designer refuses to open it
+if the header is not properly place.
diff --git a/kttsd/plugins/freetts/configure.in.bot b/kttsd/plugins/freetts/configure.in.bot
new file mode 100644
index 0000000..b3985b9
--- /dev/null
+++ b/kttsd/plugins/freetts/configure.in.bot
@@ -0,0 +1,15 @@
+if test "x$freetts_bindir" = "xno"; then
+ if test "$compile_freetts_plugin" = "yes"; then
+ echo ""
+ echo "======================================================"
+ echo "The freetts.jar Java archive has not been found on"
+ echo "this system. The FreeTTS plugin will be built, "
+ echo "but you must install FreeTTS it before you can use it,"
+ echo "or if it already installed you must set the path to"
+ echo "it in the KDE Text-to-Speech Manager."
+ echo "FreeTTS is available from freetts.sourceforge.net"
+ echo "====================================================="
+ all_tests=bad
+ fi
+fi
+
diff --git a/kttsd/plugins/freetts/configure.in.in b/kttsd/plugins/freetts/configure.in.in
new file mode 100644
index 0000000..78555fc
--- /dev/null
+++ b/kttsd/plugins/freetts/configure.in.in
@@ -0,0 +1,22 @@
+dnl ================
+dnl checks for FreeTTS
+dnl ================
+
+AC_ARG_ENABLE(kttsd-freetts,
+ AC_HELP_STRING([--enable-kttsd-freetts],
+ [build KTTSD FreeTTS Plugin [default=yes]]),
+ freetts_plugin=$enableval,
+ freetts_plugin=yes)
+
+compile_freetts_plugin="yes"
+
+if test "x$freetts_plugin" = "xno"; then
+ compile_freetts_plugin="no"
+fi
+
+dnl Check for festival executable.
+dnl Note that Festival Interactive plugin is always built
+dnl whether binary is found or not, unless user overrides with -disable-freetts.
+AC_PATH_PROG(freetts_bindir, "freetts.jar", "no")
+
+AM_CONDITIONAL(include_kttsd_freetts, test "x$compile_freetts_plugin" = "xyes")
diff --git a/kttsd/plugins/freetts/freettsconf.cpp b/kttsd/plugins/freetts/freettsconf.cpp
new file mode 100644
index 0000000..701af5e
--- /dev/null
+++ b/kttsd/plugins/freetts/freettsconf.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+ Configuration widget and functions for FreeTTS (interactive) plug in
+ -------------------
+ Copyright : (C) 2004 Paul Giannaros
+ -------------------
+ Original author: Paul Giannaros <ceruleanblaze@gmail.com>
+ Current Maintainer: Paul Giannaros <ceruleanblaze@gmail.com>
+ ******************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; version 2 of the License. *
+ * *
+ ***************************************************************************/
+
+// Qt includes.
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qfile.h>
+#include <qapplication.h>
+
+// KDE includes.
+#include <kdialog.h>
+#include <ktempfile.h>
+#include <kstandarddirs.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kprogress.h>
+
+// KTTS includes.
+#include <pluginconf.h>
+#include <testplayer.h>
+
+// FreeTTS includes.
+#include "freettsconf.h"
+#include "freettsconfigwidget.h"
+
+/** Constructor */
+FreeTTSConf::FreeTTSConf( QWidget* parent, const char* name, const QStringList&/*args*/) :
+ PlugInConf( parent, name ) {
+
+ // kdDebug() << "FreeTTSConf::FreeTTSConf: Running" << endl;
+ m_freettsProc = 0;
+ m_progressDlg = 0;
+
+ QVBoxLayout *layout = new QVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint(), "FreeTTSConfigWidgetLayout");
+ layout->setAlignment (Qt::AlignTop);
+ m_widget = new FreeTTSConfWidget(this, "FreeTTSConfigWidget");
+ layout->addWidget(m_widget);
+
+ defaults();
+
+ connect(m_widget->freettsPath, SIGNAL(textChanged(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->freettsTest, SIGNAL(clicked()), this, SLOT(slotFreeTTSTest_clicked()));
+}
+
+/** Destructor */
+FreeTTSConf::~FreeTTSConf() {
+ // kdDebug() << "Running: FreeTTSConf::~FreeTTSConf()" << endl;
+ if (!m_waveFile.isNull()) QFile::remove(m_waveFile);
+ delete m_freettsProc;
+ delete m_progressDlg;
+}
+
+void FreeTTSConf::load(KConfig *config, const QString &configGroup) {
+ // kdDebug() << "FreeTTSConf::load: Running" << endl;
+
+ config->setGroup(configGroup);
+ QString freeTTSJar = config->readEntry("FreeTTSJarPath", QString::null);
+ if (freeTTSJar.isEmpty())
+ {
+ config->setGroup("FreeTTS");
+ freeTTSJar = config->readEntry("FreeTTSJarPath", QString::null);
+ }
+ if (freeTTSJar.isEmpty())
+ freeTTSJar = getLocation("freetts.jar");
+ m_widget->freettsPath->setURL(freeTTSJar);
+ /// If freettsPath is still empty, then we couldn't find the file in the path.
+}
+
+void FreeTTSConf::save(KConfig *config, const QString &configGroup){
+ // kdDebug() << "FreeTTSConf::save: Running" << endl;
+
+ config->setGroup("FreeTTS");
+ config->writeEntry("FreeTTSJarPath",
+ realFilePath(m_widget->freettsPath->url()));
+
+ config->setGroup(configGroup);
+ if(m_widget->freettsPath->url().isEmpty())
+ KMessageBox::sorry(0, i18n("Unable to locate freetts.jar in your path.\nPlease specify the path to freetts.jar in the Properties tab before using KDE Text-to-Speech"), i18n("KDE Text-to-Speech"));
+ config->writeEntry("FreeTTSJarPath",
+ realFilePath(m_widget->freettsPath->url()));
+}
+
+void FreeTTSConf::defaults(){
+ // kdDebug() << "Running: FreeTTSConf::defaults()" << endl;
+ m_widget->freettsPath->setURL("");
+}
+
+void FreeTTSConf::setDesiredLanguage(const QString &lang)
+{
+ m_languageCode = lang;
+}
+
+QString FreeTTSConf::getTalkerCode()
+{
+ QString freeTTSJar = realFilePath(m_widget->freettsPath->url());
+ if (!freeTTSJar.isEmpty())
+ {
+ if (!getLocation(freeTTSJar).isEmpty())
+ {
+ return QString(
+ "<voice lang=\"%1\" name=\"%2\" gender=\"%3\" />"
+ "<prosody volume=\"%4\" rate=\"%5\" />"
+ "<kttsd synthesizer=\"%6\" />")
+ .arg(m_languageCode)
+ .arg("fixed")
+ .arg("neutral")
+ .arg("medium")
+ .arg("medium")
+ .arg("FreeTTS");
+ }
+ }
+ return QString::null;
+}
+
+// QString FreeTTSConf::getLocation(const QString &name) {
+// /// Iterate over the path and see if 'name' exists in it. Return the
+// /// full path to it if it does. Else return an empty QString.
+// kdDebug() << "FreeTTSConf::getLocation: Searching for " << name << " in the path... " << endl;
+// kdDebug() << m_path << endl;
+// for(QStringList::iterator it = m_path.begin(); it != m_path.end(); ++it) {
+// QString fullName = *it;
+// fullName += "/";
+// fullName += name;
+// /// The user either has the directory of the file in the path...
+// if(QFile::exists(fullName)) {
+// return fullName;
+// kdDebug() << fullName << endl;
+// }
+// /// ....Or the file itself
+// else if(QFileInfo(*it).baseName().append(QString(".").append(QFileInfo(*it).extension())) == name) {
+// return fullName;
+// kdDebug() << fullName << endl;
+// }
+// }
+// return "";
+// }
+
+
+void FreeTTSConf::slotFreeTTSTest_clicked()
+{
+ // kdDebug() << "FreeTTSConf::slotFreeTTSTest_clicked(): Running" << endl;
+ // If currently synthesizing, stop it.
+ if (m_freettsProc)
+ m_freettsProc->stopText();
+ else
+ {
+ m_freettsProc = new FreeTTSProc();
+ connect (m_freettsProc, SIGNAL(stopped()), this, SLOT(slotSynthStopped()));
+ }
+ // Create a temp file name for the wave file.
+ KTempFile tempFile (locateLocal("tmp", "freettsplugin-"), ".wav");
+ QString tmpWaveFile = tempFile.file()->name();
+ tempFile.close();
+
+ // Get test message in the language of the voice.
+ QString testMsg = testMessage(m_languageCode);
+
+ // Tell user to wait.
+ m_progressDlg = new KProgressDialog(m_widget, "kttsmgr_freetts_testdlg",
+ i18n("Testing"),
+ i18n("Testing."),
+ true);
+ m_progressDlg->progressBar()->hide();
+ m_progressDlg->setAllowCancel(true);
+
+ // I think FreeTTS only officialy supports English, but if anyone knows of someone
+ // whos built up a different language lexicon and has it working with FreeTTS gimme an email at ceruleanblaze@gmail.com
+ connect (m_freettsProc, SIGNAL(synthFinished()), this, SLOT(slotSynthFinished()));
+ m_freettsProc->synth(
+ testMsg,
+ tmpWaveFile,
+ realFilePath(m_widget->freettsPath->url()));
+
+ // Display progress dialog modally. Processing continues when plugin signals synthFinished,
+ // or if user clicks Cancel button.
+ m_progressDlg->exec();
+ disconnect (m_freettsProc, SIGNAL(synthFinished()), this, SLOT(slotSynthFinished()));
+ if (m_progressDlg->wasCancelled()) m_freettsProc->stopText();
+ delete m_progressDlg;
+ m_progressDlg = 0;
+}
+
+void FreeTTSConf::slotSynthFinished()
+{
+ // If user canceled, progress dialog is gone, so exit.
+ if (!m_progressDlg)
+ {
+ m_freettsProc->ackFinished();
+ return;
+ }
+ // Hide the Cancel button so user can't cancel in the middle of playback.
+ m_progressDlg->showCancelButton(false);
+ // Get new wavefile name.
+ m_waveFile = m_freettsProc->getFilename();
+ // Tell synth we're done.
+ m_freettsProc->ackFinished();
+ // Play the wave file (possibly adjusting its Speed).
+ // Player object deletes the wave file when done.
+ if (m_player) m_player->play(m_waveFile);
+ QFile::remove(m_waveFile);
+ m_waveFile = QString::null;
+ if (m_progressDlg) m_progressDlg->close();
+}
+
+void FreeTTSConf::slotSynthStopped()
+{
+ // Clean up after canceling test.
+ QString filename = m_freettsProc->getFilename();
+ if (!filename.isNull()) QFile::remove(filename);
+}
+
+#include "freettsconf.moc"
diff --git a/kttsd/plugins/freetts/freettsconf.h b/kttsd/plugins/freetts/freettsconf.h
new file mode 100644
index 0000000..9ab3ae8
--- /dev/null
+++ b/kttsd/plugins/freetts/freettsconf.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+ Configuration widget and functions for FreeTTS (interactive) plug in
+ -------------------
+ Copyright : (C) 2004 Paul Giannaros
+ -------------------
+ Original author: Paul Giannaros <ceruleanblaze@gmail.com>
+ Current Maintainer: Paul Giannaros <ceruleanblaze@gmail.com>
+ ******************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; version 2 of the License. *
+ * *
+ ***************************************************************************/
+
+#ifndef _FREETTSCONF_H_
+#define _FREETTSCONF_H_
+
+#include <qstringlist.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+
+#include <pluginconf.h>
+
+#include "freettsconfigwidget.h"
+#include "freettsproc.h"
+
+class QStringList;
+class KProgressDialog;
+
+class FreeTTSConf : public PlugInConf {
+ Q_OBJECT
+
+ public:
+ /** Constructor */
+ FreeTTSConf( QWidget* parent = 0, const char* name = 0, const QStringList &args = QStringList());
+
+ /** Destructor */
+ ~FreeTTSConf();
+
+ /** This method is invoked whenever the module should read its
+ configuration (most of the times from a config file) and update the
+ user interface. This happens when the user clicks the "Reset" button in
+ the control center, to undo all of his changes and restore the currently
+ valid settings. NOTE that this is not called after the modules is loaded,
+ so you probably want to call this method in the constructor.*/
+ void load(KConfig *config, const QString &configGroup);
+
+ /** This function gets called when the user wants to save the settings in
+ the user interface, updating the config files or wherever the
+ configuration is stored. The method is called when the user clicks "Apply"
+ or "Ok". */
+ void save(KConfig *config, const QString &configGroup);
+
+ /** This function is called to set the settings in the module to sensible
+ default values. It gets called when hitting the "Default" button. The
+ default values should probably be the same as the ones the application
+ uses when started without a config file. */
+ void defaults();
+
+ /**
+ * This function informs the plugin of the desired language to be spoken
+ * by the plugin. The plugin should attempt to adapt itself to the
+ * specified language code, choosing sensible defaults if necessary.
+ * If the passed-in code is QString::null, no specific language has
+ * been chosen.
+ * @param lang The desired language code or Null if none.
+ *
+ * If the plugin is unable to support the desired language, that is OK.
+ * Language codes are given by ISO 639-1 and are in lowercase.
+ * The code may also include an ISO 3166 country code in uppercase
+ * separated from the language code by underscore (_). For
+ * example, en_GB. If your plugin supports the given language, but
+ * not the given country, treat it as though the country
+ * code were not specified, i.e., adapt to the given language.
+ */
+ void setDesiredLanguage(const QString &lang);
+
+ /**
+ * Return fully-specified talker code for the configured plugin. This code
+ * uniquely identifies the configured instance of the plugin and distinquishes
+ * one instance from another. If the plugin has not been fully configured,
+ * i.e., cannot yet synthesize, return QString::null.
+ * @return Fully-specified talker code.
+ */
+ QString getTalkerCode();
+
+ /**
+ * Function searches the $PATH for a file. If it exists, it returns the full path
+ * to that file. If not, then it returns an empty QString.
+ * @param name The name of the file to search for.
+ * @returns The full path to the file or an empty QString.
+ */
+
+ private slots:
+ void configChanged(bool t = true) {
+ emit changed(t);
+ };
+ void slotFreeTTSTest_clicked();
+ void slotSynthFinished();
+ void slotSynthStopped();
+
+ private:
+ /// Language code.
+ QString m_languageCode;
+
+ /// Configuration Widget.
+ FreeTTSConfWidget *m_widget;
+
+ /// FreeTTS synthesizer.
+ FreeTTSProc *m_freettsProc;
+
+ /// Synthesized wave file name.
+ QString m_waveFile;
+
+ /// Progress dialog.
+ KProgressDialog* m_progressDlg;
+};
+#endif
diff --git a/kttsd/plugins/freetts/freettsconfigwidget.ui b/kttsd/plugins/freetts/freettsconfigwidget.ui
new file mode 100644
index 0000000..1d95751
--- /dev/null
+++ b/kttsd/plugins/freetts/freettsconfigwidget.ui
@@ -0,0 +1,200 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>FreeTTSConfWidget</class>
+<author>Gary Cramblitt &lt;garycramblitt@comcast.net&gt;</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>FreeTTSConfWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>576</width>
+ <height>134</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>FreeTTS Config UI</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>freettsConfigurationBox</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>GroupBoxPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="title">
+ <string>FreeTTS Interactive Configuration</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>voicesPathBox</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>freettsPathLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;FreeTTS jar file:</string>
+ </property>
+ <property name="textFormat">
+ <enum>AutoText</enum>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>freettsPath</cstring>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>freettsPath</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>selectVoiceBox</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="3" column="0">
+ <property name="name">
+ <cstring>layout10</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>410</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>freettsTest</cstring>
+ </property>
+ <property name="text">
+ <string>Test</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<includes>
+ <include location="global" impldecl="in declaration">kurlrequester.h</include>
+ <include location="global" impldecl="in implementation">kurlrequester.h</include>
+</includes>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kttsd/plugins/freetts/freettsplugin.cpp b/kttsd/plugins/freetts/freettsplugin.cpp
new file mode 100644
index 0000000..c8a75df
--- /dev/null
+++ b/kttsd/plugins/freetts/freettsplugin.cpp
@@ -0,0 +1,26 @@
+/****************************************************************************
+ Factory generation for the FreeTTS plugin so it can actually be used
+ as such.
+ -------------------
+ Copyright : (C) 2004 Paul Giannaros
+ -------------------
+ Original author: Paul Giannaros <ceruleanblaze@gmail.com>
+ Current Maintainer: Paul Giannaros <ceruleanblaze@gmail.com>
+ ******************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; version 2 of the License. *
+ * *
+ ***************************************************************************/
+
+#include <kgenericfactory.h>
+
+#include "freettsconf.h"
+#include "freettsproc.h"
+
+typedef K_TYPELIST_2( FreeTTSProc, FreeTTSConf ) FreeTTS;
+K_EXPORT_COMPONENT_FACTORY( libkttsd_freettsplugin, KGenericFactory<FreeTTS>("kttsd_freetts"))
+
diff --git a/kttsd/plugins/freetts/freettsproc.cpp b/kttsd/plugins/freetts/freettsproc.cpp
new file mode 100644
index 0000000..829fee9
--- /dev/null
+++ b/kttsd/plugins/freetts/freettsproc.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+ Main speaking functions for the FreeTTS Plug in
+ -------------------
+ Copyright : (C) 2004 Paul Giannaros
+ -------------------
+ Original author: Paul Giannaros <ceruleanblaze@gmail.com>
+ Current Maintainer: Paul Giannaros <ceruleanblaze@gmail.com>
+ ******************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; version 2 of the License. *
+ * *
+ ***************************************************************************/
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qfileinfo.h>
+
+#include <kdebug.h>
+#include <kconfig.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
+
+#include "freettsproc.h"
+
+/** Constructor */
+FreeTTSProc::FreeTTSProc( QObject* parent, const char* name, const QStringList& /*args*/) :
+ PlugInProc( parent, name ) {
+ kdDebug() << "Running: FreeTTSProc::FreeTTSProc" << endl;
+ m_state = psIdle;
+ m_waitingStop = false;
+ m_freettsProc = 0;
+}
+
+/** Desctructor */
+FreeTTSProc::~FreeTTSProc() {
+ kdDebug() << "Running: FreeTTSProc::~FreeTTSProc" << endl;
+ if (m_freettsProc) {
+ stopText();
+ delete m_freettsProc;
+ }
+}
+
+/** Initializate the speech */
+bool FreeTTSProc::init(KConfig *config, const QString &configGroup) {
+ kdDebug() << "Running: FreeTTSProc::init()" << endl;
+ kdDebug() << "Initializing plug in: FreeTTS" << endl;
+ config->setGroup(configGroup);
+ m_freettsJarPath = config->readEntry("FreeTTSJarPath", "freetts.jar");
+ kdDebug() << "FreeTTSProc::init: path to freetts.jar: " << m_freettsJarPath << endl;
+ return true;
+}
+
+/**
+ * Say a text. Synthesize and audibilize it.
+ * @param text The text to be spoken.
+ *
+ * If the plugin supports asynchronous operation, it should return immediately.
+ */
+void FreeTTSProc::sayText(const QString &text) {
+ synth(text, QString::null, m_freettsJarPath);
+}
+
+/**
+ * Synthesize text into an audio file, but do not send to the audio device.
+ * @param text The text to be synthesized.
+ * @param suggestedFilename Full pathname of file to create. The plugin
+ * may ignore this parameter and choose its own
+ * filename. KTTSD will query the generated
+ * filename using getFilename().
+ *
+ * If the plugin supports asynchronous operation, it should return immediately.
+ */
+void FreeTTSProc::synthText(const QString& text, const QString& suggestedFilename) {
+ kdDebug() << "Running: FreeTTSProc::synthText" << endl;
+ synth(text, suggestedFilename, m_freettsJarPath);
+}
+
+// A little helper function because KDE 3.2 kdDebug() does not support QValueList<QCString>.
+QStringList argsToQStringList(const QValueList<QCString> list)
+{
+ QStringList newList;
+ QValueList<QCString>::ConstIterator it = list.begin();
+ for ( ; it != list.end(); ++it ) newList.append(*it);
+ return newList;
+}
+
+void FreeTTSProc::synth(
+ const QString &text,
+ const QString &synthFilename,
+ const QString& freettsJarPath) {
+
+ kdDebug() << "Running: FreeTTSProc::synth" << endl;
+
+ if (m_freettsProc) {
+ if (m_freettsProc->isRunning()) m_freettsProc->kill();
+ delete m_freettsProc;
+ m_freettsProc = 0;
+
+ }
+
+ m_freettsProc = new KProcess;
+ connect(m_freettsProc, SIGNAL(processExited(KProcess*)),
+ this, SLOT(slotProcessExited(KProcess*)));
+ connect(m_freettsProc, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotReceivedStdout(KProcess*, char*, int)));
+ connect(m_freettsProc, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedStderr(KProcess*, char*, int)));
+ connect(m_freettsProc, SIGNAL(wroteStdin(KProcess*)),
+ this, SLOT(slotWroteStdin(KProcess* )));
+ if (synthFilename.isNull())
+ m_state = psSaying;
+ else
+ m_state = psSynthing;
+
+
+ QString saidText = text;
+ saidText += "\n";
+
+ /// As freetts.jar doesn't seem to like being called from an absolute path,
+ /// we need to strip off the path to freetts.jar and pass it to
+ /// KProcess::setWorkingDirectory()
+ /// We could just strip off 11 characters from the end of the path to freetts.jar, but thats
+ /// not exactly very portable...
+ QString filename = QFileInfo(freettsJarPath).baseName().append(QString(".").append(QFileInfo(freettsJarPath).extension()));
+ QString freettsJarDir = freettsJarPath.left((freettsJarPath.length() - filename.length()) - 1);
+
+ m_freettsProc->setWorkingDirectory(freettsJarDir);
+ kdDebug() << "FreeTTSProc::synthText: moved to directory '" << freettsJarDir << "'" << endl;
+ kdDebug() << "FreeTTSProc::synthText: Running file: '" << filename << "'" << endl;
+ *m_freettsProc << "java" << "-jar" << filename;
+
+ /// Dump audio into synthFilename
+
+ if (!synthFilename.isNull()) *m_freettsProc << "-dumpAudio" << synthFilename;
+
+ m_synthFilename = synthFilename;
+
+ kdDebug() << "FreeTTSProc::synth: Synthing text: '" << saidText << "' using FreeTTS plug in" << endl;
+ if (!m_freettsProc->start(KProcess::NotifyOnExit, KProcess::All)) {
+ kdDebug() << "FreeTTSProc::synth: Error starting FreeTTS process. Is freetts.jar in the PATH?" << endl;
+ m_state = psIdle;
+ kdDebug() << "KProcess args: " << argsToQStringList(m_freettsProc->args()) << endl;
+ return;
+ }
+ kdDebug()<< "FreeTTSProc:synth: FreeTTS initialized" << endl;
+ m_freettsProc->writeStdin(saidText.latin1(), saidText.length());
+}
+
+/**
+ * Returning the filename of the synth'd text
+ * @returns The filename of the last synth'd text
+ */
+QString FreeTTSProc::getFilename() {
+ kdDebug() << "FreeTTSProc::getFilename: returning " << m_synthFilename << endl;
+ return m_synthFilename;
+}
+
+/**
+ * Stop current operation (saying or synthesizing text).
+ * Important: This function may be called from a thread different from the
+ * one that called sayText or synthText.
+ * If the plugin cannot stop an in-progress @ref sayText or
+ * @ref synthText operation, it must not block waiting for it to complete.
+ * Instead, return immediately.
+ *
+ * If a plugin returns before the operation has actually been stopped,
+ * the plugin must emit the @ref stopped signal when the operation has
+ * actually stopped.
+ *
+ * The plugin should change to the psIdle state after stopping the
+ * operation.
+ */
+void FreeTTSProc::stopText() {
+ kdDebug() << "FreeTTSProc::stopText:: Running" << endl;
+ if (m_freettsProc) {
+ if (m_freettsProc->isRunning()) {
+ kdDebug() << "FreeTTSProc::stopText: killing FreeTTS." << endl;
+ m_waitingStop = true;
+ m_freettsProc->kill();
+ }
+ else m_state = psIdle;
+ }
+ else m_state = psIdle;
+ kdDebug() << "FreeTTSProc::stopText: FreeTTS stopped." << endl;
+}
+
+void FreeTTSProc::slotProcessExited(KProcess*) {
+ kdDebug() << "FreeTTSProc:slotProcessExited: FreeTTS process has exited." << endl;
+ pluginState prevState = m_state;
+ if (m_waitingStop) {
+ m_waitingStop = false;
+ m_state = psIdle;
+ emit stopped();
+ }
+ else {
+ m_state = psFinished;
+ if (prevState == psSaying)
+ emit sayFinished();
+ else if (prevState == psSynthing)
+ emit synthFinished();
+ }
+}
+
+void FreeTTSProc::slotReceivedStdout(KProcess*, char* buffer, int buflen) {
+ QString buf = QString::fromLatin1(buffer, buflen);
+ kdDebug() << "FreeTTSProc::slotReceivedStdout: Received output from FreeTTS: " << buf << endl;
+}
+
+void FreeTTSProc::slotReceivedStderr(KProcess*, char* buffer, int buflen) {
+ QString buf = QString::fromLatin1(buffer, buflen);
+ kdDebug() << "FreeTTSProc::slotReceivedStderr: Received error from FreeTTS: " << buf << endl;
+}
+
+void FreeTTSProc::slotWroteStdin(KProcess*) {
+ kdDebug() << "FreeTTSProc::slotWroteStdin: closing Stdin" << endl;
+ m_freettsProc->closeStdin();
+}
+
+/**
+ * Return the current state of the plugin.
+ * This function only makes sense in asynchronous mode.
+ * @return The pluginState of the plugin.
+ *
+ * @see pluginState
+ */
+pluginState FreeTTSProc::getState() {
+ return m_state;
+}
+
+/**
+ * Acknowledges a finished state and resets the plugin state to psIdle.
+ *
+ * If the plugin is not in state psFinished, nothing happens.
+ * The plugin may use this call to do any post-processing cleanup,
+ * for example, blanking the stored filename (but do not delete the file).
+ * Calling program should call getFilename prior to ackFinished.
+ */
+void FreeTTSProc::ackFinished() {
+ if (m_state == psFinished) {
+ m_state = psIdle;
+ m_synthFilename = QString::null;
+ }
+}
+
+/**
+ * Returns True if the plugin supports asynchronous processing,
+ * i.e., returns immediately from sayText or synthText.
+ * @return True if this plugin supports asynchronous processing.
+ *
+ * If the plugin returns True, it must also implement @ref getState .
+ * It must also emit @ref sayFinished or @ref synthFinished signals when
+ * saying or synthesis is completed.
+ */
+bool FreeTTSProc::supportsAsync() {
+// return true;
+ return true;
+}
+
+/**
+ * Returns True if the plugIn supports synthText method,
+ * i.e., is able to synthesize text to a sound file without
+ * audibilizing the text.
+ * @return True if this plugin supports synthText method.
+ */
+bool FreeTTSProc::supportsSynth() {
+// return true;
+ return true;
+}
+
+
+#include "freettsproc.moc"
diff --git a/kttsd/plugins/freetts/freettsproc.h b/kttsd/plugins/freetts/freettsproc.h
new file mode 100644
index 0000000..b2bb631
--- /dev/null
+++ b/kttsd/plugins/freetts/freettsproc.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+ Main speaking functions for the FreeTTS Plug in
+ -------------------
+ Copyright : (C) 2004 Paul Giannaros
+ -------------------
+ Original author: Paul Giannaros <ceruleanblaze@gmail.com>
+ Current Maintainer: Paul Giannaros <ceruleanblaze@gmail.com>
+ ******************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; version 2 of the License. *
+ * *
+ ***************************************************************************/
+
+#ifndef _FREETTSPROC_H_
+#define _FREETTSPROC_H_
+
+
+#include <qstringlist.h>
+#include <qmutex.h>
+
+#include <pluginproc.h>
+
+class KProcess;
+
+class FreeTTSProc : public PlugInProc{
+ Q_OBJECT
+
+public:
+ /**
+ * Constructor
+ */
+ FreeTTSProc( QObject* parent = 0, const char* name = 0, const QStringList &args = QStringList());
+
+ /**
+ * Destructor
+ */
+ virtual ~FreeTTSProc();
+
+ /**
+ * Initializate the speech engine.
+ * @param config Settings object.
+ * @param configGroup Settings group.
+ */
+ virtual bool init(KConfig *config, const QString &configGroup);
+
+ /**
+ * Say a text string.
+ * @param text The text to speak.
+ */
+ virtual void sayText(const QString &text);
+
+ /**
+ * Synthesize text into an audio file, but do not send to the audio device.
+ * @param text The text to be synthesized.
+ * @param suggestedFilename Full pathname of file to create. The plugin
+ * may ignore this parameter and choose its own
+ * filename. KTTSD will query the generated
+ * filename using getFilename().
+ *
+ * If the plugin supports asynchronous operation, it should return immediately.
+ */
+ virtual void synthText(const QString& text, const QString& suggestedFilename);
+
+ /**
+ * Get the generated audio filename from synthText.
+ * @return Name of the audio file the plugin generated.
+ * Null if no such file.
+ *
+ * The plugin must not re-use the filename.
+ */
+ virtual QString getFilename();
+
+ /**
+ * Stop current operation (saying or synthesizing text).
+ * Important: This function may be called from a thread different from the
+ * one that called sayText or synthText.
+ * If the plugin cannot stop an in-progress @ref sayText or
+ * @ref synthText operation, it must not block waiting for it to complete.
+ * Instead, return immediately.
+ *
+ * If a plugin returns before the operation has actually been stopped,
+ * the plugin must emit the @ref stopped signal when the operation has
+ * actually stopped.
+ *
+ * The plugin should change to the psIdle state after stopping the
+ * operation.
+ */
+ virtual void stopText();
+
+ /**
+ * Return the current state of the plugin.
+ * This function only makes sense in asynchronous mode.
+ * @return The pluginState of the plugin.
+ *
+ * @see pluginState
+ */
+ virtual pluginState getState();
+
+ /**
+ * Acknowledges a finished state and resets the plugin state to psIdle.
+ *
+ * If the plugin is not in state psFinished, nothing happens.
+ * The plugin may use this call to do any post-processing cleanup,
+ * for example, blanking the stored filename (but do not delete the file).
+ * Calling program should call getFilename prior to ackFinished.
+ */
+ virtual void ackFinished();
+
+ /**
+ * Returns True if the plugin supports asynchronous processing,
+ * i.e., returns immediately from sayText or synthText.
+ * @return True if this plugin supports asynchronous processing.
+ *
+ * If the plugin returns True, it must also implement @ref getState .
+ * It must also emit @ref sayFinished or @ref synthFinished signals when
+ * saying or synthesis is completed.
+ */
+ virtual bool supportsAsync();
+
+ /**
+ * Returns True if the plugin supports synthText method,
+ * i.e., is able to synthesize text to a sound file without
+ * audibilizing the text.
+ * @return True if this plugin supports synthText method.
+ */
+ virtual bool supportsSynth();
+
+ /**
+ * Say or Synthesize text.
+ * @param text The text to be synthesized.
+ * @param synthFilename If not Null, synthesize only to this filename, otherwise
+ * synthesize and audibilize the text.
+ * @param freettsJarPath Path to the freetts jar file.
+ */
+ void synth(
+ const QString &text,
+ const QString &synthFilename,
+ const QString &freettsJarPath);
+
+private slots:
+ void slotProcessExited(KProcess* proc);
+ void slotReceivedStdout(KProcess* proc, char* buffer, int buflen);
+ void slotReceivedStderr(KProcess* proc, char* buffer, int buflen);
+ void slotWroteStdin(KProcess* proc);
+
+private:
+
+ /**
+ * Path to FreeTTS jar file (from config).
+ */
+ QString m_freettsJarPath;
+
+ /**
+ * FreeTTS process
+ */
+ KProcess* m_freettsProc;
+
+ /**
+ * Synthesis filename.
+ */
+ QString m_synthFilename;
+
+ /**
+ * Plugin state.
+ */
+ pluginState m_state;
+
+ /**
+ * True when stopText has been called. Used to force transition to psIdle when
+ * FreeTTS exits.
+ */
+ bool m_waitingStop;
+
+};
+
+#endif // _FREETTSPROC_H_
diff --git a/kttsd/plugins/freetts/kttsd_freettsplugin.desktop b/kttsd/plugins/freetts/kttsd_freettsplugin.desktop
new file mode 100644
index 0000000..cdfab63
--- /dev/null
+++ b/kttsd/plugins/freetts/kttsd_freettsplugin.desktop
@@ -0,0 +1,51 @@
+[Desktop Entry]
+Name=FreeTTS
+Name[tr]=Freetts
+Name[vi]=Văn bản sang Tiếng nói Tự do
+Comment=FreeTTS speech synthesizer
+Comment[bg]=Синтезатор на глас FreeTTS
+Comment[ca]=Sintetitzador de veu FreeTTS
+Comment[cs]=Hlasový syntetizér FreeTTS
+Comment[da]=FreeTTS tale-synthesizer
+Comment[de]=FreeTTS Sprachsynthesizer
+Comment[el]=Συνθέτης ομιλίας FreeTTS
+Comment[es]=Sintetizador de texto a voz FreeTTS
+Comment[et]=Kõnesüntesaator FreeTTS
+Comment[eu]=FreeTTS hizketa-sintetizadorea
+Comment[fa]=ترکیب‌دهندۀ گفتار FreeTTS
+Comment[fi]=FreeTTS puhesyntetisaattori
+Comment[fr]=Synthèse vocale FreeTTS
+Comment[ga]=Sintéiseoir cainte FreeTTS
+Comment[gl]=Sintetizador de voces FreeTTS
+Comment[hu]=FreeTTS beszédszintetizátor
+Comment[is]=FreeTTS talgerfill
+Comment[it]=Sintetizzatore vocale FreeTTS
+Comment[ja]=FreeTTS スピーチシンセサイザ
+Comment[ka]=FreeTTS ხმის სინთეზატორი
+Comment[km]=កម្មវិធី​សង្គ្រោះ​ការនិយាយ FreeTTS
+Comment[mk]=FreeTTS синтетизатор на говор
+Comment[ms]=Pensintesis tutur FreeTTS
+Comment[nb]=FreeTTS talesyntetisering
+Comment[nds]=Blicksnuut FreeTTS
+Comment[ne]=FreeTTS संवाद सिन्थेसाइजर
+Comment[nl]=FreeTTS spraaksynthesizer
+Comment[pa]=FreeTTS ਬੋਲੀ ਸੰਸਲੇਸ਼ਕ
+Comment[pl]=Syntezator mowy FreeTTS
+Comment[pt]=O sintetizador de fala FreeTTS
+Comment[pt_BR]=Sintetizador de fala FreeTTS
+Comment[ru]=Синтезатор речи FreeTTS
+Comment[sk]=Syntetizátor reči FreeTTS
+Comment[sl]=Sintetizator govora FreeTTS
+Comment[sr]=Синтетизатор говора FreeTTS
+Comment[sr@Latn]=Sintetizator govora FreeTTS
+Comment[sv]=FreeTTS talsyntes
+Comment[ta]=FreeTTS பேச்சு கூட்டிணைப்பான்
+Comment[tg]=Таҳлилгари овози FreeTTS
+Comment[tr]=FreeTTS konuşma bireştirici
+Comment[uk]=Синтезатор мовлення FreeTTS
+Comment[vi]=Trình tổng hợp tiếng nói Tự do
+Comment[zh_TW]=FreeTTS 語音合成器
+Type=Service
+ServiceTypes=KTTSD/SynthPlugin
+X-KDE-Library=libkttsd_freettsplugin
+X-KDE-Languages=en,en_US,en_GB