2016-07-11 Fred Gleason <fredg@paravelsystems.com>

* Added rdxml_parse_test(1) in 'tests/'.
	* Added a RDCart::readXml()' method in 'lib/rdcart.cpp' and
	'lib/rdcart.h'.
	* Fixed a typo in the 'averageSegueLength' field in the 'RDCart::xml()'
	method in 'lib/rdcart.cpp'.
	* Removed the 'validity' field from the output of the 'RDCart::xml()'
	method in 'lib/rdcart.cpp'.
	* Removed the 'validity' and 'localCounter' fields from the output
	of the 'RDCut::xml()' method in 'lib/rdcut.cpp'.
This commit is contained in:
Fred Gleason 2016-07-11 14:01:30 -04:00
parent 3cac92b29d
commit edd8221b6f
18 changed files with 1351 additions and 14 deletions

1
.gitignore vendored
View File

@ -74,6 +74,7 @@ tests/audio_export_test
tests/audio_import_test
tests/audio_peaks_test
tests/datedecode_test
tests/rdxml_parse_test
tests/reserve_carts_test
tests/sas_switch_torture
tests/sas_torture

View File

@ -15268,3 +15268,13 @@
dialog heirarchy correctly.
2016-07-07 Fred Gleason <fredg@paravelsystems.com>
* Incremented the package version to 2.14.1int00.
2016-07-11 Fred Gleason <fredg@paravelsystems.com>
* Added rdxml_parse_test(1) in 'tests/'.
* Added a RDCart::readXml()' method in 'lib/rdcart.cpp' and
'lib/rdcart.h'.
* Fixed a typo in the 'averageSegueLength' field in the 'RDCart::xml()'
method in 'lib/rdcart.cpp'.
* Removed the 'validity' field from the output of the 'RDCart::xml()'
method in 'lib/rdcart.cpp'.
* Removed the 'validity' and 'localCounter' fields from the output
of the 'RDCut::xml()' method in 'lib/rdcut.cpp'.

View File

@ -431,6 +431,42 @@
<source>Cut Log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feature</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>open</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>theme</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>background</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>promo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>cold</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>fade</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>

View File

@ -427,6 +427,42 @@
<source>Cut Log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feature</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>open</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>theme</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>background</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>promo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>cold</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>fade</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>

View File

@ -427,6 +427,42 @@
<source>Cut Log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feature</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>open</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>theme</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>background</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>promo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>cold</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>fade</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>

View File

@ -413,6 +413,42 @@
<source>Cut Log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feature</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>open</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>theme</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>background</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>promo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>cold</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>fade</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>

View File

@ -427,6 +427,42 @@
<source>Cut Log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feature</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>open</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>theme</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>background</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>promo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>cold</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>fade</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>

View File

@ -427,6 +427,42 @@
<source>Cut Log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feature</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>open</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>theme</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>background</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>promo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>cold</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>fade</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>

View File

@ -427,6 +427,42 @@
<source>Cut Log</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>unknown</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>feature</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>open</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>close</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>theme</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>background</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>promo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>cold</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>fade</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>RDAddCart</name>

View File

