summaryrefslogtreecommitdiffstats
path: root/kttsd/libkttsd/testplayer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kttsd/libkttsd/testplayer.cpp')
-rw-r--r--kttsd/libkttsd/testplayer.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/kttsd/libkttsd/testplayer.cpp b/kttsd/libkttsd/testplayer.cpp
new file mode 100644
index 0000000..06d05a7
--- /dev/null
+++ b/kttsd/libkttsd/testplayer.cpp
@@ -0,0 +1,209 @@
+/***************************************************** vim:set ts=4 sw=4 sts=4:
+ Player Object for playing synthesized audio files. Plays them
+ synchronously.
+ -------------------
+ 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.
+ ******************************************************************************/
+
+// Qt includes.
+#include <qfile.h>
+
+// KDE includes.
+#include <kapplication.h>
+#include <ktempfile.h>
+#include <kstandarddirs.h>
+#include <kparts/componentfactory.h>
+#include <ktrader.h>
+#include <kdebug.h>
+
+// KTTS includes.
+#include "player.h"
+#include "stretcher.h"
+#include "pluginconf.h"
+
+// TestPlayer includes.
+#include "testplayer.h"
+
+/**
+ * Constructor.
+ */
+TestPlayer::TestPlayer(QObject *parent, const char *name,
+ const int playerOption, const float audioStretchFactor, const QString &sinkName) :
+ QObject(parent, name)
+{
+ m_playerOption = playerOption;
+ m_audioStretchFactor = audioStretchFactor;
+ m_stretcher = 0;
+ m_player = 0;
+ m_sinkName = sinkName;
+}
+
+/**
+ * Destructor.
+ */
+TestPlayer::~TestPlayer()
+{
+ delete m_stretcher;
+ delete m_player;
+}
+
+/**
+ * Sets which audio player to use.
+ * 0 = aRts
+ * 1 = gstreamer
+ * 2 = ALSA
+ * 3 = aKode
+ */
+void TestPlayer::setPlayerOption(const int playerOption) { m_playerOption = playerOption; }
+
+/**
+ * Sets the audio stretch factor (Speed adjustment).
+ * 1.0 = normal
+ * 0.5 = twice as fast
+ * 2.0 = twice as slow
+ */
+void TestPlayer::setAudioStretchFactor(const float audioStretchFactor)
+ { m_audioStretchFactor = audioStretchFactor; }
+
+void TestPlayer::setSinkName(const QString &sinkName) { m_sinkName = sinkName; }
+
+/**
+ * Plays the specifified audio file and waits for completion.
+ * The audio file speed is adjusted according to the stretch factor.
+ * @param waveFile Name of the audio file to play.
+ */
+void TestPlayer::play(const QString &waveFile)
+{
+ // kdDebug() << "TestPlayer::play: running" << endl;
+ // Create a Stretcher object to adjust the audio Speed.
+ QString playFile = waveFile;
+ QString tmpFile;
+ if (m_audioStretchFactor != 1.0)
+ {
+ tmpFile = makeSuggestedFilename();
+ // kdDebug() << "TestPlayer::play: stretching file " << playFile << " by " << m_audioStretchFactor
+ // << " to file " << tmpFile << endl;
+ m_stretcher = new Stretcher();
+ if (m_stretcher->stretch(playFile, tmpFile, m_audioStretchFactor))
+ {
+ while (m_stretcher->getState() != Stretcher::ssFinished) qApp->processEvents();
+ playFile = m_stretcher->getOutFilename();
+ }
+ delete m_stretcher;
+ m_stretcher = 0;
+ }
+
+ // Create player object based on player option.
+ // kdDebug() << "TestPlayer::play: creating Player object with playerOption " << m_playerOption << endl;
+ m_player = createPlayerObject(m_playerOption);
+ // If player object could not be created, avoid crash is the best we can do!
+ if (!m_player) return;
+ // kdDebug() << "TestPlayer::play: starting playback." << endl;
+ m_player->startPlay(playFile);
+
+ // TODO: The following hunk of code would ideally be unnecessary. We would just
+ // return at this point and let take care of
+ // cleaning up the play object. However, because we've been called from DCOP,
+ // this seems to be necessary. The call to processEvents is problematic because
+ // it can cause re-entrancy.
+ while (m_player->playing()) qApp->processEvents();
+ // kdDebug() << "TestPlayer::play: stopping playback." << endl;
+ m_player->stop();
+ delete m_player;
+ m_player = 0;
+ if (!tmpFile.isEmpty()) QFile::remove(tmpFile);
+}
+
+/**
+ * Creates and returns a player object based on user option.
+ */
+Player* TestPlayer::createPlayerObject(int playerOption)
+{
+ Player* player = 0;
+ QString plugInName;
+ switch(playerOption)
+ {
+ case 1 :
+ {
+ plugInName = "kttsd_gstplugin";
+ break;
+ }
+ case 2 :
+ {
+ plugInName = "kttsd_alsaplugin";
+ break;
+ }
+ case 3 :
+ {
+ plugInName = "kttsd_akodeplugin";
+ break;
+ }
+ default:
+ {
+ plugInName = "kttsd_artsplugin";
+ break;
+ }
+ }
+ KTrader::OfferList offers = KTrader::self()->query(
+ "KTTSD/AudioPlugin", QString("DesktopEntryName == '%1'").arg(plugInName));
+
+ if(offers.count() == 1)
+ {
+ // kdDebug() << "TestPlayer::createPlayerObject: Loading " << offers[0]->library() << endl;
+ KLibFactory *factory = KLibLoader::self()->factory(offers[0]->library().latin1());
+ if (factory)
+ player =
+ KParts::ComponentFactory::createInstanceFromLibrary<Player>(
+ offers[0]->library().latin1(), this, offers[0]->library().latin1());
+ else
+ kdDebug() << "TestPlayer::createPlayerObject: Could not create factory." << endl;
+ }
+ if (player == 0)
+ kdDebug() << "TestPlayer::createPlayerObject: Could not load " + plugInName +
+ ". Is KDEDIRS set correctly?" << endl;
+ else
+ // Must have GStreamer >= 0.8.7.
+ if (playerOption == 1)
+ {
+ if (!player->requireVersion(0, 8, 7))
+ {
+ delete player;
+ player = 0;
+ }
+ }
+ if (player) player->setSinkName(m_sinkName);
+ return player;
+}
+
+/**
+ * Constructs a temporary filename for plugins to use as a suggested filename
+ * for synthesis to write to.
+ * @return Full pathname of suggested file.
+ */
+QString TestPlayer::makeSuggestedFilename()
+{
+ KTempFile tempFile (locateLocal("tmp", "kttsmgr-"), ".wav");
+ QString waveFile = tempFile.file()->name();
+ tempFile.close();
+ QFile::remove(waveFile);
+ // kdDebug() << "TestPlayer::makeSuggestedFilename: Suggesting filename: " << waveFile << endl;
+ return PlugInConf::realFilePath(waveFile);
+}
+