diff --git a/livesupport/modules/playlistExecutor/etc/Makefile.in b/livesupport/modules/playlistExecutor/etc/Makefile.in
index 7dd2ee5a0..87b1912fe 100644
--- a/livesupport/modules/playlistExecutor/etc/Makefile.in
+++ b/livesupport/modules/playlistExecutor/etc/Makefile.in
@@ -20,8 +20,8 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
-# Author : $Author: maroy $
-# Version : $Revision: 1.6 $
+# Author : $Author: fgerlits $
+# Version : $Revision: 1.7 $
# Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/etc/Makefile.in,v $
#
# @configure_input@
@@ -77,6 +77,8 @@ VPATH = ${SRC_DIR}
LIBXMLPP_CFLAGS=@LIBXMLPP_CFLAGS@
LIBXMLPP_LIBS=@LIBXMLPP_LIBS@
+TAGLIB_LIBS =`${USR_DIR}/bin/taglib-config --libs`
+
TEST_RESULTS = ${DOC_DIR}/testResults.xml
# the text result XSLT has to be relative to the test result file, e.g. TMP_DIR
TEST_XSLT = ../etc/testResultToHtml.xsl
@@ -105,6 +107,7 @@ CXXFLAGS = @CXXFLAGS@ @DEFS@ @COVERAGE_CXXFLAGS@ -pthread \
-I${INCLUDE_DIR} -I${TMP_DIR}
LDFLAGS = @LDFLAGS@ -pthread \
${LIBXMLPP_LIBS} \
+ ${TAGLIB_LIBS} \
-L${USR_LIB_DIR} \
-L${CORE_LIB_DIR} \
-L${HELIX_LIB_DIR} \
@@ -126,8 +129,8 @@ TEST_RUNNER_OBJS = ${TMP_DIR}/TestRunner.o \
${TMP_DIR}/HelixPlayerTest.o \
${TMP_DIR}/AudioPlayerFactoryTest.o
TEST_RUNNER_LIBS = -l${PLAYLIST_EXECUTOR_LIB} -l${CORE_LIB} \
- ${HELIX_LIBS} \
- -lcppunit -ldl -lm
+ ${HELIX_LIBS} ${TAGLIB_LIBS} \
+ -lcppunit -ldl -lm -lxmlrpc++
#-------------------------------------------------------------------------------
diff --git a/livesupport/modules/playlistExecutor/etc/playlist.xml b/livesupport/modules/playlistExecutor/etc/playlist.xml
new file mode 100644
index 000000000..160530ef1
--- /dev/null
+++ b/livesupport/modules/playlistExecutor/etc/playlist.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/livesupport/modules/playlistExecutor/src/HelixPlayer.cxx b/livesupport/modules/playlistExecutor/src/HelixPlayer.cxx
index 0433236bd..2b832cfaf 100644
--- a/livesupport/modules/playlistExecutor/src/HelixPlayer.cxx
+++ b/livesupport/modules/playlistExecutor/src/HelixPlayer.cxx
@@ -21,8 +21,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Author : $Author: maroy $
- Version : $Revision: 1.10 $
+ Author : $Author: fgerlits $
+ Version : $Revision: 1.11 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/HelixPlayer.cxx,v $
------------------------------------------------------------------------------*/
@@ -278,7 +278,7 @@ void
HelixPlayer :: start(void) throw (std::logic_error)
{
if (player->GetSourceCount() == 0) {
- throw std::logic_error("HelixPlayer::playThis() not called yet");
+ throw std::logic_error("HelixPlayer::open() not called yet");
}
player->Begin();
playing = true;
@@ -376,3 +376,97 @@ DLLAccessPath* GetDLLAccessPath(void)
}
+/*------------------------------------------------------------------------------
+ * Play a playlist, with simulated fading.
+ *----------------------------------------------------------------------------*/
+void
+HelixPlayer :: openAndStartPlaylist(Ptr::Ref playlist)
+ throw (std::invalid_argument,
+ std::logic_error,
+ std::runtime_error)
+{
+ if (!playlist || !playlist->getUri()) {
+ throw std::invalid_argument("no playlist SMIL file found");
+ }
+ open(*playlist->getUri()); // may throw invalid_argument
+
+ bool hasFadeInfo = false;
+ int numberOfPlaylistElements = 0;
+ Playlist::const_iterator it = playlist->begin();
+ while (it != playlist->end()) {
+ ++numberOfPlaylistElements;
+ if (it->second->getFadeInfo()) {
+ hasFadeInfo = true;
+ }
+ ++it;
+ }
+
+ start(); // may throw logic_error
+ if (!numberOfPlaylistElements || !hasFadeInfo) {
+ return;
+ }
+
+ IHXAudioPlayer* audioPlayer = 0;
+ if (player->QueryInterface(IID_IHXAudioPlayer, (void**)&audioPlayer)
+ != HXR_OK
+ || !audioPlayer) {
+ throw std::runtime_error("can't get IHXAudioPlayer interface");
+ }
+
+ IHXAudioCrossFade* crossFade = 0;
+ if (audioPlayer->QueryInterface(IID_IHXAudioCrossFade, (void**)&crossFade)
+ != HXR_OK
+ || !crossFade) {
+ throw std::runtime_error("can't get IHXAudioCrossFade interface");
+ }
+
+ Ptr::Ref sleepT(new time_duration(microseconds(10)));
+
+ IHXAudioStream* audioStream[numberOfPlaylistElements];
+ for (int i = 0; i < numberOfPlaylistElements; i++) {
+ do {
+ TimeConversion::sleep(sleepT);
+ audioStream[i] = audioPlayer->GetAudioStream(i);
+ } while (!audioStream[i]);
+ }
+
+ it = playlist->begin();
+
+ sleepT.reset(new time_duration(seconds(2)));
+ TimeConversion::sleep(sleepT);
+
+ for (int i = 1; i < numberOfPlaylistElements; i++) {
+
+ Ptr::Ref playlistElement = it->second;
+ if (!playlistElement->getFadeInfo()) {
+ ++it;
+ continue;
+ }
+
+ // we assume i-th fade out is the same as (i+1)-st fade in
+ unsigned long crossFadeLength = playlistElement
+ ->getFadeInfo()
+ ->getFadeOut()
+ ->total_milliseconds();
+ unsigned long fadeOutAt = playlistElement->getRelativeOffset()
+ ->total_milliseconds()
+ + playlistElement->getPlayable()
+ ->getPlaylength()
+ ->total_milliseconds()
+ - crossFadeLength;
+
+//std::cerr << "fadeOutAt: " << fadeOutAt << "\n"
+// << "crossFadeLength: " << crossFadeLength << "\n";
+ crossFade->CrossFade(audioStream[i-1], audioStream[i],
+ fadeOutAt, fadeOutAt, crossFadeLength);
+
+ ++it;
+ }
+
+ for (int i = 0; i < numberOfPlaylistElements; i++) {
+ HX_RELEASE(audioStream[i]);
+ }
+ HX_RELEASE(crossFade);
+ HX_RELEASE(audioPlayer);
+}
+
diff --git a/livesupport/modules/playlistExecutor/src/HelixPlayer.h b/livesupport/modules/playlistExecutor/src/HelixPlayer.h
index 8f5882e81..94c4d370d 100644
--- a/livesupport/modules/playlistExecutor/src/HelixPlayer.h
+++ b/livesupport/modules/playlistExecutor/src/HelixPlayer.h
@@ -21,8 +21,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Author : $Author: maroy $
- Version : $Revision: 1.8 $
+ Author : $Author: fgerlits $
+ Version : $Revision: 1.9 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/HelixPlayer.h,v $
------------------------------------------------------------------------------*/
@@ -52,7 +52,7 @@
#include "ErrorSink.h"
#include "AuthenticationManager.h"
#include "ClientContext.h"
-
+#include "LiveSupport/Core/Playlist.h"
namespace LiveSupport {
namespace PlaylistExecutor {
@@ -90,8 +90,8 @@ using namespace LiveSupport::Core;
*
*
*
- * @author $Author: maroy $
- * @version $Revision: 1.8 $
+ * @author $Author: fgerlits $
+ * @version $Revision: 1.9 $
*/
class HelixPlayer : virtual public Configurable,
virtual public AudioPlayerInterface,
@@ -236,7 +236,7 @@ class HelixPlayer : virtual public Configurable,
* will be accessed automatically.
* Note: this call will not start playing! You will
* have to call the start() function to begin playing.
- * Always close any opened resources with a call to close().
+ * Always close any opened resource with a call to close().
*
* @param fileUrl a URL to a file
* @exception std::invalid_argument if the supplied fileUrl
@@ -258,12 +258,12 @@ class HelixPlayer : virtual public Configurable,
/**
* Start playing.
* This call will start playing the active playlist, which was
- * set by a previous call to playThis().
+ * set by a previous call to open().
* Playing can be stopped by calling stop().
*
* @exception std::logic_error if there was no previous call to
- * playThis().
- * @see #playThis
+ * open().
+ * @see #open
* @see #stop
*/
virtual void
@@ -326,6 +326,23 @@ class HelixPlayer : virtual public Configurable,
*/
virtual void
setVolume(unsigned int volume) throw ();
+
+ /**
+ * Play a playlist, with simulated fading.
+ *
+ * @param playlist the Playlist object to be played.
+ * @exception std::invalid_argument playlist is invalid (e.g.,
+ * does not have a URI field, or there is no valid
+ * SMIL file at the given URI).
+ * @exception std::logic_error thrown by start() if open() was
+ * unsuccessful, but returned normally (never happens)
+ * @exception std::runtime_error on errors thrown by the helix player
+ */
+ void
+ openAndStartPlaylist(Ptr::Ref playlist)
+ throw (std::invalid_argument,
+ std::logic_error,
+ std::runtime_error);
};
diff --git a/livesupport/modules/playlistExecutor/src/HelixPlayerTest.cxx b/livesupport/modules/playlistExecutor/src/HelixPlayerTest.cxx
index be93a459e..25ab8065d 100644
--- a/livesupport/modules/playlistExecutor/src/HelixPlayerTest.cxx
+++ b/livesupport/modules/playlistExecutor/src/HelixPlayerTest.cxx
@@ -21,8 +21,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Author : $Author: maroy $
- Version : $Revision: 1.8 $
+ Author : $Author: fgerlits $
+ Version : $Revision: 1.9 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/HelixPlayerTest.cxx,v $
------------------------------------------------------------------------------*/
@@ -63,6 +63,12 @@ CPPUNIT_TEST_SUITE_REGISTRATION(HelixPlayerTest);
*/
static const std::string configFileName = "etc/helixPlayer.xml";
+/**
+ * The name of the configuration file for the test playlist in the
+ * openAndStartPlaylist() method.
+ */
+static const std::string playlistConfigFileName = "etc/playlist.xml";
+
/* =============================================== local function prototypes */
@@ -382,3 +388,46 @@ HelixPlayerTest :: smilSoundAnimationTest(void)
}
+/*------------------------------------------------------------------------------
+ * Test different SMIL file features
+ *----------------------------------------------------------------------------*/
+void
+HelixPlayerTest :: animationWorkaroundTest(void)
+ throw (CPPUNIT_NS::Exception)
+{
+ Ptr::Ref playlist;
+
+ try {
+ Ptr::Ref parser(
+ new xmlpp::DomParser(playlistConfigFileName, true));
+ const xmlpp::Document * document = parser->get_document();
+ const xmlpp::Element * root = document->get_root_node();
+
+ playlist.reset(new Playlist());
+ playlist->configure(*root);
+
+ } catch (std::invalid_argument &e) {
+ std::cerr << "semantic error in configuration file" << std::endl;
+ } catch (xmlpp::exception &e) {
+ std::cerr << e.what() << std::endl;
+ }
+
+ CPPUNIT_ASSERT(playlist);
+ CPPUNIT_ASSERT(playlist->getId());
+
+ Ptr::Ref uri(new std::string("file:var/playlist.smil"));
+ playlist->setUri(uri);
+
+ CPPUNIT_ASSERT_NO_THROW(helixPlayer->initialize());
+ CPPUNIT_ASSERT_NO_THROW(helixPlayer->openAndStartPlaylist(playlist));
+ CPPUNIT_ASSERT(helixPlayer->isPlaying());
+
+ Ptr::Ref sleepT(new time_duration(microseconds(10)));
+ while (helixPlayer->isPlaying()) {
+ TimeConversion::sleep(sleepT);
+ }
+ CPPUNIT_ASSERT(!helixPlayer->isPlaying());
+ helixPlayer->close();
+
+ helixPlayer->deInitialize();
+}
diff --git a/livesupport/modules/playlistExecutor/src/HelixPlayerTest.h b/livesupport/modules/playlistExecutor/src/HelixPlayerTest.h
index a865ae16b..5fbaca722 100644
--- a/livesupport/modules/playlistExecutor/src/HelixPlayerTest.h
+++ b/livesupport/modules/playlistExecutor/src/HelixPlayerTest.h
@@ -22,7 +22,7 @@
Author : $Author: fgerlits $
- Version : $Revision: 1.7 $
+ Version : $Revision: 1.8 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/playlistExecutor/src/Attic/HelixPlayerTest.h,v $
------------------------------------------------------------------------------*/
@@ -58,7 +58,7 @@ namespace PlaylistExecutor {
* Unit test for the HelixPlayer class.
*
* @author $Author: fgerlits $
- * @version $Revision: 1.7 $
+ * @version $Revision: 1.8 $
* @see HelixPlayer
*/
class HelixPlayerTest : public CPPUNIT_NS::TestFixture
@@ -75,6 +75,7 @@ class HelixPlayerTest : public CPPUNIT_NS::TestFixture
// CPPUNIT_TEST(smilParallelTest3);
// CPPUNIT_TEST(smilParallelTest4);
// CPPUNIT_TEST(smilSoundAnimationTest);
+ CPPUNIT_TEST(animationWorkaroundTest);
CPPUNIT_TEST_SUITE_END();
private:
@@ -185,6 +186,14 @@ class HelixPlayerTest : public CPPUNIT_NS::TestFixture
void
smilSoundAnimationTest(void) throw (CPPUNIT_NS::Exception);
+ /**
+ * Test the openAndStartPlaylist() method.
+ *
+ * @exception CPPUNIT_NS::Exception on test failures.
+ */
+ void
+ animationWorkaroundTest(void) throw (CPPUNIT_NS::Exception);
+
public:
/**
diff --git a/livesupport/modules/playlistExecutor/var/playlist.smil b/livesupport/modules/playlistExecutor/var/playlist.smil
new file mode 100644
index 000000000..6f4f48b8a
--- /dev/null
+++ b/livesupport/modules/playlistExecutor/var/playlist.smil
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
diff --git a/livesupport/modules/playlistExecutor/var/test10001.mp3 b/livesupport/modules/playlistExecutor/var/test10001.mp3
new file mode 100644
index 000000000..5fe526402
Binary files /dev/null and b/livesupport/modules/playlistExecutor/var/test10001.mp3 differ
diff --git a/livesupport/modules/playlistExecutor/var/test10002.mp3 b/livesupport/modules/playlistExecutor/var/test10002.mp3
new file mode 100644
index 000000000..1219a9056
Binary files /dev/null and b/livesupport/modules/playlistExecutor/var/test10002.mp3 differ
diff --git a/livesupport/modules/playlistExecutor/var/test10003.mp3 b/livesupport/modules/playlistExecutor/var/test10003.mp3
new file mode 100644
index 000000000..c0685a294
Binary files /dev/null and b/livesupport/modules/playlistExecutor/var/test10003.mp3 differ