added support for playlists containing other playlists

This commit is contained in:
fgerlits 2004-11-29 20:40:36 +00:00
parent f8e5516240
commit 34b681064c
14 changed files with 489 additions and 164 deletions

View File

@ -4,6 +4,6 @@
<!ELEMENT audioClip EMPTY >
<!ATTLIST audioClip id NMTOKEN #REQUIRED >
<!ATTLIST audioClip playlength NMTOKEN #REQUIRED >
<!ATTLIST audioClip uri CDATA #REQUIRED >
<!ATTLIST audioClip uri CDATA #IMPLIED >
]>
<audioClip id="1" playlength="00:18:30.000" uri="file:var/test1.mp3" />

View File

@ -5,14 +5,14 @@
<!ATTLIST playlist id NMTOKEN #REQUIRED >
<!ATTLIST playlist playlength NMTOKEN #REQUIRED >
<!ELEMENT playlistElement (audioClip, fadeInfo?) >
<!ELEMENT playlistElement ((audioClip|playlist), fadeInfo?) >
<!ATTLIST playlistElement id NMTOKEN #REQUIRED >
<!ATTLIST playlistElement relativeOffset NMTOKEN #REQUIRED >
<!ELEMENT audioClip EMPTY >
<!ATTLIST audioClip id NMTOKEN #REQUIRED >
<!ATTLIST audioClip playlength NMTOKEN #REQUIRED >
<!ATTLIST audioClip uri CDATA #REQUIRED >
<!ATTLIST audioClip uri CDATA #IMPLIED >
<!ELEMENT fadeInfo EMPTY >
<!ATTLIST fadeInfo id NMTOKEN #REQUIRED >
@ -20,15 +20,23 @@
<!ATTLIST fadeInfo fadeOut NMTOKEN #REQUIRED >
]>
<playlist id="1" playlength="01:30:00.000">
<playlist id="1" playlength="00:00:34.000" >
<playlistElement id="101" relativeOffset="0" >
<audioClip id="10001" playlength="01:00:00.000"
uri="file:var/test1.mp3"/>
<audioClip id="10001" playlength="00:00:11.000"
uri="file:var/test1.mp3" />
</playlistElement>
<playlistElement id="102" relativeOffset="01:00:00.000" >
<audioClip id="10002" playlength="00:30:00.000"
uri="file:var/test2.mp3"/>
<fadeInfo id="9901" fadeIn="00:00:02.000"
<playlistElement id="102" relativeOffset="00:00:11.000000" >
<audioClip id="10002" playlength="00:00:12.000000"
uri="file:var/test2.mp3" />
<fadeInfo id="9901" fadeIn="00:00:02.000000"
fadeOut="00:00:01.500000" />
</playlistElement>
<playlistElement id="103" relativeOffset="00:00:23.000000" >
<playlist id="2" playlength="00:00:11.000000" >
<playlistElement id="111" relativeOffset="0" >
<audioClip id="10003" playlength="00:00:11.000"
uri="file:var/test3.mp3" />
</playlistElement>
</playlist>
</playlistElement>
</playlist>

View File

