1 /***************************************************** vim:set ts=4 sw=4 sts=4:
2 Player Object for playing synthesized audio files. Plays them
6 (C) 2004 by Gary Cramblitt <garycramblitt@comcast.net>
8 Original author: Gary Cramblitt <garycramblitt@comcast.net>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 ******************************************************************************/
25 // TestPlayer includes.
26 #include "testplayer.h"
29 #include <QtCore/QFile>
30 #include <QtGui/QApplication>
33 #include <ktemporaryfile.h>
34 #include <kstandarddirs.h>
35 #include <kparts/componentfactory.h>
37 #include <kservicetypetrader.h>
41 #include "stretcher.h"
42 #include "pluginconf.h"
47 TestPlayer::TestPlayer(QObject
*parent
, const char *name
,
48 const int playerOption
, const float audioStretchFactor
, const QString
&sinkName
) :
52 m_playerOption
= playerOption
;
53 m_audioStretchFactor
= audioStretchFactor
;
56 m_sinkName
= sinkName
;
62 TestPlayer::~TestPlayer()
69 * Sets which audio player to use.
73 void TestPlayer::setPlayerOption(const int playerOption
) { m_playerOption
= playerOption
; }
76 * Sets the audio stretch factor (Speed adjustment).
81 void TestPlayer::setAudioStretchFactor(const float audioStretchFactor
)
82 { m_audioStretchFactor
= audioStretchFactor
; }
84 void TestPlayer::setSinkName(const QString
&sinkName
) { m_sinkName
= sinkName
; }
87 * Plays the specifified audio file and waits for completion.
88 * The audio file speed is adjusted according to the stretch factor.
89 * @param waveFile Name of the audio file to play.
91 void TestPlayer::play(const QString
&waveFile
)
93 // kDebug() << "TestPlayer::play: running";
94 // Create a Stretcher object to adjust the audio Speed.
95 QString playFile
= waveFile
;
97 if (m_audioStretchFactor
!= 1.0)
99 tmpFile
= makeSuggestedFilename();
100 // kDebug() << "TestPlayer::play: stretching file " << playFile << " by " << m_audioStretchFactor
101 // << " to file " << tmpFile << endl;
102 m_stretcher
= new Stretcher();
103 if (m_stretcher
->stretch(playFile
, tmpFile
, m_audioStretchFactor
))
105 while (m_stretcher
->getState() != Stretcher::ssFinished
) qApp
->processEvents();
106 playFile
= m_stretcher
->getOutFilename();
112 // Create player object based on player option.
113 // kDebug() << "TestPlayer::play: creating Player object with playerOption " << m_playerOption;
114 m_player
= createPlayerObject(m_playerOption
);
115 // If player object could not be created, avoid crash is the best we can do!
116 if (!m_player
) return;
117 // kDebug() << "TestPlayer::play: starting playback.";
118 m_player
->startPlay(playFile
);
120 // TODO: The following hunk of code would ideally be unnecessary. We would just
121 // return at this point and let take care of
122 // cleaning up the play object. However, because we've been called from DCOP,
123 // this seems to be necessary. The call to processEvents is problematic because
124 // it can cause re-entrancy.
125 while (m_player
->playing()) qApp
->processEvents();
126 // kDebug() << "TestPlayer::play: stopping playback.";
130 if (!tmpFile
.isEmpty()) QFile::remove(tmpFile
);
134 * Creates and returns a player object based on user option.
136 Player
* TestPlayer::createPlayerObject(int playerOption
)
144 plugInName
= "kttsd_phononplugin";
149 plugInName
= "kttsd_alsaplugin";
154 // Default to Phonon.
155 plugInName
= "kttsd_phononplugin";
159 KService::List offers
= KServiceTypeTrader::self()->query(
160 "KTTSD/AudioPlugin", QString("DesktopEntryName == '%1'").arg(plugInName
));
162 if(offers
.count() == 1)
164 // kDebug() << "TestPlayer::createPlayerObject: Loading " << offers[0]->library();
165 KLibFactory
*factory
= KLibLoader::self()->factory(offers
[0]->library().toLatin1());
168 KLibLoader::createInstance
<Player
>(
169 offers
[0]->library().toLatin1(), this, QStringList(offers
[0]->library().toLatin1()));
171 kDebug() << "TestPlayer::createPlayerObject: Could not create factory.";
174 kDebug() << "TestPlayer::createPlayerObject: Could not load " + plugInName
+
175 ". Is KDEDIRS set correctly?" << endl
;
176 if (player
) player
->setSinkName(m_sinkName
);
181 * Constructs a temporary filename for plugins to use as a suggested filename
182 * for synthesis to write to.
183 * @return Full pathname of suggested file.
185 QString
TestPlayer::makeSuggestedFilename()
187 KTemporaryFile
*tempFile
= new KTemporaryFile();
188 tempFile
->setPrefix("kttsmgr-");
189 tempFile
->setSuffix(".wav");
191 QString waveFile
= tempFile
->fileName();
193 // kDebug() << "TestPlayer::makeSuggestedFilename: Suggesting filename: " << waveFile;
194 return PlugInConf::realFilePath(waveFile
);