summaryrefslogtreecommitdiffstats
path: root/kttsd/plugins/epos
diff options
context:
space:
mode:
Diffstat (limited to 'kttsd/plugins/epos')
-rw-r--r--kttsd/plugins/epos/Makefile.am20
-rw-r--r--kttsd/plugins/epos/README3
-rw-r--r--kttsd/plugins/epos/configure.in.bot15
-rw-r--r--kttsd/plugins/epos/configure.in.in22
-rw-r--r--kttsd/plugins/epos/eposconf.cpp319
-rw-r--r--kttsd/plugins/epos/eposconf.h141
-rw-r--r--kttsd/plugins/epos/eposconfwidget.ui610
-rw-r--r--kttsd/plugins/epos/eposplugin.cpp31
-rw-r--r--kttsd/plugins/epos/eposproc.cpp389
-rw-r--r--kttsd/plugins/epos/eposproc.h241
-rw-r--r--kttsd/plugins/epos/kttsd_eposplugin.desktop87
11 files changed, 1878 insertions, 0 deletions
diff --git a/kttsd/plugins/epos/Makefile.am b/kttsd/plugins/epos/Makefile.am
new file mode 100644
index 0000000..8f40ca7
--- /dev/null
+++ b/kttsd/plugins/epos/Makefile.am
@@ -0,0 +1,20 @@
+INCLUDES = \
+ -I$(top_srcdir)/kttsd/libkttsd -I$(top_builddir)/kttsd/libkttsd \
+ $(all_includes)
+
+METASOURCES = AUTO
+
+kde_module_LTLIBRARIES = libkttsd_eposplugin.la
+
+libkttsd_eposplugin_la_SOURCES = \
+ eposconfwidget.ui \
+ eposconf.cpp \
+ eposproc.cpp \
+ eposplugin.cpp
+libkttsd_eposplugin_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries)
+libkttsd_eposplugin_la_LIBADD = $(top_builddir)/kttsd/libkttsd/libkttsd.la
+
+services_DATA = kttsd_eposplugin.desktop
+servicesdir = $(kde_servicesdir)
+
+noinst_HEADERS = eposproc.h eposconf.h eposconfwidget.h
diff --git a/kttsd/plugins/epos/README b/kttsd/plugins/epos/README
new file mode 100644
index 0000000..2f61a9c
--- /dev/null
+++ b/kttsd/plugins/epos/README
@@ -0,0 +1,3 @@
+This is the directory containing the Epos plug in.
+This plugin is developed and maintained by Gary Cramblitt.
+<garycramblitt@comcast.net>
diff --git a/kttsd/plugins/epos/configure.in.bot b/kttsd/plugins/epos/configure.in.bot
new file mode 100644
index 0000000..59f4fdc
--- /dev/null
+++ b/kttsd/plugins/epos/configure.in.bot
@@ -0,0 +1,15 @@
+if test "x$epos_bindir" = "xno"; then
+ if test "$compile_epos_plugin" = "yes"; then
+ echo ""
+ echo "======================================================="
+ echo "The Epos program does not appear to be"
+ echo "installed on this system. The epos plugin will"
+ echo "be built, but you need to install epos before you"
+ echo "can use it. You can get it at"
+ echo " http://epos.ure.cas.cz/"
+ echo "Debian users: apt-get install epos"
+ echo "======================================================"
+ all_tests=bad
+ fi
+fi
+
diff --git a/kttsd/plugins/epos/configure.in.in b/kttsd/plugins/epos/configure.in.in
new file mode 100644
index 0000000..5a0f655
--- /dev/null
+++ b/kttsd/plugins/epos/configure.in.in
@@ -0,0 +1,22 @@
+dnl =========================================
+dnl checks for Festival Lite (epos) Plug In
+dnl =========================================
+
+AC_ARG_ENABLE(kttsd-epos,
+ AC_HELP_STRING([--enable-kttsd-epos],
+ [build KTTSD Epos plugin [default=yes]]),
+ epos_plugin=$enableval,
+ epos_plugin=yes)
+
+compile_epos_plugin="yes"
+
+if test "x$epos_plugin" = "xno"; then
+ compile_epos_plugin="no"
+fi
+
+dnl Check for epos executable.
+dnl Note that epos plugin is always built, unless
+dnl user overrides on configure command line.
+AC_PATH_PROG(epos_bindir, "epos", "no")
+
+AM_CONDITIONAL(include_kttsd_epos, test "x$compile_epos_plugin" != "xno")
diff --git a/kttsd/plugins/epos/eposconf.cpp b/kttsd/plugins/epos/eposconf.cpp
new file mode 100644
index 0000000..063c9f9
--- /dev/null
+++ b/kttsd/plugins/epos/eposconf.cpp
@@ -0,0 +1,319 @@
+/***************************************************** vim:set ts=4 sw=4 sts=4:
+ Configuration widget and functions for Epos plug in
+ -------------------
+ Copyright:
+ (C) 2004 by Gary Cramblitt <garycramblitt@comcast.net>
+ -------------------
+ Original author: Gary Cramblitt <garycramblitt@comcast.net>
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ******************************************************************************/
+
+// C++ includes.
+#include <math.h>
+
+// Qt includes.
+#include <qfile.h>
+#include <qapplication.h>
+#include <qtextcodec.h>
+#include <qlayout.h>
+#include <qslider.h>
+
+// KDE includes.
+#include <kdialog.h>
+#include <ktempfile.h>
+#include <kstandarddirs.h>
+#include <kcombobox.h>
+#include <klocale.h>
+#include <knuminput.h>
+
+// KTTS includes.
+#include <testplayer.h>
+
+// Epos Plugin includes.
+#include "eposproc.h"
+#include "eposconf.h"
+#include "eposconf.moc"
+
+/** Constructor */
+EposConf::EposConf( QWidget* parent, const char* name, const QStringList& /*args*/) :
+ PlugInConf(parent, name)
+{
+ // kdDebug() << "EposConf::EposConf: Running" << endl;
+ m_eposProc = 0;
+ m_progressDlg = 0;
+
+ QVBoxLayout *layout = new QVBoxLayout(this, KDialog::marginHint(),
+ KDialog::spacingHint(), "EposConfigWidgetLayout");
+ layout->setAlignment (Qt::AlignTop);
+ m_widget = new EposConfWidget(this, "EposConfigWidget");
+ layout->addWidget(m_widget);
+
+ // Build codec list and fill combobox.
+ m_codecList = PlugInProc::buildCodecList();
+ m_widget->characterCodingBox->clear();
+ m_widget->characterCodingBox->insertStringList(m_codecList);
+
+ defaults();
+
+ connect(m_widget->eposServerPath, SIGNAL(textChanged(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->eposClientPath, SIGNAL(textChanged(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->timeBox, SIGNAL(valueChanged(int)),
+ this, SLOT(timeBox_valueChanged(int)));
+ connect(m_widget->frequencyBox, SIGNAL(valueChanged(int)),
+ this, SLOT(frequencyBox_valueChanged(int)));
+ connect(m_widget->timeSlider, SIGNAL(valueChanged(int)),
+ this, SLOT(timeSlider_valueChanged(int)));
+ connect(m_widget->frequencySlider, SIGNAL(valueChanged(int)),
+ this, SLOT(frequencySlider_valueChanged(int)));
+ connect(m_widget->timeBox, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ connect(m_widget->timeSlider, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ connect(m_widget->frequencyBox, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ connect(m_widget->frequencySlider, SIGNAL(valueChanged(int)), this, SLOT(configChanged()));
+ connect(m_widget->characterCodingBox, SIGNAL(activated(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->eposServerOptions, SIGNAL(textChanged(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->eposClientOptions, SIGNAL(textChanged(const QString&)),
+ this, SLOT(configChanged()));
+ connect(m_widget->eposTest, SIGNAL(clicked()),
+ this, SLOT(slotEposTest_clicked()));
+}
+
+/** Destructor */
+EposConf::~EposConf(){
+ // kdDebug() << "Running: EposConf::~EposConf()" << endl;
+ if (!m_waveFile.isNull()) QFile::remove(m_waveFile);
+ delete m_eposProc;
+ delete m_progressDlg;
+}
+
+void EposConf::load(KConfig *config, const QString &configGroup){
+ // kdDebug() << "EposConf::load: Running " << endl;
+
+ config->setGroup(configGroup);
+ m_widget->eposServerPath->setURL(config->readEntry("EposServerExePath", "eposd"));
+ m_widget->eposClientPath->setURL(config->readEntry("EposClientExePath", "say-epos"));
+ m_widget->eposServerOptions->setText(config->readEntry("EposServerOptions", ""));
+ m_widget->eposClientOptions->setText(config->readEntry("EposClientOptions", ""));
+ QString codecString = config->readEntry("Codec", "ISO 8859-2");
+ int codec = PlugInProc::codecNameToListIndex(codecString, m_codecList);
+ m_widget->timeBox->setValue(config->readNumEntry("time", 100));
+ m_widget->frequencyBox->setValue(config->readNumEntry("pitch", 100));
+ m_widget->characterCodingBox->setCurrentItem(codec);
+}
+
+/**
+* Converts a language code into the language setting passed to Epos synth.
+*/
+QString EposConf::languageCodeToEposLanguage(const QString &languageCode)
+{
+ QString eposLanguage;
+ if (languageCode.left(2) == "cs") eposLanguage = "czech";
+ if (languageCode.left(2) == "sk") eposLanguage = "slovak";
+ return eposLanguage;
+}
+
+void EposConf::save(KConfig *config, const QString &configGroup){
+ // kdDebug() << "EposConf::save: Running" << endl;
+
+ config->setGroup("Epos");
+ config->writeEntry("EposServerExePath",
+ realFilePath(m_widget->eposServerPath->url()));
+ config->writeEntry("EposClientExePath",
+ realFilePath(m_widget->eposClientPath->url()));
+ config->writeEntry("Language", languageCodeToEposLanguage(m_languageCode));
+ config->setGroup(configGroup);
+ config->writeEntry("EposServerExePath",
+ realFilePath(m_widget->eposServerPath->url()));
+ config->writeEntry("EposClientExePath",
+ realFilePath(m_widget->eposClientPath->url()));
+ config->writeEntry("EposServerOptions", m_widget->eposServerOptions->text());
+ config->writeEntry("EposClientOptions", m_widget->eposClientOptions->text());
+ config->writeEntry("time", m_widget->timeBox->value());
+ config->writeEntry("pitch", m_widget->frequencyBox->value());
+ int codec = m_widget->characterCodingBox->currentItem();
+ config->writeEntry("Codec", PlugInProc::codecIndexToCodecName(codec, m_codecList));
+}
+
+void EposConf::defaults(){
+ // kdDebug() << "EposConf::defaults: Running" << endl;
+ // Epos server command changed from epos to eposd. Epos client command changed from
+ // say to say-epos. These changes appeared around Epos v2.5.35. Try for these automatically.
+ QString exeName = "eposd";
+ if (realFilePath(exeName).isEmpty())
+ if (!realFilePath("epos").isEmpty())
+ exeName = "epos";
+ m_widget->eposServerPath->setURL(exeName);
+ exeName = "say-epos";
+ if (realFilePath(exeName).isEmpty())
+ if (!realFilePath("say").isEmpty())
+ exeName = "say";
+ m_widget->eposClientPath->setURL(exeName);
+ m_widget->eposServerOptions->setText("");
+ m_widget->eposClientOptions->setText("");
+ m_widget->timeBox->setValue(100);
+ timeBox_valueChanged(100);
+ m_widget->frequencyBox->setValue(100);
+ frequencyBox_valueChanged(100);
+ int codec = PlugInProc::codecNameToListIndex("ISO 8859-2", m_codecList);
+ m_widget->characterCodingBox->setCurrentItem(codec);
+}
+
+void EposConf::setDesiredLanguage(const QString &lang)
+{
+ m_languageCode = lang;
+}
+
+QString EposConf::getTalkerCode()
+{
+ QString eposServerExe = realFilePath(m_widget->eposServerPath->url());
+ QString eposClientExe = realFilePath(m_widget->eposClientPath->url());
+ if (!eposServerExe.isEmpty() && !eposClientExe.isEmpty())
+ {
+ if (!getLocation(eposServerExe).isEmpty() && !getLocation(eposClientExe).isEmpty())
+ {
+ QString rate = "medium";
+ if (m_widget->timeBox->value() < 75) rate = "slow";
+ if (m_widget->timeBox->value() > 125) rate = "fast";
+ 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(rate)
+ .arg("Epos TTS Synthesis System");
+ }
+ }
+ return QString::null;
+}
+
+void EposConf::slotEposTest_clicked()
+{
+ // kdDebug() << "EposConf::slotEposTest_clicked(): Running" << endl;
+ // If currently synthesizing, stop it.
+ if (m_eposProc)
+ m_eposProc->stopText();
+ else
+ {
+ m_eposProc = new EposProc();
+ connect (m_eposProc, SIGNAL(stopped()), this, SLOT(slotSynthStopped()));
+ }
+ // Create a temp file name for the wave file.
+ KTempFile tempFile (locateLocal("tmp", "eposplugin-"), ".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_epos_testdlg",
+ i18n("Testing"),
+ i18n("Testing."),
+ true);
+ m_progressDlg->progressBar()->hide();
+ m_progressDlg->setAllowCancel(true);
+
+ // TODO: Whenever server options change, the server must be restarted.
+ // TODO: Do codec names contain non-ASCII characters?
+ connect (m_eposProc, SIGNAL(synthFinished()), this, SLOT(slotSynthFinished()));
+ m_eposProc->synth(
+ testMsg,
+ tmpWaveFile,
+ realFilePath(m_widget->eposServerPath->url()),
+ realFilePath(m_widget->eposClientPath->url()),
+ m_widget->eposServerOptions->text(),
+ m_widget->eposClientOptions->text(),
+ PlugInProc::codecIndexToCodec(m_widget->characterCodingBox->currentItem(), m_codecList),
+ languageCodeToEposLanguage(m_languageCode),
+ m_widget->timeBox->value(),
+ m_widget->frequencyBox->value()
+ );
+
+ // Display progress dialog modally. Processing continues when plugin signals synthFinished,
+ // or if user clicks Cancel button.
+ m_progressDlg->exec();
+ disconnect (m_eposProc, SIGNAL(synthFinished()), this, SLOT(slotSynthFinished()));
+ if (m_progressDlg->wasCancelled()) m_eposProc->stopText();
+ delete m_progressDlg;
+ m_progressDlg = 0;
+}
+
+void EposConf::slotSynthFinished()
+{
+ // If user canceled, progress dialog is gone, so exit.
+ if (!m_progressDlg)
+ {
+ m_eposProc->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_eposProc->getFilename();
+ // Tell synth we're done.
+ m_eposProc->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 EposConf::slotSynthStopped()
+{
+ // Clean up after canceling test.
+ QString filename = m_eposProc->getFilename();
+ if (!filename.isNull()) QFile::remove(filename);
+}
+
+// Basically the slider values are logarithmic (0,...,1000) whereas percent
+// values are linear (50%,...,200%).
+//
+// slider = alpha * (log(percent)-log(50))
+// with alpha = 1000/(log(200)-log(50))
+
+int EposConf::percentToSlider(int percentValue) {
+ double alpha = 1000 / (log(200) - log(50));
+ return (int)floor (0.5 + alpha * (log(percentValue)-log(50)));
+}
+
+int EposConf::sliderToPercent(int sliderValue) {
+ double alpha = 1000 / (log(200) - log(50));
+ return (int)floor(0.5 + exp (sliderValue/alpha + log(50)));
+}
+
+void EposConf::timeBox_valueChanged(int percentValue) {
+ m_widget->timeSlider->setValue (percentToSlider (percentValue));
+}
+
+void EposConf::frequencyBox_valueChanged(int percentValue) {
+ m_widget->frequencySlider->setValue(percentToSlider(percentValue));
+}
+
+void EposConf::timeSlider_valueChanged(int sliderValue) {
+ m_widget->timeBox->setValue (sliderToPercent (sliderValue));
+}
+
+void EposConf::frequencySlider_valueChanged(int sliderValue) {
+ m_widget->frequencyBox->setValue(sliderToPercent(sliderValue));
+}
diff --git a/kttsd/plugins/epos/eposconf.h b/kttsd/plugins/epos/eposconf.h
new file mode 100644
index 0000000..5c3fbe3
--- /dev/null
+++ b/kttsd/plugins/epos/eposconf.h
@@ -0,0 +1,141 @@
+/***************************************************** vim:set ts=4 sw=4 sts=4:
+ Configuration widget and functions for Epos plug in
+ -------------------
+ Copyright:
+ (C) 2004 by Gary Cramblitt <garycramblitt@comcast.net>
+ -------------------
+ Original author: Gary Cramblitt <garycramblitt@comcast.net>
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ******************************************************************************/
+
+#ifndef _EPOSCONF_H_
+#define _EPOSCONF_H_
+
+// Qt includes.
+#include <qstring.h>
+
+// KDE includes.
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kprogress.h>
+
+// KTTS includes.
+#include <pluginconf.h>
+
+// Epos plugin includes.
+#include "eposconfwidget.h"
+
+class EposProc;
+class KProgressDialog;
+
+class EposConf : public PlugInConf {
+ Q_OBJECT
+
+ public:
+ /** Constructor */
+ EposConf( QWidget* parent = 0, const char* name = 0, const QStringList &args = QStringList());
+
+ /** Destructor */
+ ~EposConf();
+
+ /** 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();
+
+ private slots:
+ void configChanged(){
+ kdDebug() << "EposConf::configChanged: Running" << endl;
+ emit changed(true);
+ };
+ void slotEposTest_clicked();
+ void slotSynthFinished();
+ void slotSynthStopped();
+ void timeBox_valueChanged(int percentValue);
+ void frequencyBox_valueChanged(int percentValue);
+ void timeSlider_valueChanged(int sliderValue);
+ void frequencySlider_valueChanged(int sliderValue);
+
+ private:
+ /**
+ * Converts a language code into the language setting passed to Epos synth.
+ */
+ QString languageCodeToEposLanguage(const QString &languageCode);
+
+ int percentToSlider(int percentValue);
+ int sliderToPercent(int sliderValue);
+
+ // Language code.
+ QString m_languageCode;
+
+ // Configuration widget.
+ EposConfWidget* m_widget;
+
+ // Epos synthesizer.
+ EposProc* m_eposProc;
+ // Synthesized wave file name.
+ QString m_waveFile;
+ // Progress dialog.
+ KProgressDialog* m_progressDlg;
+ // List of displayed codec names.
+ QStringList m_codecList;
+};
+#endif // _EPOSCONF_H_
diff --git a/kttsd/plugins/epos/eposconfwidget.ui b/kttsd/plugins/epos/eposconfwidget.ui
new file mode 100644
index 0000000..23e47da
--- /dev/null
+++ b/kttsd/plugins/epos/eposconfwidget.ui
@@ -0,0 +1,610 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>EposConfWidget</class>
+<author>Gary Cramblitt</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>EposConfWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>535</width>
+ <height>381</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>Epos Config UI</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This is the configuration dialog for the Epos Czech and Slovak speech synthesizer.</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>eposConfigurationBox</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>E&amp;pos Configuration</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This is the configuration dialog for the Epos Czech and Slovak speech synthesizer.</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="2" column="0">
+ <property name="name">
+ <cstring>layout13</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>characterCodingLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Character &amp;encoding:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>characterCodingBox</cstring>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <property name="name">
+ <cstring>characterCodingBox</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Specifies which character encoding is used for passing the text.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout17</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout14</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>timeLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Speed:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>timeBox</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Sets the speed of speech. Slide the slider to the left to slow speech down; to the right to increase talking speed. Anything less than 75 percent is considered "slow", and anything greater than 125 percent is considered "fast".</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>frequencyLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Pitch:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>frequencyBox</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Sets the tone (frequency) of speech. Slide the slider to the left to lower the voice tone; to the right to increase tone. Anything less than 75 percent is considered "low", and anything greater than 125 percent is considered "high".</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout15</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>timeBox</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> %</string>
+ </property>
+ <property name="maxValue">
+ <number>200</number>
+ </property>
+ <property name="minValue">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Sets the speed of speech. Slide the slider to the left to slow speech down; to the right to increase talking speed. Anything less than 75 percent is considered "slow", and anything greater than 125 percent is considered "fast".</string>
+ </property>
+ </widget>
+ <widget class="KIntSpinBox">
+ <property name="name">
+ <cstring>frequencyBox</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> %</string>
+ </property>
+ <property name="maxValue">
+ <number>200</number>
+ </property>
+ <property name="minValue">
+ <number>50</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Sets the tone (frequency) of speech. Slide the slider to the left to lower the voice tone; to the right to increase tone. Anything less than 75 percent is considered "low", and anything greater than 125 percent is considered "high".</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout16</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>timeSlider</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="focusPolicy">
+ <enum>NoFocus</enum>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="lineStep">
+ <number>10</number>
+ </property>
+ <property name="pageStep">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>500</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Sets the speed of speech. Slide the slider to the left to slow speech down; to the right to increase talking speed. Anything less than 75 percent is considered "slow", and anything greater than 125 percent is considered "fast".</string>
+ </property>
+ </widget>
+ <widget class="QSlider">
+ <property name="name">
+ <cstring>frequencySlider</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="focusPolicy">
+ <enum>NoFocus</enum>
+ </property>
+ <property name="maxValue">
+ <number>1000</number>
+ </property>
+ <property name="lineStep">
+ <number>10</number>
+ </property>
+ <property name="pageStep">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>500</number>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Sets the tone (frequency) of speech. Slide the slider to the left to lower the voice tone; to the right to increase tone. Anything less than 75 percent is considered "low", and anything greater than 125 percent is considered "high".</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout13</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>eposServerPathLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Epos server executable path:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>festivalVoicesPath</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If the Epos server program will be found due to your PATH environment variable, simply enter "epos", otherwise enter the full path to the Epos server executable program.</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>eposClientPathLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Epos client executable path:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>festivalVoicesPath</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If the Epos client program will be found due to the PATH environment variable, simply enter "say" here. Otherwise, specify the full path to the Epos client program.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout12</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>eposServerPath</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="url" stdset="0">
+ <string>epos</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If the Epos server program will be found due to your PATH environment variable, simply enter "epos", otherwise enter the full path to the Epos server executable program.</string>
+ </property>
+ </widget>
+ <widget class="KURLRequester">
+ <property name="name">
+ <cstring>eposClientPath</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="url" stdset="0">
+ <string>say</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>If the Epos client program will be found due to the PATH environment variable, simply enter "say" here. Otherwise, specify the full path to the Epos client program.</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox" row="3" column="0">
+ <property name="name">
+ <cstring>advancedGroupBox</cstring>
+ </property>
+ <property name="title">
+ <string>Additional Options (advanced)</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout14</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout13</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>eposServerOptions</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Optional. Enter any server command line options here. To see available options, enter "epos -h" in a terminal. Do not use "-o".</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>eposClientOptions</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Specify options to be passed to Epos client. To see available options, enter "say -h" in a terminal. Do not use "-o".</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout12</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>eposServerOptionsLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Epos server:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>festivalVoicesPath</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Optional. Enter any server command line options here. To see available options, enter "epos -h" in a terminal. Do not use "-o".</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>eposClientOptionsLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Epos client:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>festivalVoicesPath</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Specify options to be passed to Epos client. Do not use -o. To see available options, enter "say -h" in a terminal. Do not use "-o".</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="4" column="0">
+ <property name="name">
+ <cstring>layout5</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>eposTest</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Test</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>Click to test the configuration. If correct, you will hear a sentence spoken.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<tabstops>
+ <tabstop>eposServerPath</tabstop>
+ <tabstop>eposClientPath</tabstop>
+ <tabstop>characterCodingBox</tabstop>
+ <tabstop>eposTest</tabstop>
+</tabstops>
+<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>kcombobox.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>knuminput.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kttsd/plugins/epos/eposplugin.cpp b/kttsd/plugins/epos/eposplugin.cpp
new file mode 100644
index 0000000..9bc0bee
--- /dev/null
+++ b/kttsd/plugins/epos/eposplugin.cpp
@@ -0,0 +1,31 @@
+/***************************************************** vim:set ts=4 sw=4 sts=4:
+ Generating the factories so Epos can be used as plug in.
+ -------------------
+ Copyright:
+ (C) 2005 by Gary Cramblitt <garycramblitt@comcast.net>
+ -------------------
+ Original author: Gary Cramblitt <garycramblitt@comcast.net>
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ******************************************************************************/
+
+#include <kgenericfactory.h>
+
+#include "eposconf.h"
+#include "eposproc.h"
+
+typedef K_TYPELIST_2( EposProc, EposConf ) Epos;
+K_EXPORT_COMPONENT_FACTORY( libkttsd_eposplugin, KGenericFactory<Epos>("kttsd_epos") )
+
diff --git a/kttsd/plugins/epos/eposproc.cpp b/kttsd/plugins/epos/eposproc.cpp
new file mode 100644
index 0000000..35bc1d3
--- /dev/null
+++ b/kttsd/plugins/epos/eposproc.cpp
@@ -0,0 +1,389 @@
+/***************************************************** vim:set ts=4 sw=4 sts=4:
+ eposproc.cpp
+ Main speaking functions for the Epos Plug in
+ -------------------
+ Copyright:
+ (C) 2004 by Gary Cramblitt <garycramblitt@comcast.net>
+ -------------------
+ Original author: Gary Cramblitt <garycramblitt@comcast.net>
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ******************************************************************************/
+
+// C++ includes.
+#include <math.h>
+
+// Qt includes.
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qtextcodec.h>
+#include <qfile.h>
+
+// KDE includes.
+#include <kdebug.h>
+#include <kconfig.h>
+#include <ktempfile.h>
+#include <kstandarddirs.h>
+#include <kprocess.h>
+
+// Epos Plugin includes.
+#include "eposproc.h"
+#include "eposproc.moc"
+
+/** Constructor */
+EposProc::EposProc( QObject* parent, const char* name, const QStringList& ) :
+ PlugInProc( parent, name ){
+ kdDebug() << "EposProc::EposProc: Running" << endl;
+ m_state = psIdle;
+ m_waitingStop = false;
+ m_eposServerProc = 0;
+ m_eposProc = 0;
+}
+
+/** Destructor */
+EposProc::~EposProc(){
+ kdDebug() << "EposProc::~EposProc:: Running" << endl;
+ if (m_eposProc)
+ {
+ stopText();
+ delete m_eposProc;
+ }
+ delete m_eposServerProc;
+}
+
+/** Initialize the speech */
+bool EposProc::init(KConfig* config, const QString& configGroup)
+{
+ // kdDebug() << "EposProc::init: Running" << endl;
+ // kdDebug() << "Initializing plug in: Epos" << endl;
+ // Retrieve path to epos executable.
+ config->setGroup(configGroup);
+ m_eposServerExePath = config->readEntry("EposServerExePath", "epos");
+ m_eposClientExePath = config->readEntry("EposClientExePath", "say");
+ m_eposLanguage = config->readEntry("Language", QString::null);
+ m_time = config->readNumEntry("time", 100);
+ m_pitch = config->readNumEntry("pitch", 100);
+ m_eposServerOptions = config->readEntry("EposServerOptions", QString::null);
+ m_eposClientOptions = config->readEntry("EposClientOptions", QString::null);
+ kdDebug() << "EposProc::init: path to epos server: " << m_eposServerExePath << endl;
+ kdDebug() << "EposProc::init: path to epos client: " << m_eposClientExePath << endl;
+
+ QString codecString = config->readEntry("Codec", "Local");
+ m_codec = codecNameToCodec(codecString);
+ // Start the Epos server if not already started.
+ if (!m_eposServerProc)
+ {
+ m_eposServerProc = new KProcess;
+ *m_eposServerProc << m_eposServerExePath;
+ if (!m_eposServerOptions.isEmpty())
+ *m_eposServerProc << m_eposServerOptions;
+ connect(m_eposServerProc, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotReceivedStdout(KProcess*, char*, int)));
+ connect(m_eposServerProc, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedStderr(KProcess*, char*, int)));
+ m_eposServerProc->start(KProcess::DontCare, KProcess::AllOutput);
+ }
+
+ kdDebug() << "EposProc::init: Initialized with codec: " << codecString << 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 EposProc::sayText(const QString &text)
+{
+ synth(text, QString::null, m_eposServerExePath, m_eposClientExePath,
+ m_eposServerOptions, m_eposClientOptions,
+ m_codec, m_eposLanguage, m_time, m_pitch);
+}
+
+/**
+* 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 EposProc::synthText(const QString& text, const QString& suggestedFilename)
+{
+ synth(text, suggestedFilename, m_eposServerExePath, m_eposClientExePath,
+ m_eposServerOptions, m_eposClientOptions,
+ m_codec, m_eposLanguage, m_time, m_pitch);
+}
+
+/**
+* Say or Synthesize text.
+* @param text The text to be synthesized.
+* @param suggestedFilename If not Null, synthesize only to this filename, otherwise
+* synthesize and audibilize the text.
+* @param eposServerExePath Path to the Epos server executable.
+* @param eposClientExePath Path to the Epos client executable.
+* @param eposServerOptions Options passed to Epos server executable.
+* @param eposClientOptions Options passed to Epos client executable (don't include -o).
+* @param codec Codec for encoding of text.
+* @param eposLanguage Epos language setting. "czech", "slovak",
+* or null (default language).
+* @param time Speed percentage. 50 to 200. 200% = 2x normal.
+* @param pitch Pitch persentage. 50 to 200.
+*/
+void EposProc::synth(
+ const QString &text,
+ const QString &suggestedFilename,
+ const QString& eposServerExePath,
+ const QString& eposClientExePath,
+ const QString& eposServerOptions,
+ const QString& eposClientOptions,
+ QTextCodec *codec,
+ const QString& eposLanguage,
+ int time,
+ int pitch)
+{
+ // kdDebug() << "Running: EposProc::synth(const QString &text)" << endl;
+
+ if (m_eposProc)
+ {
+ if (m_eposProc->isRunning()) m_eposProc->kill();
+ delete m_eposProc;
+ m_eposProc = 0;
+ }
+ // Start the Epos server if not already started.
+ if (!m_eposServerProc)
+ {
+ m_eposServerProc = new KProcess;
+ *m_eposServerProc << eposServerExePath;
+ if (!eposServerOptions.isEmpty())
+ *m_eposServerProc << eposServerOptions;
+ connect(m_eposServerProc, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotReceivedStdout(KProcess*, char*, int)));
+ connect(m_eposServerProc, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedStderr(KProcess*, char*, int)));
+ m_eposServerProc->start(KProcess::DontCare, KProcess::AllOutput);
+ kdDebug() << "EposProc:: Epos server process started" << endl;
+ }
+
+// // Encode the text.
+// // 1.a) encode the text
+// m_encText = QCString();
+// QTextStream ts (m_encText, IO_WriteOnly);
+// ts.setCodec(codec);
+// ts << text;
+// ts << endl; // Some synths need this, eg. flite.
+
+ if (codec)
+ m_encText = codec->fromUnicode(text);
+ else
+ m_encText = text.latin1(); // Should not happen, but just in case.
+
+ // kdDebug()<< "EposProc::synth: Creating Epos object" << endl;
+ m_eposProc = new KProcess;
+ m_eposProc->setUseShell(true);
+ QString languageCode;
+ if (eposLanguage == "czech")
+ languageCode == "cz";
+ else if (eposLanguage == "slovak")
+ languageCode == "sk";
+ if (!languageCode.isEmpty())
+ {
+ m_eposProc->setEnvironment("LANG", languageCode + "." + codec->mimeName());
+ m_eposProc->setEnvironment("LC_CTYPE", languageCode + "." + codec->mimeName());
+ }
+ *m_eposProc << eposClientExePath;
+ // Language.
+ if (!eposLanguage.isEmpty())
+ *m_eposProc << QString("--language=%1").arg(eposLanguage);
+ // Rate (speed).
+ // Map 50% to 200% onto 0 to 1000.
+ // slider = alpha * (log(percent)-log(50))
+ // with alpha = 1000/(log(200)-log(50))
+ double alpha = 1000 / (log(200) - log(50));
+ int slider = (int)floor (0.5 + alpha * (log(time)-log(50)));
+ // Center at 0.
+ slider = slider - 500;
+ // Map -500 to 500 onto 45 to -45 then shift to 130 to 40 (85 midpoint).
+ float stretchValue = (-float(slider) * 45.0 / 500.0) + 85.0;
+ QString timeMsg = QString("--init_t=%1").arg(stretchValue, 0, 'f', 3);
+ *m_eposProc << timeMsg;
+ // Pitch. Map 50% to 200% onto 50 to 200. easy.
+ QString pitchMsg = QString("--init_f=%1").arg(pitch);
+ *m_eposProc << pitchMsg;
+ // Output file.
+ if (!suggestedFilename.isEmpty())
+ *m_eposProc << "-o";
+ if (!eposClientOptions.isEmpty())
+ *m_eposProc << eposClientOptions;
+ *m_eposProc << "-"; // Read from StdIn.
+ if (!suggestedFilename.isEmpty())
+ *m_eposProc << " >" + suggestedFilename;
+ connect(m_eposProc, SIGNAL(processExited(KProcess*)),
+ this, SLOT(slotProcessExited(KProcess*)));
+ connect(m_eposProc, SIGNAL(receivedStdout(KProcess*, char*, int)),
+ this, SLOT(slotReceivedStdout(KProcess*, char*, int)));
+ connect(m_eposProc, SIGNAL(receivedStderr(KProcess*, char*, int)),
+ this, SLOT(slotReceivedStderr(KProcess*, char*, int)));
+ connect(m_eposProc, SIGNAL(wroteStdin(KProcess*)),
+ this, SLOT(slotWroteStdin(KProcess* )));
+ if (suggestedFilename.isEmpty())
+ m_state = psSaying;
+ else
+ m_state = psSynthing;
+
+ // Ok, let's rock.
+ m_synthFilename = suggestedFilename;
+ // kdDebug() << "EposProc::synth: Synthing text: '" << text << "' using Epos plug in" << endl;
+ if (!m_eposProc->start(KProcess::NotifyOnExit, KProcess::All))
+ {
+ kdDebug() << "EposProc::synth: Error starting Epos process. Is epos in the PATH?" << endl;
+ m_state = psIdle;
+ return;
+ }
+ // kdDebug() << "EposProc:synth: Epos initialized" << endl;
+ // kdDebug() << "EposProc::synth: m_encText.length() = " << m_encText.length() << " text.length() = "
+ // << text.length() << endl;
+ if (!m_eposProc->writeStdin(m_encText, m_encText.length()))
+ kdDebug() << "EposProc::synth: Error writing to Epos client StdIn." << endl;
+}
+
+/**
+* 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.
+*/
+QString EposProc::getFilename()
+{
+ kdDebug() << "EposProc::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 EposProc::stopText(){
+ kdDebug() << "EposProc::stopText:: Running" << endl;
+ if (m_eposProc)
+ {
+ if (m_eposProc->isRunning())
+ {
+ kdDebug() << "EposProc::stopText: killing Epos." << endl;
+ m_waitingStop = true;
+ m_eposProc->kill();
+ } else m_state = psIdle;
+ } else m_state = psIdle;
+ kdDebug() << "EposProc::stopText: Epos stopped." << endl;
+}
+
+void EposProc::slotProcessExited(KProcess*)
+{
+ // kdDebug() << "EposProc:slotProcessExited: Epos 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 EposProc::slotReceivedStdout(KProcess*, char* buffer, int buflen)
+{
+ QString buf = QString::fromLatin1(buffer, buflen);
+ kdDebug() << "EposProc::slotReceivedStdout: Received output from Epos: " << buf << endl;
+}
+
+void EposProc::slotReceivedStderr(KProcess*, char* buffer, int buflen)
+{
+ QString buf = QString::fromLatin1(buffer, buflen);
+ kdDebug() << "EposProc::slotReceivedStderr: Received error from Epos: " << buf << endl;
+}
+
+void EposProc::slotWroteStdin(KProcess*)
+{
+ // kdDebug() << "EposProc::slotWroteStdin: closing Stdin" << endl;
+ m_eposProc->closeStdin();
+ m_encText = QCString();
+}
+
+/**
+* Return the current state of the plugin.
+* This function only makes sense in asynchronous mode.
+* @return The pluginState of the plugin.
+*
+* @see pluginState
+*/
+pluginState EposProc::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 EposProc::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 EposProc::supportsAsync() { 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 EposProc::supportsSynth() { return true; }
diff --git a/kttsd/plugins/epos/eposproc.h b/kttsd/plugins/epos/eposproc.h
new file mode 100644
index 0000000..b2d1d90
--- /dev/null
+++ b/kttsd/plugins/epos/eposproc.h
@@ -0,0 +1,241 @@
+/***************************************************** vim:set ts=4 sw=4 sts=4:
+ eposproc.h
+ Main speaking functions for the Epos Plug in
+ -------------------
+ Copyright:
+ (C) 2004 by Gary Cramblitt <garycramblitt@comcast.net>
+ -------------------
+ Original author: Gary Cramblitt <garycramblitt@comcast.net>
+
+ 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ ******************************************************************************/
+
+#ifndef _EPOSPROC_H_
+#define _EPOSPROC_H_
+
+// Qt includes.
+#include <qstringlist.h>
+#include <qmutex.h>
+
+// KTTS includes.
+#include <pluginproc.h>
+
+class KProcess;
+class QTextCodec;
+
+class EposProc : public PlugInProc{
+ Q_OBJECT
+
+ public:
+ /**
+ * Constructor
+ */
+ EposProc( QObject* parent = 0, const char* name = 0, const QStringList &args = QStringList());
+
+ /**
+ * Destructor
+ */
+ virtual ~EposProc();
+
+ /**
+ * 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 suggestedFilename If not Null, synthesize only to this filename, otherwise
+ * synthesize and audibilize the text.
+ * @param eposServerExePath Path to the Epos server executable.
+ * @param eposClientExePath Path to the Epos client executable.
+ * @param eposServerOptions Options passed to Epos server executable.
+ * @param eposClientOptions Options passed to Epos client executable (don't include -o).
+ * @param codec Codec for encoding of text.
+ * @param eposLanguage Epos language setting. "czech", "slovak",
+ * or null (default language).
+ * @param time Speed percentage. 50 to 200. 200% = 2x normal.
+ * @param pitch Pitch persentage. 50 to 200.
+ */
+ void synth(
+ const QString &text,
+ const QString &suggestedFilename,
+ const QString& eposServerExePath,
+ const QString& eposClientExePath,
+ const QString& eposServerOptions,
+ const QString& eposClientOptions,
+ QTextCodec *codec,
+ const QString& eposLanguage,
+ int time,
+ int pitch);
+
+ 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 epos executables (from config).
+ */
+ QString m_eposServerExePath;
+ QString m_eposClientExePath;
+
+ /**
+ * User options passed to executables (from config).
+ */
+ QString m_eposServerOptions;
+ QString m_eposClientOptions;
+
+ /**
+ * Epos Server process.
+ */
+ KProcess* m_eposServerProc;
+
+ /**
+ * Epos Client process
+ */
+ KProcess* m_eposProc;
+
+ /**
+ * Epos language setting. "czech", "slovak", or Null (use default language).
+ */
+ QString m_eposLanguage;
+
+ /**
+ * Rate (speed) from config file.
+ */
+ int m_time;
+
+ /**
+ * Pitch from the config file.
+ */
+ int m_pitch;
+
+ /**
+ * Codec.
+ */
+ QTextCodec* m_codec;
+
+ /**
+ * Encoded buffer to be sent to Epos client.
+ */
+ QCString m_encText;
+
+ /**
+ * Synthesis filename.
+ */
+ QString m_synthFilename;
+
+ /**
+ * Plugin state.
+ */
+ pluginState m_state;
+
+ /**
+ * True when stopText has been called. Used to force transition to psIdle when
+ * Epos exits.
+ */
+ bool m_waitingStop;
+
+};
+
+#endif // _EPOSPROC_H_
diff --git a/kttsd/plugins/epos/kttsd_eposplugin.desktop b/kttsd/plugins/epos/kttsd_eposplugin.desktop
new file mode 100644
index 0000000..7673929
--- /dev/null
+++ b/kttsd/plugins/epos/kttsd_eposplugin.desktop
@@ -0,0 +1,87 @@
+[Desktop Entry]
+Name=Epos TTS Synthesis System
+Name[ca]=Sistema de síntesi Epos TTS
+Name[cs]=Epos TTS
+Name[da]=Epos TTS Synthesis-system
+Name[de]=Epos TTS-Synthese-System
+Name[el]=Σύστημα σύνθεσης Epos TTS
+Name[es]=Sistema de síntesis Epos TTS
+Name[et]=Kõnesünteesisüsteem Epos TTS
+Name[eu]=Epos TTS sintesi-sistema
+Name[fa]=سیستم ترکیب‌دهی Epos TTS
+Name[fi]=Epos TTS -syntetisoijasysteemi
+Name[fr]=Système de synthèse Epos TTS
+Name[ga]=Córas Sintéise TTS Epos
+Name[gl]=Sistema de Síntese de TTS Epos
+Name[hu]=Epos szövegfelolvasó motor
+Name[it]=Sistema di sintesi TTS Epos
+Name[ja]=Epos TTS シンセサイズシステム
+Name[ka]=Epos TTS სინთეზის სისტემა
+Name[km]=ប្រព័ន្ធ​សង្គ្រោះ Epos TTS
+Name[mk]=Epos TTS систем за синтеза
+Name[ms]=Sistem Sintesis Epos TTS
+Name[nb]=Epos TTT syntesesystem
+Name[nds]=Epos Blicksnuut
+Name[ne]=Epos TTS सिन्थेसिस प्रणाली
+Name[nl]=Epos TTS Synthesis-systeem
+Name[pa]=Epos TTS ਸੰਸਲੇਸ਼ਣ ਸਿਸਟਮ
+Name[pl]=System syntezy mowy Epos
+Name[pt]=Sistema de Síntese Epos TTS
+Name[pt_BR]=Sistema de Sintetizador de Fala Epos
+Name[sk]=Systém Epos TTS Synthesis
+Name[sl]=Sistem sinteze besedila v govor Epos
+Name[sr]=Систем за синтезу Epos TTS
+Name[sr@Latn]=Sistem za sintezu Epos TTS
+Name[sv]=Epos TTS syntessystem
+Name[ta]=Epos TTS கூட்டிணைப்பு அமைப்பு
+Name[tg]=Системаи Синтезиси Epos TTS
+Name[tr]=Epos TTS Sentezleme Sistemi
+Name[vi]=Hệ thống Tổng hợp Văn bản sang Tiếng nói Epos
+Name[zh_TW]=Epos TTS 合成系統
+Comment=Epos TTS speech synthesizer
+Comment[bg]=Синтезатор на глас Epos TTS
+Comment[ca]=Sintetitzador de veu Epos TTS
+Comment[cs]=Hlasový syntetizér Epos TTS
+Comment[da]=Epos TTS tale-synthesizer
+Comment[de]=Epos TTS-Sprachsynthesizer
+Comment[el]=Συνθέτης ομιλίας Epos TTS
+Comment[es]=Sintetizador de texto a voz Epos TTS
+Comment[et]=Kõnesüntesaator Epos TTS
+Comment[eu]=Epos TTS hizketa-sintetizadorea
+Comment[fa]=ترکیب‌دهندۀ گفتار Epos TTS
+Comment[fi]=Epos TTS -puhesyntetisaattori
+Comment[fr]=Synthèse vocale Epos TTS
+Comment[ga]=Sintéiseoir cainte TTS Epos
+Comment[gl]=Sintetizador de fala TTS Epos
+Comment[hu]=Epos TTS beszédszintetizátor
+Comment[is]=Epos TTS talgerfill
+Comment[it]=Sintetizzatore vocale TTS Epos
+Comment[ja]=Epos TTS スピーチシンセサイザ
+Comment[ka]=Epos TTS სიტყვის სინთეზატორი
+Comment[km]=កម្មវិធី​សង្គ្រោះ​ការនិយាយ Epos TTS
+Comment[mk]=Epos TTS синтетизатор на говор
+Comment[ms]=Pensintesis tutur Epos TTS
+Comment[nb]=Epos TTT talesyntetisering
+Comment[nds]=Blicksnuut vun Epos
+Comment[ne]=Epos TTS संवाद सिन्थेसाइजर
+Comment[nl]=Epos TTS spraaksynthesizer
+Comment[pa]=Epos TTS ਬੋਲੀ ਸੰਸਲੇਸ਼ਣ
+Comment[pl]=Syntezator mowy Epos
+Comment[pt]=O sintetizador de fala Epos TTS
+Comment[pt_BR]=Sistema de Sintetizador de Fala Epos
+Comment[ru]=Синтезатор речи Epos TTS
+Comment[sk]=Syntetizátor reči Epos TTS
+Comment[sl]=Sintetizator besedila v govor Epos
+Comment[sr]=Синтетизатор говора Epos TTS
+Comment[sr@Latn]=Sintetizator govora Epos TTS
+Comment[sv]=Epos TTS talsyntes
+Comment[ta]=Epos TTS பேச்சு கூட்டிணைப்பான்
+Comment[tg]=Таҳлилгари овози Epos TTS
+Comment[tr]=Epos TTS konuşma sentezleyicisi
+Comment[uk]=Синтезатор мовлення Epos TTS
+Comment[vi]=Trình tổng hợp Văn bản sang Tiếng nói Epos
+Comment[zh_TW]=Epos TTS 語音合成器
+Type=Service
+ServiceTypes=KTTSD/SynthPlugin
+X-KDE-Library=libkttsd_eposplugin
+X-KDE-Languages=cs,sk