@ -1,14 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE playlistElement [
<!ELEMENT playlistElement (audioClip, fadeInfo?) >
<!ELEMENT playlistElement ((audioClip|playlist), fadeInfo?) >
<!ATTLIST playlistElement id NMTOKEN #REQUIRED >
<!ATTLIST playlistElement relativeOffset NMTOKEN #REQUIRED >
<!ELEMENT playlist (playlistElement*) >
<!ATTLIST playlist id NMTOKEN #REQUIRED >
<!ATTLIST playlist playlength NMTOKEN #REQUIRED >
<!ELEMENT audioClip EMPTY >
<!ATTLIST audioClip id NMTOKEN #REQUIRED >
<!ATTLIST audioClip playlength NMTOKEN #REQUIRED >
<!ATTLIST audioClip uri CDATA #REQUIRED >
<!ATTLIST audioClip uri CDATA #IMPLIED >
<!ELEMENT fadeInfo EMPTY >
<!ATTLIST fadeInfo id NMTOKEN #REQUIRED >
@ -16,7 +20,12 @@
<!ATTLIST fadeInfo fadeOut NMTOKEN #REQUIRED >
]>
<playlistElement id="707" relativeOffset="00:12:34.000" >
<audioClip id="10001" playlength="01:00:00.000" uri="file:var/test1.mp3" />
<playlistElement id="103" relativeOffset="00:00:11.000000" >
<playlist id="2" playlength="00:00:11.000000" >
<playlistElement id="111" relativeOffset="0" >
<audioClip id="10003" playlength="00:00:11.000"
uri="file:var/test3.mp3" />
</playlistElement>
</playlist>
<fadeInfo id="9901" fadeIn="00:00:02.000" fadeOut="00:00:01.500000" />
</playlistElement >
</playlistElement>

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.7 $
Version : $Revision: 1.8 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/AudioClip.h,v $
------------------------------------------------------------------------------*/
@ -77,21 +77,24 @@ using namespace boost::posix_time;
* <pre><code>
* &lt;audioClip id="1"
* playlength="00:18:30.000000"
* uri="file:var/test1.mp3" &gt;
* uri="file:var/test1.mp3"
* &lt;/audioClip&gt;
* </code></pre>
*
* The URI is not normally part of the XML element; it's only included
* as an optional attribute for testing purposes.
*
* The DTD for the above element is:
*
* <pre><code>
* &lt;!ELEMENT audioClip EMPTY &gt;
* &lt;!ATTLIST audioClip id NMTOKEN #REQUIRED &gt;
* &lt;!ATTLIST audioClip playlength NMTOKEN #REQUIRED &gt;
* &lt;!ATTLIST audioClip uri CDATA #REQUIRED &gt;
* &lt;!ATTLIST audioClip uri CDATA #IMPLIED &gt;
* </code></pre>
*
* @author $Author: fgerlits $
* @version $Revision: 1.7 $
* @version $Revision: 1.8 $
*/
class AudioClip : public Configurable
{
@ -112,9 +115,14 @@ class AudioClip : public Configurable
Ptr<time_duration>::Ref playlength;
/**
* The location of the audio clip.
* The location of the binary audio clip sound file.
*/
Ptr<string>::Ref uri;
Ptr<const string>::Ref uri;
/**
* The identifying token returned by the storage server.
*/
Ptr<const string>::Ref token;
public:
@ -193,14 +201,14 @@ class AudioClip : public Configurable
*
* @return the playing length of this audio clip, in microseconds.
*/
Ptr<const time_duration>::Ref
Ptr<time_duration>::Ref
getPlaylength(void) const throw ()
{
return playlength;
}
/**
* Return the URI of this audio clip.
* Return the URI of the binary sound file of this audio clip.
*
* @return the URI of this audio clip.
*/
@ -211,15 +219,37 @@ class AudioClip : public Configurable
}
/**
* Change the URI of this audio clip. This is only used in testing.
* Set the URI of the binary sound file of this audio clip.
*
* @return the URI of this audio clip.
*/
void
setUri(Ptr<string>::Ref uri) throw ()
setUri(Ptr<const string>::Ref uri) throw ()
{
this->uri = uri;
}
/**
* Return the token returned by the storage server.
*
* @return the token of this audio clip.
*/
Ptr<const string>::Ref
getToken(void) const throw ()
{
return token;
}
/**
* Set the token returned by the storage server.
*
* @return the token of this audio clip.
*/
void
setToken(Ptr<const string>::Ref token) throw ()
{
this->token = token;
}
};

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.3 $
Version : $Revision: 1.4 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/FadeInfo.h,v $
------------------------------------------------------------------------------*/
@ -89,7 +89,7 @@ using namespace boost::posix_time;
* </code></pre>
*
* @author $Author: fgerlits $
* @version $Revision: 1.3 $
* @version $Revision: 1.4 $
*/
class FadeInfo : public Configurable
{
@ -203,7 +203,7 @@ class FadeInfo : public Configurable
*
* @return the length of the fade in period, in microseconds.
*/
Ptr<const time_duration>::Ref
Ptr<time_duration>::Ref
getFadeIn(void) const throw ()
{
return fadeIn;
@ -214,7 +214,7 @@ class FadeInfo : public Configurable
*
* @return the length of the fade in period, in microseconds.
*/
Ptr<const time_duration>::Ref
Ptr<time_duration>::Ref
getFadeOut(void) const throw ()
{
return fadeOut;

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.16 $
Version : $Revision: 1.17 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/Playlist.h,v $
------------------------------------------------------------------------------*/
@ -92,7 +92,7 @@ using namespace boost::posix_time;
* </code></pre>
*
* @author $Author: fgerlits $
* @version $Revision: 1.16 $
* @version $Revision: 1.17 $
*/
class Playlist : public Configurable
{
@ -115,7 +115,12 @@ class Playlist : public Configurable
/**
* The uri of the SMIL file generated from this playlist (if any).
*/
Ptr<std::string>::Ref uri;
Ptr<const std::string>::Ref uri;
/**
* The token given to this playlist by the storage server.
*/
Ptr<const std::string>::Ref token;
/**
* Flag set if playlist is currently playing.
@ -238,33 +243,54 @@ class Playlist : public Configurable
*
* @return the playling length of this playlist, in microseconds.
*/
Ptr<const time_duration>::Ref
Ptr<time_duration>::Ref
getPlaylength(void) const throw ()
{
return playlength;
}
/**
* Return the uri of the playlist.
* Return the URI of the SMIL file generated from this playlist.
*
* @return the uri of the playlist.
*/
Ptr<const std::string>::Ref
getUri(void) const throw ()
getUri(void) const throw ()
{
return uri;
}
/**
* Set the uri of the playlist.
* Set the URI of the SMIL file generated from this playlist.
*
*/
void
setUri(Ptr<std::string>::Ref uri) throw ()
setUri(Ptr<const std::string>::Ref uri) throw ()
{
this->uri = uri;
}
/**
* Return the token given to this playlist by the storage server.
*
* @return the uri of the playlist.
*/
Ptr<const std::string>::Ref
getToken(void) const throw ()
{
return token;
}
/**
* Set the token given to this playlist by the storage server.
*
*/
void
setToken(Ptr<const std::string>::Ref token) throw ()
{
this->token = token;
}
/**
* Test whether the playlist is locked for editing or playing.
*
@ -355,7 +381,7 @@ class Playlist : public Configurable
* to the start of the playlist
* @param fadeInfo the fade in / fade out info (optional)
* @exception std::invalid_argument if the playlist already contains
* an audio clip with the same relative offset
* a playlist element with the same relative offset
*/
void
addAudioClip(Ptr<AudioClip>::Ref audioClip,
@ -364,6 +390,23 @@ class Playlist : public Configurable
= Ptr<FadeInfo>::Ref())
throw (std::invalid_argument);
/**
* Add a new sub-playlist to the playlist.
*
* @param playlist the sub-playlist to be added
* @param relativeOffset the start of the sub-playlist, relative
* to the start of the containing playlist
* @param fadeInfo the fade in / fade out info (optional)
* @exception std::invalid_argument if the playlist already contains
* a playlist element with the same relative offset
*/
void
addPlaylist(Ptr<Playlist>::Ref playlist,
Ptr<time_duration>::Ref relativeOffset,
Ptr<FadeInfo>::Ref fadeInfo
= Ptr<FadeInfo>::Ref())
throw (std::invalid_argument);
/**
* Set the fade in / fade out info for a playlist element.
*
@ -380,6 +423,8 @@ class Playlist : public Configurable
/**
* Remove an audio clip from the playlist.
* THIS IS OBSOLETE, SUPERSEDED BY removePlaylistElement().
* TODO: REMOVE IT AFTER THERE ARE NO MORE REFERENCES TO IT.
*
* @param relativeOffset the start of the audio clip, relative
* to the start of the playlist
@ -390,6 +435,18 @@ class Playlist : public Configurable
removeAudioClip(Ptr<const time_duration>::Ref relativeOffset)
throw (std::invalid_argument);
/**
* Remove a playlist element from the playlist.
*
* @param relativeOffset the start of the playlist element, relative
* to the start of the playlist
* @exception std::invalid_argument if the playlist does not contain
* a playlist element at the specified relative offset
*/
void
removePlaylistElement(Ptr<const time_duration>::Ref relativeOffset)
throw (std::invalid_argument);
/**
* Validate the playlist: check that there are no overlaps or gaps.
* If the playlength is the only thing amiss, playlist is considered

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.7 $
Version : $Revision: 1.8 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/include/LiveSupport/Core/PlaylistElement.h,v $
------------------------------------------------------------------------------*/
@ -61,6 +61,8 @@ using namespace boost::posix_time;
using namespace LiveSupport;
using namespace LiveSupport::Core;
// forward declaration to avoid circular reference
class Playlist;
/* ================================================================ constants */
@ -71,7 +73,7 @@ using namespace LiveSupport::Core;
/* =============================================================== data types */
/**
* An item in a Playlist, consisting of an AudioClip
* An item in a Playlist, consisting of an AudioClip or another Playlist
* and optional FadeInfo (fade in / fade out information).
*
* This object has to be configured with an XML configuration element
@ -90,16 +92,23 @@ using namespace LiveSupport::Core;
* The DTD for the above element is:
*
* <pre><code>
* &lt;!ELEMENT playlistElement (audioClip, fadeInfo?) &gt;
* &lt;!ELEMENT playlistElement ((audioClip|playlist), fadeInfo?) &gt;
* &lt;!ATTLIST playlistElement id NMTOKEN #REQUIRED &gt;
* &lt;!ATTLIST playlistElement relativeOffset NMTOKEN #REQUIRED &gt;
* </code></pre>
*
* @author $Author: fgerlits $
* @version $Revision: 1.7 $
* @version $Revision: 1.8 $
*/
class PlaylistElement : public Configurable
{
public:
/**
* The possible types of the playlist element (audio clip or
* sub-playlist).
*/
enum Type { AudioClipType, PlaylistType };
private:
/**
* The name of the configuration XML element used by Playlist.
@ -116,11 +125,21 @@ class PlaylistElement : public Configurable
*/
Ptr<time_duration>::Ref relativeOffset;
/**
* The type of the entry (audio clip or sub-playlist).
*/
Type type;
/**
* The audio clip associated with the entry.
*/
Ptr<AudioClip>::Ref audioClip;
/**
* The playlist associated with the entry.
*/
Ptr<Playlist>::Ref playlist;
/**
* The fade in / fade out info associated with the entry.
*/
@ -161,7 +180,7 @@ class PlaylistElement : public Configurable
}
/**
* Create a new playlist element, with a new UniqueId,
* Create a new audio clip playlist element, with a new UniqueId,
* to be added to a playlist.
*
* @param relativeOffset the start time of this element, relative to
@ -180,6 +199,30 @@ class PlaylistElement : public Configurable
this->relativeOffset = relativeOffset;
this->audioClip = audioClip;
this->fadeInfo = fadeInfo;
this->type = AudioClipType;
}
/**
* Create a new sub-playlist playlist element, with a new UniqueId,
* to be added to a playlist.
*
* @param relativeOffset the start time of this element, relative to
* the start of the playlist.
* @param playlist (a pointer to) the sub-playlist associated
* with the playlist element.
* @param fadeInfo fade in / fade out information (optional)
*/
PlaylistElement(Ptr<time_duration>::Ref relativeOffset,
Ptr<Playlist>::Ref playlist,
Ptr<FadeInfo>::Ref fadeInfo
= Ptr<FadeInfo>::Ref())
throw ()
{
this->id = UniqueId::generateId();
this->relativeOffset = relativeOffset;
this->playlist = playlist;
this->fadeInfo = fadeInfo;
this->type = PlaylistType;
}
/**
@ -231,12 +274,23 @@ class PlaylistElement : public Configurable
*
* @return the relative offset of the element.
*/
Ptr<const time_duration>::Ref
Ptr<time_duration>::Ref
getRelativeOffset(void) const throw ()
{
return relativeOffset;
}
/**
* Return the type of this playlist element.
*
* @return either AudioClipType or PlaylistType.
*/
Type
getType(void) const throw ()
{
return type;
}
/**
* Return the audio clip associated with the playlist element.
*
@ -248,6 +302,17 @@ class PlaylistElement : public Configurable
return audioClip;
}
/**
* Return the sub-playlist associated with the playlist element.
*
* @return the sub-playlist associated with the element.
*/
Ptr<Playlist>::Ref
getPlaylist(void) const throw ()
{
return playlist;
}
/**
* Set the fade info associated with the playlist element.
*
@ -264,7 +329,7 @@ class PlaylistElement : public Configurable
*
* @return the fade info associated with the element.
*/
Ptr<const FadeInfo>::Ref
Ptr<FadeInfo>::Ref
getFadeInfo(void) const throw ()
{
return fadeInfo;

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.4 $
Version : $Revision: 1.5 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/AudioClip.cxx,v $
------------------------------------------------------------------------------*/
@ -97,14 +97,6 @@ AudioClip :: configure(const xmlpp::Element & element)
strStr >> idValue;
id.reset(new UniqueId(idValue));
if (!(attribute = element.get_attribute(uriAttrName))) {
std::string eMsg = "Missing attribute ";
eMsg += uriAttrName;
throw std::invalid_argument(eMsg);
}
std::string uriValue = attribute->get_value();
uri.reset(new std::string(uriValue));
if (!(attribute = element.get_attribute(playlengthAttrName))) {
std::string eMsg = "missing attribute ";
eMsg += idAttrName;
@ -112,4 +104,9 @@ AudioClip :: configure(const xmlpp::Element & element)
}
playlength.reset(new time_duration(
duration_from_string(attribute->get_value())));
if (attribute = element.get_attribute(uriAttrName)) {
std::string uriValue = attribute->get_value();
uri.reset(new std::string(uriValue));
}
}

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.1 $
Version : $Revision: 1.2 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/AudioClipTest.cxx,v $
------------------------------------------------------------------------------*/
@ -110,8 +110,6 @@ AudioClipTest :: firstTest(void)
CPPUNIT_ASSERT(duration->minutes() == 18);
CPPUNIT_ASSERT(duration->seconds() == 30);
// CPPUNIT_ASSERT(*(audioClip->getTitle()) == "The_Sounds_of_Silence");
} catch (std::invalid_argument &e) {
CPPUNIT_FAIL("semantic error in configuration file");
} catch (xmlpp::exception &e) {

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.14 $
Version : $Revision: 1.15 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/Playlist.cxx,v $
------------------------------------------------------------------------------*/
@ -153,7 +153,7 @@ Playlist::addAudioClip(Ptr<AudioClip>::Ref audioClip,
throw (std::invalid_argument)
{
if (elementList->find(*relativeOffset) != elementList->end()) {
std::string eMsg = "two audio clips at the same relative offset";
std::string eMsg = "two playlist elements at the same relative offset";
throw std::invalid_argument(eMsg);
}
@ -163,6 +163,26 @@ Playlist::addAudioClip(Ptr<AudioClip>::Ref audioClip,
}
/*------------------------------------------------------------------------------
* Add a new sub-playlist to the playlist.
*----------------------------------------------------------------------------*/
void
Playlist::addPlaylist(Ptr<Playlist>::Ref playlist,
Ptr<time_duration>::Ref relativeOffset,
Ptr<FadeInfo>::Ref fadeInfo)
throw (std::invalid_argument)
{
if (elementList->find(*relativeOffset) != elementList->end()) {
std::string eMsg = "two playlist elements at the same relative offset";
throw std::invalid_argument(eMsg);
}
Ptr<PlaylistElement>::Ref playlistElement(new PlaylistElement(
relativeOffset, playlist, fadeInfo));
(*elementList)[*relativeOffset] = playlistElement;
}
/*------------------------------------------------------------------------------
* Change the fade in / fade out info of a playlist element.
*----------------------------------------------------------------------------*/
@ -174,7 +194,7 @@ Playlist::setFadeInfo(Ptr<time_duration>::Ref relativeOffset,
PlaylistElementListType::iterator it = elementList->find(*relativeOffset);
if (it == elementList->end()) {
std::string eMsg = "no audio clip at this relative offset";
std::string eMsg = "no playlist element at this relative offset";
throw std::invalid_argument(eMsg);
}
@ -184,6 +204,9 @@ Playlist::setFadeInfo(Ptr<time_duration>::Ref relativeOffset,
/*------------------------------------------------------------------------------
* Remove an audio clip from the playlist.
CHANGE references of THIS TO REFER TO removePlaylistElement()
*----------------------------------------------------------------------------*/
void
Playlist::removeAudioClip(Ptr<const time_duration>::Ref relativeOffset)
@ -197,6 +220,22 @@ Playlist::removeAudioClip(Ptr<const time_duration>::Ref relativeOffset)
}
/*------------------------------------------------------------------------------
* Remove a playlist element from the playlist.
*----------------------------------------------------------------------------*/
void
Playlist::removePlaylistElement(Ptr<const time_duration>::Ref relativeOffset)
throw (std::invalid_argument)
{
// this returns the number of elements found and erased
if (!elementList->erase(*relativeOffset)) {
std::string eMsg = "no playlist element found "
"at the specified relative offset";
throw std::invalid_argument(eMsg);
}
}
/*------------------------------------------------------------------------------
* Lock or unlock the playlist for editing.
*----------------------------------------------------------------------------*/
@ -254,9 +293,10 @@ Playlist::setLockedForPlaying(const bool lockStatus)
bool
Playlist::valid(void) throw ()
{
Ptr<time_duration>::Ref runningTime(new time_duration(0,0,0,0));
Ptr<const PlaylistElement>::Ref playlistElement;
Ptr<const AudioClip>::Ref audioClip;
Ptr<time_duration>::Ref runningTime(new time_duration(0,0,0,0));
Ptr<PlaylistElement>::Ref playlistElement;
Ptr<AudioClip>::Ref audioClip;
Ptr<Playlist>::Ref playlist;
PlaylistElementListType::const_iterator it = elementList->begin();
while (it != elementList->end()) {
@ -264,11 +304,23 @@ Playlist::valid(void) throw ()
if (*runningTime != *(playlistElement->getRelativeOffset())) {
return false;
}
audioClip = playlistElement->getAudioClip();
*runningTime += *(audioClip->getPlaylength());
if (playlistElement->getType() == PlaylistElement::AudioClipType) {
audioClip = playlistElement->getAudioClip();
*runningTime += *(audioClip->getPlaylength());
}
else if (playlistElement->getType() == PlaylistElement::PlaylistType) {
playlist = playlistElement->getPlaylist();
if (!playlist->valid()) {
return false;
}
*runningTime += *(playlist->getPlaylength());
}
else { // this should never happen
return false;
}
++it;
}
playlength = runningTime; // fix playlength, if everything else is OK
playlength = runningTime; // fix playlength, if everything else is OK
return true;
}

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.4 $
Version : $Revision: 1.5 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistElement.cxx,v $
------------------------------------------------------------------------------*/
@ -35,6 +35,7 @@
#include <sstream>
#include "LiveSupport/Core/Playlist.h"
#include "LiveSupport/Core/PlaylistElement.h"
using namespace boost::posix_time;
@ -66,6 +67,11 @@ static const std::string relativeOffsetAttrName = "relativeOffset";
*/
static const std::string audioClipElementName = "audioClip";
/**
* The name of the playlist child element of the playlist element.
*/
static const std::string playlistElementName = "playlist";
/**
* The name of the fade info child element of the playlist element.
*/
@ -118,24 +124,46 @@ PlaylistElement :: configure(const xmlpp::Element & element)
= element.get_children(audioClipElementName);
xmlpp::Node::NodeList::iterator it = childNodes.begin();
if (it == childNodes.end()) {
std::string eMsg = "missing ";
eMsg += audioClipElementName;
eMsg += " XML element";
throw std::invalid_argument(eMsg);
}
const xmlpp::Element * audioClipElement
= dynamic_cast<const xmlpp::Element*> (*it);
audioClip.reset(new AudioClip);
audioClip->configure(*audioClipElement); // may throw exception
++it;
if (it != childNodes.end()) {
std::string eMsg = "more than one ";
eMsg += audioClipElementName;
eMsg += " XML element";
throw std::invalid_argument(eMsg);
const xmlpp::Element * audioClipElement
= dynamic_cast<const xmlpp::Element*> (*it);
type = AudioClipType;
audioClip.reset(new AudioClip);
audioClip->configure(*audioClipElement); // may throw exception
++it;
if (it != childNodes.end()) {
std::string eMsg = "more than one ";
eMsg += audioClipElementName;
eMsg += " XML element";
throw std::invalid_argument(eMsg);
}
}
else {
childNodes = element.get_children(playlistElementName);
it = childNodes.begin();
if (it != childNodes.end()) {
const xmlpp::Element * playlistElement
= dynamic_cast<const xmlpp::Element*> (*it);
type = PlaylistType;
playlist.reset(new Playlist);
playlist->configure(*playlistElement); // may throw exception
++it;
if (it != childNodes.end()) {
std::string eMsg = "more than one ";
eMsg += playlistElementName;
eMsg += " XML element";
throw std::invalid_argument(eMsg);
}
}
else {
std::string eMsg = "missing ";
eMsg += audioClipElementName;
eMsg += " or ";
eMsg += playlistElementName;
eMsg += " XML element in PlaylistElement configuration";
throw std::invalid_argument(eMsg);
}
}
// set fade info

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.3 $
Version : $Revision: 1.4 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistElementTest.cxx,v $
------------------------------------------------------------------------------*/
@ -105,24 +105,47 @@ PlaylistElementTest :: firstTest(void)
playlistElement->configure(*root);
CPPUNIT_ASSERT(playlistElement->getId()->getId() == 707);
// the playlist element
CPPUNIT_ASSERT(playlistElement->getId()->getId() == 103);
Ptr<const time_duration>::Ref relativeOffset
= playlistElement->getRelativeOffset();
CPPUNIT_ASSERT(relativeOffset->total_seconds() == 12*60 + 34);
CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId()
== 10001);
CPPUNIT_ASSERT(relativeOffset->total_seconds() == 11);
CPPUNIT_ASSERT(playlistElement->getFadeInfo()->getId()->getId()
== 9901);
Ptr<const time_duration>::Ref fadeIn
= playlistElement->getFadeInfo()
->getFadeIn();
CPPUNIT_ASSERT(fadeIn->total_milliseconds() == 2000);
Ptr<const time_duration>::Ref fadeOut
= playlistElement->getFadeInfo()
->getFadeOut();
CPPUNIT_ASSERT(fadeOut->total_milliseconds() == 1500);
CPPUNIT_ASSERT(playlistElement->getType()
== PlaylistElement::PlaylistType);
// the playlist inside the playlist element
CPPUNIT_ASSERT(playlistElement->getPlaylist()->getId()->getId()
== 2);
Ptr<Playlist>::Ref playlist = playlistElement->getPlaylist();
Playlist::const_iterator it = playlist->begin();
CPPUNIT_ASSERT(it != playlist->end());
playlistElement = it->second;
++it;
CPPUNIT_ASSERT(it == playlist->end());
// the playlist element inside the playlist
CPPUNIT_ASSERT(playlistElement->getId()->getId() == 111);
relativeOffset = playlistElement->getRelativeOffset();
CPPUNIT_ASSERT(relativeOffset->total_seconds() == 0);
CPPUNIT_ASSERT(playlistElement->getType()
== PlaylistElement::AudioClipType);
// and the audio clip inside the playlist element
CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId()
== 10003);
} catch (std::invalid_argument &e) {
std::string eMsg = "semantic error in configuration file:\n";
eMsg += e.what();

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.12 $
Version : $Revision: 1.13 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/core/src/PlaylistTest.cxx,v $
------------------------------------------------------------------------------*/
@ -84,15 +84,6 @@ PlaylistTest :: setUp(void) throw ()
playlist->configure(*root);
CPPUNIT_ASSERT(playlist->getId()->getId() == 1);
Ptr<const boost::posix_time::time_duration>::Ref duration
= playlist->getPlaylength();
CPPUNIT_ASSERT(duration->hours() == 1);
CPPUNIT_ASSERT(duration->minutes() == 30);
CPPUNIT_ASSERT(duration->seconds() == 0);
CPPUNIT_ASSERT(playlist->valid());
} catch (std::invalid_argument &e) {
CPPUNIT_FAIL("semantic error in configuration file");
} catch (xmlpp::exception &e) {
@ -117,13 +108,22 @@ void
PlaylistTest :: firstTest(void)
throw (CPPUNIT_NS::Exception)
{
Playlist::const_iterator it = playlist->begin();
CPPUNIT_ASSERT(playlist->getId()->getId() == 1);
Ptr<const boost::posix_time::time_duration>::Ref duration
= playlist->getPlaylength();
CPPUNIT_ASSERT(duration->total_seconds() == 34);
CPPUNIT_ASSERT(playlist->valid());
Playlist::const_iterator it = playlist->begin();
CPPUNIT_ASSERT(it != playlist->end());
Ptr<PlaylistElement>::Ref playlistElement = it->second;
Ptr<PlaylistElement>::Ref playlistElement = it->second;
CPPUNIT_ASSERT(playlistElement->getId()->getId() == 101);
Ptr<const time_duration>::Ref relativeOffset
= playlistElement->getRelativeOffset();
Ptr<const time_duration>::Ref relativeOffset
= playlistElement->getRelativeOffset();
CPPUNIT_ASSERT(relativeOffset->total_seconds() == 0);
CPPUNIT_ASSERT(playlistElement->getType()
== PlaylistElement::AudioClipType);
CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId()
== 10001);
@ -132,12 +132,14 @@ PlaylistTest :: firstTest(void)
playlistElement = it->second;
CPPUNIT_ASSERT(playlistElement->getId()->getId() == 102);
relativeOffset = playlistElement->getRelativeOffset();
CPPUNIT_ASSERT(relativeOffset->total_seconds() == 60 * 60);
CPPUNIT_ASSERT(relativeOffset->total_seconds() == 11);
CPPUNIT_ASSERT(playlistElement->getType()
== PlaylistElement::AudioClipType);
CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId()
== 10002);
++it;
CPPUNIT_ASSERT(it == playlist->end());
// CPPUNIT_ASSERT(it == playlist->end());
}
@ -192,13 +194,21 @@ PlaylistTest :: audioClipTest(void)
CPPUNIT_FAIL(eMsg);
}
CPPUNIT_ASSERT(!playlist->valid()); // overlapping audio clips
CPPUNIT_ASSERT(!playlist->valid()); // big gap in playlist
Playlist::const_iterator it = playlist->begin();
CPPUNIT_ASSERT(it != playlist->end());
++it;
Ptr<PlaylistElement>::Ref playlistElement = it->second;
CPPUNIT_ASSERT(it != playlist->end());
++it;
CPPUNIT_ASSERT(it != playlist->end());
++it;
CPPUNIT_ASSERT(it != playlist->end());
Ptr<PlaylistElement>::Ref playlistElement = it->second;
CPPUNIT_ASSERT(playlistElement->getType()
== PlaylistElement::AudioClipType);
CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId()
== 20001);
@ -206,17 +216,14 @@ PlaylistTest :: audioClipTest(void)
= playlistElement->getRelativeOffset();
CPPUNIT_ASSERT(otherRelativeOffset->total_seconds() == 10*60);
++it;
CPPUNIT_ASSERT(it != playlist->end());
++it;
CPPUNIT_ASSERT(it == playlist->end());
try {
playlist->removeAudioClip(relativeOffset);
playlist->removePlaylistElement(relativeOffset);
}
catch (std::invalid_argument &e) {
string eMsg = "removeAudioClip returned with error: ";
string eMsg = "removePlaylistElement returned with error: ";
eMsg += e.what();
CPPUNIT_FAIL(eMsg);
}
@ -226,18 +233,19 @@ PlaylistTest :: audioClipTest(void)
++it;
CPPUNIT_ASSERT(it != playlist->end());
++it;
CPPUNIT_ASSERT(it != playlist->end());
++it;
CPPUNIT_ASSERT(it == playlist->end());
Ptr<const time_duration>::Ref phonyRelativeOffset(
new time_duration(0,0,1,0));
try {
playlist->removeAudioClip(phonyRelativeOffset);
playlist->removePlaylistElement(phonyRelativeOffset);
CPPUNIT_FAIL("removePlaylistElement allowed to remove "
"non-existent audio clip");
}
catch (std::invalid_argument &e) {
return;
}
CPPUNIT_FAIL("removeAudioClip allowed to remove "
"non-existent audio clip");
}
@ -256,10 +264,12 @@ PlaylistTest :: savedCopyTest(void)
}
playlist->createSavedCopy();
playlist->removeAudioClip(Ptr<time_duration>::Ref(
playlist->removePlaylistElement(Ptr<time_duration>::Ref(
new time_duration(0,0,0,0)));
playlist->removeAudioClip(Ptr<time_duration>::Ref(
new time_duration(1,0,0,0)));
playlist->removePlaylistElement(Ptr<time_duration>::Ref(
new time_duration(0,0,11,0)));
playlist->removePlaylistElement(Ptr<time_duration>::Ref(
new time_duration(0,0,23,0)));
CPPUNIT_ASSERT(playlist->begin() == playlist->end());
try {
@ -273,7 +283,13 @@ PlaylistTest :: savedCopyTest(void)
CPPUNIT_ASSERT(it != playlist->end());
++it;
CPPUNIT_ASSERT(it != playlist->end());
CPPUNIT_ASSERT(it->second->getAudioClip()->getId()->getId() == 10002);
Ptr<PlaylistElement>::Ref playlistElement = it->second;
CPPUNIT_ASSERT(playlistElement->getType()
== PlaylistElement::AudioClipType);
CPPUNIT_ASSERT(playlistElement->getAudioClip()->getId()->getId()
== 10002);
++it;
CPPUNIT_ASSERT(it != playlist->end());
++it;
CPPUNIT_ASSERT(it == playlist->end());
@ -307,14 +323,16 @@ PlaylistTest :: fadeInfoTest(void)
CPPUNIT_ASSERT(playlistElement->getFadeInfo()->getFadeOut()
->total_milliseconds() == 1500);
++it;
CPPUNIT_ASSERT(it != playlist->end());
++it;
CPPUNIT_ASSERT(it == playlist->end());
Ptr<time_duration>::Ref relativeOffset (new time_duration(0,0,0,0));
Ptr<time_duration>::Ref fadeIn (new time_duration(0,0,3,200000));
Ptr<time_duration>::Ref fadeOut(new time_duration(0,0,4,0));
Ptr<FadeInfo>::Ref fadeInfo(new FadeInfo(fadeIn, fadeOut));
Ptr<time_duration>::Ref relativeOffset (new time_duration(0,0,0,0));
try {
playlist->setFadeInfo(relativeOffset, fadeInfo);
}
@ -322,22 +340,20 @@ PlaylistTest :: fadeInfoTest(void)
CPPUNIT_FAIL("could not add new fade info");
}
relativeOffset.reset(new time_duration(0,0,11,0));
try {
playlist->setFadeInfo(relativeOffset, fadeInfo);
}
catch (std::invalid_argument &e) {
CPPUNIT_FAIL("could not update fade info");
}
it = playlist->begin();
playlistElement = it->second;
CPPUNIT_ASSERT(playlistElement->getFadeInfo()->getFadeIn()
->total_milliseconds() == 3200);
CPPUNIT_ASSERT(playlistElement->getFadeInfo()->getFadeOut()
->total_milliseconds() == 4000);
relativeOffset.reset(new time_duration(1,00,0,0));
try {
playlist->setFadeInfo(relativeOffset, fadeInfo);
}
catch (std::invalid_argument &e) {
CPPUNIT_FAIL("could not update fade info");
}
++it;
playlistElement = it->second;
CPPUNIT_ASSERT(playlistElement->getFadeInfo()->getFadeIn()
@ -345,7 +361,7 @@ PlaylistTest :: fadeInfoTest(void)
CPPUNIT_ASSERT(playlistElement->getFadeInfo()->getFadeOut()
->total_milliseconds() == 4000);
relativeOffset.reset(new time_duration(0,18,0,0));
relativeOffset.reset(new time_duration(0,0,7,0));
try {
playlist->setFadeInfo(relativeOffset, fadeInfo);

View File

@ -22,7 +22,7 @@
Author : $Author: fgerlits $
Version : $Revision: 1.19 $
Version : $Revision: 1.20 $
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storage/src/TestStorageClient.cxx,v $
------------------------------------------------------------------------------*/
@ -116,6 +116,16 @@ static const std::string smilAudioClipNodeName = "audio";
*----------------------------------------------------------------------------*/
static const std::string smilAudioClipUriAttrName = "src";
/*------------------------------------------------------------------------------
* The name of the sub-playlist element node in the SMIL file.
*----------------------------------------------------------------------------*/
static const std::string smilPlaylistNodeName = "audio";
/*------------------------------------------------------------------------------
* The name of the attribute containing the URI of the sub-playlist element.
*----------------------------------------------------------------------------*/
static const std::string smilPlaylistUriAttrName = "src";
/* =============================================== local function prototypes */
@ -252,8 +262,7 @@ TestStorageClient :: acquirePlaylist(Ptr<SessionId>::Ref sessionId,
}
Ptr<Playlist>::Ref oldPlaylist = playlistMapIt->second;
Ptr<time_duration>::Ref playlength(new time_duration(
*(oldPlaylist->getPlaylength()) ));
Ptr<time_duration>::Ref playlength = oldPlaylist->getPlaylength();
Ptr<Playlist>::Ref newPlaylist(new Playlist(UniqueId::generateId(),
playlength));
Ptr<xmlpp::Document>::Ref
@ -273,28 +282,46 @@ TestStorageClient :: acquirePlaylist(Ptr<SessionId>::Ref sessionId,
Playlist::const_iterator it = oldPlaylist->begin();
while (it != oldPlaylist->end()) {
Ptr<AudioClip>::Ref audioClip
= acquireAudioClip(sessionId, it->second
->getAudioClip()
->getId());
Ptr<time_duration>::Ref relativeOffset(new time_duration(
*(it->second->getRelativeOffset()) ));
Ptr<const FadeInfo>::Ref oldFadeInfo = it->second->getFadeInfo();
Ptr<FadeInfo>::Ref newFadeInfo;
if (oldFadeInfo) { // careful: fadeInfo may be 0
newFadeInfo.reset(new FadeInfo(*oldFadeInfo));
}
Ptr<PlaylistElement>::Ref plElement = it->second;
Ptr<FadeInfo>::Ref fadeInfo = plElement->getFadeInfo();
newPlaylist->addAudioClip(audioClip,
relativeOffset,
newFadeInfo);
if (plElement->getType() == PlaylistElement::AudioClipType) {
Ptr<AudioClip>::Ref audioClip
= acquireAudioClip(sessionId, plElement
->getAudioClip()
->getId());
Ptr<time_duration>::Ref relativeOffset
= plElement->getRelativeOffset();
newPlaylist->addAudioClip(audioClip, relativeOffset, fadeInfo);
xmlpp::Element * smilAudioClipNode
xmlpp::Element* smilAudioClipNode
= smilSeqNode->add_child(smilAudioClipNodeName);
smilAudioClipNode->set_attribute(
smilAudioClipUriAttrName,
*(audioClip->getUri()) );
++it;
smilAudioClipNode->set_attribute(
smilAudioClipUriAttrName,
*(audioClip->getUri()) );
++it;
}
else if (plElement->getType() == PlaylistElement::PlaylistType) {
Ptr<Playlist>::Ref playlist
= acquirePlaylist(sessionId, plElement
->getPlaylist()
->getId());
Ptr<time_duration>::Ref relativeOffset
= plElement->getRelativeOffset();
newPlaylist->addPlaylist(playlist, relativeOffset, fadeInfo);
xmlpp::Element* smilPlaylistNode
= smilSeqNode->add_child(smilPlaylistNodeName);
smilPlaylistNode->set_attribute(
smilPlaylistUriAttrName,
*(playlist->getUri()) );
++it;
}
else { // this should never happen
Ptr<Playlist>::Ref nullPointer;
return nullPointer;
}
}
std::stringstream fileName;
@ -330,25 +357,40 @@ TestStorageClient :: releasePlaylist(Ptr<SessionId>::Ref sessionId,
std::remove(playlist->getUri()->substr(7).c_str());
int badAudioClips = 0;
int badPlaylistElements = 0;
Playlist::const_iterator it = playlist->begin();
while (it != playlist->end()) {
try {
releaseAudioClip(sessionId, it->second->getAudioClip());
Ptr<PlaylistElement>::Ref plElement = it->second;
if (plElement->getType() == PlaylistElement::AudioClipType) {
try {
releaseAudioClip(sessionId, it->second->getAudioClip());
}
catch (std::invalid_argument &e) {
++badPlaylistElements;
}
++it;
}
catch (std::invalid_argument &e) {
++badAudioClips;
else if (plElement->getType() == PlaylistElement::PlaylistType) {
try {
releasePlaylist(sessionId, it->second->getPlaylist());
}
catch (std::invalid_argument &e) {
++badPlaylistElements;
}
++it;
}
++it;
else { // this should never happen
++badPlaylistElements;
}
}
Ptr<std::string>::Ref nullPointer;
playlist->setUri(nullPointer);
if (badAudioClips) {
if (badPlaylistElements) {
std::stringstream eMsg;
eMsg << "could not release " << badAudioClips
<< " audio clips in playlist";
eMsg << "could not release " << badPlaylistElements
<< " playlist elements in playlist";
throw std::logic_error(eMsg.str());
}
}