@ -879,7 +879,7 @@ void RDCart::getMetadata(RDWaveData *data) const
data->setConductor(q->value(10).toString());
data->setTmciSongId(q->value(11).toString());
data->setBeatsPerMinute(q->value(12).toUInt());
data->setUsageCode(q->value(13).toUInt());
data->setUsageCode((RDWaveData::UsageCode)q->value(13).toUInt());
data->setSchedCodes(schedCodesList());
data->setMetadataFound(true);
}
@ -983,6 +983,35 @@ QString RDCart::xml(bool include_cuts,RDSettings *settings,int cutnum) const
RDCut *cut;
QStringList mlist;
sql=QString("select ")+
"TYPE,"+ // 00
"GROUP_NAME,"+ // 01
"TITLE,"+ // 02
"ARTIST,"+ // 03
"ALBUM,"+ // 04
"YEAR,"+ // 05
"LABEL,"+ // 06
"CLIENT,"+ // 07
"AGENCY,"+ // 08
"PUBLISHER,"+ // 09
"COMPOSER,"+ // 10
"USER_DEFINED,"+ // 11
"USAGE_CODE,"+ // 12
"FORCED_LENGTH,"+ // 13
"AVERAGE_LENGTH,"+ // 14
"LENGTH_DEVIATION,"+ // 15
"AVERAGE_SEGUE_LENGTH,"+ // 16
"AVERAGE_HOOK_LENGTH,"+ // 17
"CUT_QUANTITY,"+ // 18
"LAST_CUT_PLAYED,"+ // 19
"VALIDITY,"+ // 20
"ENFORCE_LENGTH,"+ // 21
"ASYNCRONOUS,"+ // 22
"OWNER,"+ // 23
"METADATA_DATETIME,"+ // 24
"CONDUCTOR "+ // 25
QString().sprintf("from CART where NUMBER=%u",cart_number);
/*
sql=QString().sprintf("select TYPE,GROUP_NAME,TITLE,ARTIST,ALBUM,YEAR,\
LABEL,CLIENT,AGENCY,PUBLISHER,COMPOSER,USER_DEFINED,\
USAGE_CODE,FORCED_LENGTH,AVERAGE_LENGTH,\
@ -991,6 +1020,7 @@ QString RDCart::xml(bool include_cuts,RDSettings *settings,int cutnum) const
VALIDITY,\
ENFORCE_LENGTH,ASYNCRONOUS,OWNER,METADATA_DATETIME \
from CART where NUMBER=%u",cart_number);
*/
q=new RDSqlQuery(sql);
if(q->first()) {
ret+="<cart>\n";
@ -1017,6 +1047,7 @@ QString RDCart::xml(bool include_cuts,RDSettings *settings,int cutnum) const
ret+=" "+RDXmlField("agency",q->value(8).toString());
ret+=" "+RDXmlField("publisher",q->value(9).toString());
ret+=" "+RDXmlField("composer",q->value(10).toString());
ret+=" "+RDXmlField("conductor",q->value(25).toString());
ret+=" "+RDXmlField("userDefined",q->value(11).toString());
ret+=" "+RDXmlField("usageCode",q->value(12).toInt());
ret+=" "+RDXmlField("forcedLength",
@ -1025,13 +1056,12 @@ QString RDCart::xml(bool include_cuts,RDSettings *settings,int cutnum) const
RDGetTimeLength(q->value(14).toUInt(),true));
ret+=" "+RDXmlField("lengthDeviation",
RDGetTimeLength(q->value(15).toUInt(),true));
ret+=" "+RDXmlField("averageSegueLenth",
ret+=" "+RDXmlField("averageSegueLength",
RDGetTimeLength(q->value(16).toUInt(),true));
ret+=" "+RDXmlField("averageHookLength",
RDGetTimeLength(q->value(17).toUInt(),true));
ret+=" "+RDXmlField("cutQuantity",q->value(18).toUInt());
ret+=" "+RDXmlField("lastCutPlayed",q->value(19).toUInt());
ret+=" "+RDXmlField("validity",q->value(20).toUInt());
ret+=" "+RDXmlField("enforceLength",RDBool(q->value(21).toString()));
ret+=" "+RDXmlField("asyncronous",RDBool(q->value(22).toString()));
ret+=" "+RDXmlField("owner",q->value(23).toString());
@ -1549,6 +1579,282 @@ void RDCart::removePending(RDStation *station,RDUser *user,RDConfig *config)
}
unsigned RDCart::readXml(std::vector<RDWaveData> *data,const QString &xml)
{
//
// HACK! HACK! HACK! HACK! HACK!
//
// This is totally ad-hoc and will likely break horribly for XML that
// deviates the least bit from that generated by Rivendell's own xml()
// methods.
//
// Slated to be put out of its misery as soon as we get a Real XML Parser.
//
int istate=0;
RDWaveData cartdata;
RDSettings *settings=NULL;
QStringList f0=f0.split("\n",xml);
for(unsigned i=0;i<f0.size();i++) {
f0[i]=f0[i].stripWhiteSpace();
}
for(unsigned i=0;i<f0.size();i++) {
switch(istate) {
case 0:
if(f0[i]=="<cart>") {
istate=1;
}
break;
case 1: // Cart-level objects
if(f0[i].contains("<number>")) {
cartdata.setCartNumber(GetXmlValue("number",f0[i]).toUInt());
}
if(f0[i].contains("<groupName>")) {
cartdata.setCategory(GetXmlValue("groupName",f0[i]).toString());
}
if(f0[i].contains("<title>")) {
cartdata.setTitle(GetXmlValue("title",f0[i]).toString());
}
if(f0[i].contains("<artist>")) {
cartdata.setArtist(GetXmlValue("artist",f0[i]).toString());
}
if(f0[i].contains("<album>")) {
cartdata.setAlbum(GetXmlValue("album",f0[i]).toString());
}
if(f0[i].contains("<label>")) {
cartdata.setLabel(GetXmlValue("label",f0[i]).toString());
}
if(f0[i].contains("<client>")) {
cartdata.setClient(GetXmlValue("client",f0[i]).toString());
}
if(f0[i].contains("<agency>")) {
cartdata.setAgency(GetXmlValue("agency",f0[i]).toString());
}
if(f0[i].contains("<composer>")) {
cartdata.setComposer(GetXmlValue("composer",f0[i]).toString());
}
if(f0[i].contains("<publisher>")) {
cartdata.setPublisher(GetXmlValue("publisher",f0[i]).toString());
}
if(f0[i].contains("<conductor>")) {
cartdata.setConductor(GetXmlValue("conductor",f0[i]).toString());
}
if(f0[i].contains("<userDefined>")) {
cartdata.setUserDefined(GetXmlValue("userDefined",f0[i]).toString());
}
if(f0[i].contains("<year>")) {
cartdata.setReleaseYear(GetXmlValue("year",f0[i]).toInt());
}
if(f0[i].contains("<forcedLength>")) {
cartdata.
setForcedLength(RDSetTimeLength(GetXmlValue("forcedLength",f0[i]).
toString()));
}
if(f0[i].contains("<averageLength>")) {
cartdata.
setAverageLength(RDSetTimeLength(GetXmlValue("averageLength",f0[i]).
toString()));
}
if(f0[i].contains("<lengthDeviation>")) {
cartdata.setLengthDeviation(RDSetTimeLength(GetXmlValue("lengthDeviation",f0[i]).
toString()));
}
if(f0[i].contains("<averageHookLength>")) {
cartdata.
setAverageHookLength(RDSetTimeLength(GetXmlValue("averageHookLength",f0[i]).
toString()));
}
if(f0[i].contains("<averageSegueLength>")) {
cartdata.
setAverageSegueLength(RDSetTimeLength(GetXmlValue("averageSegueLength",f0[i]).
toString()));
}
if(f0[i].contains("<cutQuantity>")) {
cartdata.setCutQuantity(GetXmlValue("cutQuantity",f0[i]).toInt());
}
if(f0[i].contains("<lastCutPlayed>")) {
cartdata.setLastCutPlayed(GetXmlValue("lastCutPlayed",f0[i]).toInt());
}
if(f0[i].contains("<enforceLength>")) {
cartdata.setEnforceLength(GetXmlValue("enforceLength",f0[i]).toBool());
}
if(f0[i].contains("<asyncronous>")) {
cartdata.setAsyncronous(GetXmlValue("asyncronous",f0[i]).toBool());
}
if(f0[i].contains("<owner>")) {
cartdata.setOwner(GetXmlValue("owner",f0[i]).toString());
}
if(f0[i].contains("<metadataDatetime>")) {
cartdata.setMetadataDatetime(GetXmlValue("metadataDatetime",f0[i]).
toDateTime());
}
if(f0[i]=="</cart>") {
istate=0;
}
if(f0[i]=="<cutList>") {
data->push_back(RDWaveData());
data->back()=cartdata;
istate=2;
}
break;
case 2: // Cut List
if(f0[i]=="<cut>") { // Start of new cut
data->push_back(RDWaveData());
data->back()=cartdata;
settings=new RDSettings();
istate=3;
}
if(f0[i]=="</cutList>") { // End of cut
istate=1;
}
break;
case 3: // Cut Object
if(f0[i].contains("<description>")) {
data->back().setDescription(GetXmlValue("description",f0[i]).toString());
}
if(f0[i].contains("<cutNumber>")) {
data->back().setCutNumber(GetXmlValue("cutNumber",f0[i]).toInt());
}
if(f0[i].contains("<cutName>")) {
data->back().setCutName(GetXmlValue("cutName",f0[i]).toString());
}
if(f0[i].contains("<evergreen>")) {
data->back().setEvergreen(GetXmlValue("evergreen",f0[i]).toBool());
}
if(f0[i].contains("<outcue>")) {
data->back().setOutCue(GetXmlValue("outcue",f0[i]).toString());
}
if(f0[i].contains("<isrc>")) {
data->back().setIsrc(GetXmlValue("isrc",f0[i]).toString());
}
if(f0[i].contains("<isci>")) {
data->back().setIsci(GetXmlValue("isci",f0[i]).toString());
}
if(f0[i].contains("<length>")) {
data->back().setLength(GetXmlValue("length",f0[i]).toInt());
}
if(f0[i].contains("<originName>")) {
data->back().setOriginator(GetXmlValue("originName",f0[i]).toString());
}
if(f0[i].contains("<originDatetime>")) {
data->back().setOriginationDate(GetXmlValue("originDatetime",f0[i]).
toDateTime().date());
data->back().setOriginationTime(GetXmlValue("originDatetime",f0[i]).
toDateTime().time());
}
if(f0[i].contains("<playCounter>")) {
data->back().setPlayCounter(GetXmlValue("playCounter",f0[i]).toInt());
}
if(f0[i].contains("<startDatetime>")) {
data->back().setStartDate(GetXmlValue("startDatetime",f0[i]).
toDateTime().date());
data->back().setStartTime(GetXmlValue("startDatetime",f0[i]).
toDateTime().time());
}
if(f0[i].contains("<endDatetime>")) {
data->back().setEndDate(GetXmlValue("endDatetime",f0[i]).
toDateTime().date());
data->back().setEndTime(GetXmlValue("endDatetime",f0[i]).
toDateTime().time());
}
if(f0[i].contains("<lastPlayDatetime>")) {
data->back().setLastPlayDatetime(GetXmlValue("lastPlayDatetime",f0[i]).
toDateTime());
}
if(f0[i].contains("<codingFormat>")) {
settings->setFormat((RDSettings::Format)GetXmlValue("codingFormat",f0[i]).
toUInt());
}
if(f0[i].contains("<sampleRate>")) {
settings->setSampleRate(GetXmlValue("sampleRate",f0[i]).toUInt());
}
if(f0[i].contains("<bitRate>")) {
settings->setBitRate(GetXmlValue("bitRate",f0[i]).toUInt());
}
if(f0[i].contains("<channels>")) {
settings->setChannels(GetXmlValue("channels",f0[i]).toUInt());
}
if(f0[i].contains("<playGain>")) {
data->back().setPlayGain(GetXmlValue("playGain",f0[i]).toInt());
}
if(f0[i].contains("<startPoint>")) {
data->back().setStartPos(GetXmlValue("startPoint",f0[i]).toInt());
}
if(f0[i].contains("<endPoint>")) {
data->back().setEndPos(GetXmlValue("endPoint",f0[i]).toInt());
}
if(f0[i].contains("<segueStartPoint>")) {
data->back().setSegueStartPos(GetXmlValue("segueStartPoint",f0[i]).
toInt());
}
if(f0[i].contains("<segueEndPoint>")) {
data->back().setSegueEndPos(GetXmlValue("segueEndPoint",f0[i]).toInt());
}
if(f0[i].contains("<segueGain>")) {
data->back().setSegueGain(GetXmlValue("segueGain",f0[i]).toInt());
}
if(f0[i].contains("<talkStartPoint>")) {
data->back().setIntroStartPos(GetXmlValue("talkStartPoint",f0[i]).
toInt());
}
if(f0[i].contains("<talkEndPoint>")) {
data->back().setIntroEndPos(GetXmlValue("talkEndPoint",f0[i]).toInt());
}
if(f0[i].contains("<hookStartPoint>")) {
data->back().setHookStartPos(GetXmlValue("hookStartPoint",f0[i]).
toInt());
}
if(f0[i].contains("<hookEndPoint>")) {
data->back().setHookEndPos(GetXmlValue("hookEndPoint",f0[i]).toInt());
}
if(f0[i].contains("<fadeupPoint>")) {
data->back().setFadeUpPos(GetXmlValue("fadeupPoint",f0[i]).toInt());
}
if(f0[i].contains("<fadedownPoint>")) {
data->back().setFadeDownPos(GetXmlValue("fadedownPoint",f0[i]).toInt());
}
if(f0[i]=="</cut>") { // End of cut
data->back().setAudioSettings(*settings);
delete settings;
settings=NULL;
istate=2;
}
break;
}
}
// printf("DUMP:\n%s\n",(const char *)cartdata.dump());
return data->size();
}
QVariant RDCart::GetXmlValue(const QString &tag,const QString &line)
{
bool ok=false;
QString value=line;
value=value.remove("<"+tag+">").remove("</"+tag+">");
value.toUInt(&ok);
if(ok) {
return QVariant(value.toUInt());
}
value.toInt(&ok);
if(ok) {
return QVariant(value.toInt());
}
return QVariant(value);
}
QString RDCart::GetNextCut(RDSqlQuery *q) const
{
QString cutname;

View File

@ -20,6 +20,7 @@
#include <qdatetime.h>
#include <qstringlist.h>
#include <qvariant.h>
#include <rdconfig.h>
#include <rdwavedata.h>
@ -158,8 +159,10 @@ class RDCart
static bool removeCutAudio(RDStation *station,RDUser *user,unsigned cart_num,
const QString &cutname,RDConfig *config);
static void removePending(RDStation *station,RDUser *user,RDConfig *config);
static unsigned readXml(std::vector<RDWaveData> *data,const QString &xml);
private:
static QVariant GetXmlValue(const QString &tag,const QString &line);
QString GetNextCut(RDSqlQuery *q) const;
int GetNextFreeCut() const;
RDCut::Validity ValidateCut(RDSqlQuery *q,bool enforce_length,

View File

@ -1226,8 +1226,6 @@ QString RDCut::xml(RDSettings *settings) const
ret+=" "+RDXmlField("weight",q->value(19).toUInt());
ret+=" "+RDXmlField("lastPlayDatetime",q->value(20).toDateTime());
ret+=" "+RDXmlField("playCounter",q->value(21).toUInt());
ret+=" "+RDXmlField("localCounter",q->value(22).toUInt());
ret+=" "+RDXmlField("validity",q->value(23).toUInt());
if(settings==NULL) {
ret+=" "+RDXmlField("codingFormat",q->value(24).toUInt());
ret+=" "+RDXmlField("sampleRate",q->value(25).toUInt());

View File

@ -17,8 +17,10 @@
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//
#include <qobject.h>
#include <rdconf.h>
#include <rdwavedata.h>
RDWaveData::RDWaveData()
@ -39,6 +41,54 @@ void RDWaveData::setMetadataFound(bool state)
}
unsigned RDWaveData::cartNumber() const
{
return data_cart_number;
}
void RDWaveData::setCartNumber(unsigned cartnum)
{
data_cart_number=cartnum;
}
int RDWaveData::cutNumber() const
{
return data_cut_number;
}
void RDWaveData::setCutNumber(int cutnum)
{
data_cut_number=cutnum;
}
QString RDWaveData::cutName() const
{
return data_cutname;
}
void RDWaveData::setCutName(const QString &str)
{
data_cutname=str;
}
RDWaveData::CartType RDWaveData::cartType() const
{
return data_cart_type;
}
void RDWaveData::setCartType(RDWaveData::CartType type)
{
data_cart_type=type;
}
QString RDWaveData::title() const
{
return data_title;
@ -159,13 +209,13 @@ void RDWaveData::setPublisher(const QString &str)
}
int RDWaveData::usageCode() const
RDWaveData::UsageCode RDWaveData::usageCode() const
{
return data_usage_code;
}
void RDWaveData::setUsageCode(int code)
void RDWaveData::setUsageCode(RDWaveData::UsageCode code)
{
data_usage_code=code;
}
@ -387,6 +437,198 @@ void RDWaveData::setEndType(RDWaveData::EndType type)
}
int RDWaveData::forcedLength() const
{
return data_forced_length;
}
void RDWaveData::setForcedLength(int msecs)
{
data_forced_length=msecs;
}
int RDWaveData::averageLength() const
{
return data_average_length;
}
void RDWaveData::setAverageLength(int msecs)
{
data_average_length=msecs;
}
int RDWaveData::lengthDeviation() const
{
return data_length_deviation;
}
void RDWaveData::setLengthDeviation(int msecs)
{
data_length_deviation=msecs;
}
int RDWaveData::averageSegueLength() const
{
return data_average_segue_length;
}
void RDWaveData::setAverageSegueLength(int msecs)
{
data_average_segue_length=msecs;
}
int RDWaveData::averageHookLength() const
{
return data_average_hook_length;
}
void RDWaveData::setAverageHookLength(int msecs)
{
data_average_hook_length=msecs;
}
int RDWaveData::cutQuantity() const
{
return data_cut_quantity;
}
void RDWaveData::setCutQuantity(int n)
{
data_cut_quantity=n;
}
int RDWaveData::lastCutPlayed() const
{
return data_last_cut_played;
}
void RDWaveData::setLastCutPlayed(int cutnum)
{
data_last_cut_played=cutnum;
}
QDateTime RDWaveData::lastPlayDatetime() const
{
return data_last_play_datetime;
}
void RDWaveData::setLastPlayDatetime(const QDateTime &dt)
{
data_last_play_datetime=dt;
}
int RDWaveData::length() const
{
return data_length;
}
void RDWaveData::setLength(int msecs)
{
data_length=msecs;
}
bool RDWaveData::enforceLength() const
{
return data_enforce_length;
}
void RDWaveData::setEnforceLength(bool state)
{
data_enforce_length=state;
}
bool RDWaveData::asyncronous() const
{
return data_asyncronous;
}
void RDWaveData::setAsyncronous(bool state)
{
data_asyncronous=state;
}
QString RDWaveData::owner() const
{
return data_owner;
}
void RDWaveData::setOwner(const QString &str)
{
data_owner=str;
}
QDateTime RDWaveData::metadataDatetime() const
{
return data_metadata_datetime;
}
void RDWaveData::setMetadataDatetime(const QDateTime &dt)
{
data_metadata_datetime=dt;
}
bool RDWaveData::dayOfWeek(int dow) const
{
return data_day_of_week[dow-1];
}
void RDWaveData::setDayOfWeek(int dow,bool state)
{
data_day_of_week[dow-1]=state;
}
int RDWaveData::weight() const
{
return data_weight;
}
void RDWaveData::setWeight(int weight)
{
data_weight=weight;
}
bool RDWaveData::evergreen() const
{
return data_evergreen;
}
void RDWaveData::setEvergreen(bool state)
{
data_evergreen=state;
}
int RDWaveData::introStartPos() const
{
return data_intro_start_pos;
@ -435,6 +677,18 @@ void RDWaveData::setSegueEndPos(int msec)
}
int RDWaveData::segueGain() const
{
return data_segue_gain;
}
void RDWaveData::setSegueGain(int lvl)
{
data_segue_gain=lvl;
}
int RDWaveData::startPos() const
{
return data_start_pos;
@ -627,9 +881,189 @@ void RDWaveData::setDaypartEndTime(const QTime &time)
}
unsigned RDWaveData::playCounter() const
{
return data_play_counter;
}
void RDWaveData::setPlayCounter(unsigned count)
{
data_play_counter=count;
}
RDSettings RDWaveData::audioSettings() const
{
return data_settings;
}
void RDWaveData::setAudioSettings(const RDSettings &settings)
{
data_settings=settings;
}
int RDWaveData::playGain() const
{
return data_play_gain;
}
void RDWaveData::setPlayGain(int lvl)
{
data_play_gain=lvl;
}
QString RDWaveData::dump() const
{
QString ret="";
//
// Cart-level attributes
//
ret+=QString().sprintf("cartNumber: %06u\n",cartNumber());
ret+="cartType: "+RDWaveData::cartTypeText(cartType())+"\n";
ret+="category: "+category()+"\n";
ret+="title: "+title()+"\n";
ret+="artist: "+artist()+"\n";
ret+="album: "+album()+"\n";
ret+="label: "+label()+"\n";
ret+="agency: "+agency()+"\n";
ret+="client: "+client()+"\n";
ret+="composer: "+composer()+"\n";
ret+="publisher: "+publisher()+"\n";
ret+="conductor: "+conductor()+"\n";
ret+="userDefined: "+userDefined()+"\n";
if(releaseYear()>0) {
ret+=QString().sprintf("year: %d\n",releaseYear());
}
else {
ret+="year:\n";
}
ret+="usageCode: "+RDWaveData::usageText(usageCode())+"\n";
ret+="forcedLength: "+RDGetTimeLength(forcedLength(),true,true)+"\n";
ret+="averageLength: "+RDGetTimeLength(averageLength(),true,true)+"\n";
ret+="lengthDeviation: "+RDGetTimeLength(lengthDeviation(),true,true)+"\n";
ret+=
"averageSegueLength: "+RDGetTimeLength(averageSegueLength(),true,true)+"\n";
ret+="averageHookLength: "+RDGetTimeLength(averageHookLength(),true,true)+"\n";
ret+=QString().sprintf("cutQuantity: %d\n",cutQuantity());
ret+=QString().sprintf("lastCutPlayed: %d\n",lastCutPlayed());
if(enforceLength()) {
ret+="enforceLength: true\n";
}
else {
ret+="enforceLength: false\n";
}
if(asyncronous()) {
ret+="asyncronous: true\n";
}
else {
ret+="asyncronous: false\n";
}
ret+="owner: "+owner()+"\n";
ret+="metadataDatetime: "+
metadataDatetime().toString("yyyy-MM-dd hh:mm:ss")+"\n";
//
// Cut-level attributes
//
ret+="cutName: "+cutName()+"\n";
ret+=QString().sprintf("cutNumber: %d\n",cutNumber());
ret+="description: "+description()+"\n";
ret+="outcue: "+outCue()+"\n";
if(evergreen()) {
ret+="evergreen: true\n";
}
else {
ret+="evergreen: false\n";
}
ret+="isrc: "+isrc()+"\n";
ret+="isci: "+isci()+"\n";
ret+=QString().sprintf("length: %d\n",length());
ret+="originator: "+originator()+"\n";
ret+="originationDate: "+originationDate().toString("yyyy-MM-dd")+"\n";
ret+="originationTime: "+originationTime().toString("hh:mm:ss")+"\n";
ret+="startDate: ";
if(startDate().isValid()) {
ret+=startDate().toString("yyyy-MM-dd");
}
ret+="\n";
ret+="startTime: ";
if(startDate().isValid()&&startTime().isValid()) {
ret+=startTime().toString("hh:mm:ss");
}
ret+="\n";
ret+="endDate: ";
if(endDate().isValid()) {
ret+=endDate().toString("yyyy-MM-dd");
}
ret+="\n";
ret+="endTime: ";
if(endDate().isValid()&&endTime().isValid()) {
ret+=endTime().toString("hh:mm:ss");
}
ret+="\n";
for(int i=1;i<8;i++) {
if(dayOfWeek(i)) {
ret+=QDate::longDayName(i)+": true\n";
}
else {
ret+=QDate::longDayName(i)+": false\n";
}
}
ret+="daypartStartTime: ";
if(daypartStartTime().isValid()&&(daypartStartTime()!=daypartEndTime())) {
ret+=daypartStartTime().toString("hh:mm:ss");
}
ret+="\n";
ret+="daypartEndTime: ";
if(daypartEndTime().isValid()&&(daypartStartTime()!=daypartEndTime())) {
ret+=daypartEndTime().toString("hh:mm:ss");
}
ret+="\n";
ret+="lastPlayDatetime: ";
if(lastPlayDatetime().isValid()) {
ret+=lastPlayDatetime().toString("yyyy-MM-dd hh:mm:ss");
}
ret+="\n";
ret+=QString().sprintf("weight: %d\n",weight());
ret+=QString().sprintf("playCounter: %d\n",playCounter());
ret+=QString().sprintf("audioSettings::format: %u\n",
audioSettings().format());
ret+=QString().sprintf("audioSettings::sampleRate: %u\n",
audioSettings().sampleRate());
ret+=QString().sprintf("audioSettings::bitRate: %u\n",
audioSettings().bitRate());
ret+=QString().sprintf("audioSettings::channels: %u\n",
audioSettings().channels());
ret+=QString().sprintf("playGain: %d\n",playGain());
ret+=QString().sprintf("startPos: %d\n",startPos());
ret+=QString().sprintf("endPos: %d\n",endPos());
ret+=QString().sprintf("segueStartPos: %d\n",segueStartPos());
ret+=QString().sprintf("segueEndPos: %d\n",segueEndPos());
ret+=QString().sprintf("segueGain: %d\n",segueGain());
ret+=QString().sprintf("introStartPos: %d\n",introStartPos());
ret+=QString().sprintf("introEndPos: %d\n",introEndPos());
ret+=QString().sprintf("hookStartPos: %d\n",hookStartPos());
ret+=QString().sprintf("hookEndPos: %d\n",hookEndPos());
ret+=QString().sprintf("fadeUpPos: %d\n",fadeUpPos());
ret+=QString().sprintf("fadeDownPos: %d\n",fadeDownPos());
ret+="\n";
return ret;
}
void RDWaveData::clear()
{
data_metadata_found=false;
data_cart_number=0;
data_cart_type=RDWaveData::AudioType;
data_cut_number=0;
data_cutname="";
data_title="";
data_artist="";
data_album="";
@ -640,7 +1074,7 @@ void RDWaveData::clear()
data_agency="";
data_composer="";
data_publisher="";
data_usage_code=0;
data_usage_code=RDWaveData::UsageFeature;
data_sched_codes.clear();
data_licensing_organization="";
data_copyright_notice="";
@ -657,11 +1091,33 @@ void RDWaveData::clear()
data_isci="";
data_mcn="";
data_out_cue="";
data_release_year=0;
data_end_type=RDWaveData::UnknownEnd;
data_length=0;
data_forced_length=-1;
data_average_length=-1;
data_length_deviation=0;
data_average_segue_length=0;
data_average_hook_length=0;
data_cut_quantity=0;
data_last_cut_played=0;
data_last_play_datetime=QDateTime();
data_enforce_length=false;
data_asyncronous=false;
data_owner="";
data_metadata_datetime=QDateTime();
for(int i=0;i<7;i++) {
data_day_of_week[i]=true;
}
data_weight=1;
data_evergreen=false;
data_intro_start_pos=-1;
data_intro_end_pos=-1;
data_segue_start_pos=-1;
data_segue_end_pos=-1;
data_segue_gain=-3000;
data_start_pos=-1;
data_end_pos=-1;
data_hook_start_pos=-1;
@ -678,4 +1134,83 @@ void RDWaveData::clear()
data_end_time=QTime();
data_daypart_start_time=QTime();
data_daypart_end_time=QTime();
data_play_counter=0;
data_play_gain=0;
}
QString RDWaveData::endTypeText(EndType type)
{
QString ret=QObject::tr("unknown");
switch(type) {
case UnknownEnd:
ret=QObject::tr("unknown");
break;
case ColdEnd:
ret=QObject::tr("cold");
break;
case FadeEnd:
ret=QObject::tr("fade");
break;
}
return ret;
}
QString RDWaveData::cartTypeText(CartType type)
{
QString ret=QObject::tr("unknown");
switch(type) {
case RDWaveData::AudioType:
ret="audio";
break;
case RDWaveData::MacroType:
ret="macro";
break;
}
return ret;
}
QString RDWaveData::usageText(UsageCode code)
{
QString ret=QObject::tr("unknown");
switch(code) {
case UsageFeature:
ret=QObject::tr("feature");
break;
case UsageOpen:
ret=QObject::tr("open");
break;
case UsageClose:
ret=QObject::tr("close");
break;
case UsageTheme:
ret=QObject::tr("theme");
break;
case UsageBackground:
ret=QObject::tr("background");
break;
case UsagePromo:
ret=QObject::tr("promo");
break;
case UsageLast:
break;
}
return ret;
}

View File

@ -25,13 +25,26 @@
#include <qstringlist.h>
#include <qdatetime.h>
#include <rdsettings.h>
class RDWaveData
{
public:
enum EndType {UnknownEnd='N',ColdEnd='C',FadeEnd='F'};
enum CartType {AudioType=0,MacroType=1};
enum UsageCode {UsageFeature=0,UsageOpen=1,UsageClose=2,UsageTheme=3,
UsageBackground=4,UsagePromo=5,UsageLast=6};
RDWaveData();
bool metadataFound() const;
void setMetadataFound(bool state);
unsigned cartNumber() const;
void setCartNumber(unsigned cartnum);
int cutNumber() const;
void setCutNumber(int cutnum);
QString cutName() const;
void setCutName(const QString &str);
CartType cartType() const;
void setCartType(CartType type);
QString title() const;
void setTitle(const QString &str);
QString artist() const;
@ -52,8 +65,8 @@ class RDWaveData
void setComposer(const QString &str);
QString publisher() const;
void setPublisher(const QString &str);
int usageCode() const;
void setUsageCode(int code);
UsageCode usageCode() const;
void setUsageCode(UsageCode code);
QStringList schedCodes() const;
void setSchedCodes(const QStringList &codes);
QString licensingOrganization() const;
@ -90,6 +103,40 @@ class RDWaveData
void setOutCue(const QString &str);
RDWaveData::EndType endType() const;
void setEndType(RDWaveData::EndType type);
int forcedLength() const;
void setForcedLength(int msecs);
int averageLength() const;
void setAverageLength(int msecs);
int lengthDeviation() const;
void setLengthDeviation(int msecs);
int averageSegueLength() const;
void setAverageSegueLength(int msecs);
int averageHookLength() const;
void setAverageHookLength(int msecs);
int cutQuantity() const;
void setCutQuantity(int n);
int lastCutPlayed() const;
void setLastCutPlayed(int cutnum);
QDateTime lastPlayDatetime() const;
void setLastPlayDatetime(const QDateTime &dt);
int length() const;
void setLength(int msecs);
bool enforceLength() const;
void setEnforceLength(bool state);
bool asyncronous() const;
void setAsyncronous(bool state);
QString owner() const;
void setOwner(const QString &str);
QDateTime metadataDatetime() const;
void setMetadataDatetime(const QDateTime &dt);
bool dayOfWeek(int dow) const;
void setDayOfWeek(int dow,bool state);
int weight() const;
void setWeight(int weight);
bool evergreen() const;
void setEvergreen(bool state);
int introStartPos() const;
void setIntroStartPos(int msec);
int introEndPos() const;
@ -98,6 +145,8 @@ class RDWaveData
void setSegueStartPos(int msec);
int segueEndPos() const;
void setSegueEndPos(int msec);
int segueGain() const;
void setSegueGain(int lvl);
int startPos() const;
void setStartPos(int msec);
int endPos() const;
@ -130,10 +179,24 @@ class RDWaveData
void setDaypartStartTime(const QTime &time);
QTime daypartEndTime() const;
void setDaypartEndTime(const QTime &time);
unsigned playCounter() const;
void setPlayCounter(unsigned count);
RDSettings audioSettings() const;
void setAudioSettings(const RDSettings &settings);
int playGain() const;
void setPlayGain(int lvl);
QString dump() const;
void clear();
static QString endTypeText(EndType type);
static QString cartTypeText(CartType type);
static QString usageText(UsageCode code);
private:
bool data_metadata_found;
unsigned data_cart_number;
CartType data_cart_type;
int data_cut_number;
QString data_cutname;
QString data_title;
QString data_artist;
QString data_album;
@ -144,7 +207,7 @@ class RDWaveData
QString data_agency;
QString data_composer;
QString data_publisher;
int data_usage_code;
UsageCode data_usage_code;
QStringList data_sched_codes;
QString data_licensing_organization;
QString data_copyright_notice;
@ -162,11 +225,30 @@ class RDWaveData
QString data_isci;
QString data_mcn;
QString data_out_cue;
RDWaveData::EndType data_end_type;
EndType data_end_type;
int data_length;
int data_forced_length;
int data_average_length;
int data_length_deviation;
int data_average_segue_length;
int data_average_hook_length;
int data_cut_quantity;
int data_last_cut_played;
QDateTime data_last_play_datetime;
bool data_enforce_length;
bool data_asyncronous;
QString data_owner;
QDateTime data_metadata_datetime;
bool data_evergreen;
bool data_day_of_week[7];
int data_weight;
int data_intro_start_pos;
int data_intro_end_pos;
int data_segue_start_pos;
int data_segue_end_pos;
int data_segue_gain;
int data_start_pos;
int data_end_pos;
int data_hook_start_pos;
@ -188,6 +270,9 @@ class RDWaveData
QTime data_end_time;
QTime data_daypart_start_time;
QTime data_daypart_end_time;
unsigned data_play_counter;
RDSettings data_settings;
int data_play_gain;
};

View File

@ -254,7 +254,7 @@ void RDWaveDataDialog::okData()
else {
wave_data->setReleaseYear(wave_year_edit->text().toInt());
}
wave_data->setUsageCode(wave_usage_box->currentItem());
wave_data->setUsageCode((RDWaveData::UsageCode)wave_usage_box->currentItem());
wave_data->setTmciSongId(wave_songid_edit->text());
wave_data->setBeatsPerMinute(wave_bpm_spin->value());
wave_data->setAlbum(wave_album_edit->text());

View File

@ -33,6 +33,7 @@ noinst_PROGRAMS = audio_convert_test\
audio_import_test\
audio_peaks_test\
datedecode_test\
rdxml_parse_test\
reserve_carts_test\
sas_switch_torture\
sas_torture\
@ -56,6 +57,9 @@ audio_peaks_test_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
dist_datedecode_test_SOURCES = datedecode_test.cpp datedecode_test.h
datedecode_test_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
dist_rdxml_parse_test_SOURCES = rdxml_parse_test.cpp rdxml_parse_test.h
rdxml_parse_test_LDADD = @LIB_RDLIBS@ @LIBVORBIS@
dist_reserve_carts_test_SOURCES = reserve_carts_test.cpp reserve_carts_test.h
reserve_carts_test_LDADD = @LIB_RDLIBS@ @LIBVORBIS@

108
tests/rdxml_parse_test.cpp Normal file
View File

@ -0,0 +1,108 @@
// rdxml_parse_test.cpp
//
// Test the Rivendell RDXML parser routines.
//
// (C) Copyright 2016 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <qapplication.h>
#include <qfile.h>
#include <rdcart.h>
#include <rdcmd_switch.h>
#include <rdwavedata.h>
#include "rdxml_parse_test.h"
MainObject::MainObject(QObject *parent)
:QObject(parent)
{
QString filename="";
QFile *file=NULL;
QString line;
QString xml="";
//
// Read Command Options
//
RDCmdSwitch *cmd=
new RDCmdSwitch(qApp->argc(),qApp->argv(),"rdxml_parse_test",
RDXML_PARSE_TEST_USAGE);
for(unsigned i=0;i<cmd->keys();i++) {
if(cmd->key(i)=="--filename") {
filename=cmd->value(i);
cmd->setProcessed(i,true);
}
if(!cmd->processed(i)) {
fprintf(stderr,"rdxml_parse_test: unknown option \"%s\"\n",
(const char *)cmd->value(i));
exit(256);
}
}
if(filename.isEmpty()) {
fprintf(stderr,"rdxml_parse_test: --filename= must be specified\n");
exit(256);
}
//
// Read File
//
file=new QFile(filename);
if(!file->open(IO_ReadOnly)) {
fprintf(stderr,"rdxml_parse_test: unable to open \"%s\"\n",
(const char *)filename);
exit(256);
}
while(file->readLine(line,1024)>=0) {
xml+=line;
}
file->close();
//
// Parse
//
std::vector<RDWaveData> data;
int n=RDCart::readXml(&data,xml);
if(n<1) {
fprintf(stderr,"rdxml_parse_test: no data found\n");
exit(256);
}
printf("*** CART DATA ***\n");
printf("%s\n",(const char *)data[0].dump());
printf("\n");
for(unsigned i=1;i<data.size();i++) {
printf("*** CUT %u DATA ***\n",i);
printf("%s\n",(const char *)data[i].dump());
printf("\n");
}
exit(0);
}
int main(int argc,char *argv[])
{
QApplication a(argc,argv,false);
new MainObject();
return a.exec();
}

35
tests/rdxml_parse_test.h Normal file
View File

@ -0,0 +1,35 @@
// rdxml_parse_test.h
//
// Test the Rivendell RDXML parser routines.
//
// (C) Copyright 2016 Fred Gleason <fredg@paravelsystems.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#ifndef RDXML_PARSE_TEST_H
#define RDXML_PARSE_TEST_H
#include <qobject.h>
#define RDXML_PARSE_TEST_USAGE "--filename=<input-file>\n\n"
class MainObject : public QObject
{
public:
MainObject(QObject *parent=0);
};
#endif // RDXML_PARSE_TEST_H