Add option to specify number of play queue tracks for dynamic playlists.

Issue #1048
This commit is contained in:
Craig Drummond
2017-08-12 20:05:15 +01:00
committed by Craig Drummond
parent d632c0d675
commit eca12746b0
6 changed files with 52 additions and 12 deletions

View File

@@ -1,5 +1,6 @@
2.2.0
-----
1. Add option to specify number of play queue tracks for dynamic playlists.
2.1.0
-----

View File

@@ -39,8 +39,10 @@ my $dynamicIsActive =1;
my $currentStatus ="IDLE";
$testMode=0;
$PLAY_QUEUE_DESIRED_LENGTH=10;
$PLAY_QUEUE_CURRENT_POS=5;
$MIN_PLAY_QUEUE_DESIRED_LENGTH=10;
$MAX_PLAY_QUEUE_DESIRED_LENGTH=500;
$DEFAULT_PLAY_QUEUE_DESIRED_LENGTH=10;
$playQueueDesiredLength=$DEFAULT_PLAY_QUEUE_DESIRED_LENGTH;
my $mpdHost : shared = "localhost";
my $mpdPort : shared = "6600";
@@ -416,6 +418,7 @@ sub readRules() {
$ratingTo=0;
$minDuration=0;
$maxDuration=0;
$playQueueDesiredLength=$DEFAULT_PLAY_QUEUE_DESIRED_LENGTH;
close($fileHandle);
foreach my $line (@lines) {
if (! ($line=~ m/^(#)/)) {
@@ -459,6 +462,13 @@ sub readRules() {
$maxDuration=$tmp;
}
}
} elsif ($key=~ m/^(NumTracks)/) {
if ($val >= $MIN_PLAY_QUEUE_DESIRED_LENGTH && $val <= $MAX_PLAY_QUEUE_DESIRED_LENGTH) {
$playQueueDesiredLength=$val;
if ($playQueueDesiredLength % 2 > 0) {
$playQueueDesiredLength += 1;
}
}
} else {
if ($key eq "Date") {
my @dateVals = split("-", $val);
@@ -891,8 +901,9 @@ sub populatePlayQueue() {
$playQueueLength--;
}
# trim playlist start so that current becomes <=$PLAY_QUEUE_CURRENT_POS
for (my $i=0; $i < $playQueueCurrentTrackPos - ($PLAY_QUEUE_CURRENT_POS-1); $i++) {
# trim playlist start so that current becomes <=$playQueueDesiredLength/2
my $wantCurrentPos = $playQueueDesiredLength/2;
for (my $i=0; $i < $playQueueCurrentTrackPos - ($wantCurrentPos-1); $i++) {
&sendCommand("delete 0");
$playQueueLength--;
}
@@ -906,7 +917,7 @@ sub populatePlayQueue() {
# fill up playlist to 10 random tunes
my $failues=0;
my $added=0;
while ($playQueueLength < $PLAY_QUEUE_DESIRED_LENGTH && $numMpdSongs>0) {
while ($playQueueLength < $playQueueDesiredLength && $numMpdSongs>0) {
my $pos=int(rand($numMpdSongs));
my $origFile=${mpdSongs[$pos]};
my $file=$origFile;
@@ -927,7 +938,7 @@ sub populatePlayQueue() {
}
}
# If we are not currently playing and we filled playqueue - then play first!
if ($numMpdSongs>0 && $isPlaying==0 && $added==$PLAY_QUEUE_DESIRED_LENGTH) {
if ($numMpdSongs>0 && $isPlaying==0 && $added==$playQueueDesiredLength) {
&sendCommand("play 0")
}
}

View File

@@ -135,6 +135,7 @@ const QString Dynamic::constGenreKey=QLatin1String("Genre");
const QString Dynamic::constDateKey=QLatin1String("Date");
const QString Dynamic::constRatingKey=QLatin1String("Rating");
const QString Dynamic::constDurationKey=QLatin1String("Duration");
const QString Dynamic::constNumTracksKey=QLatin1String("NumTracks");
const QString Dynamic::constFileKey=QLatin1String("File");
const QString Dynamic::constExactKey=QLatin1String("Exact");
const QString Dynamic::constExcludeKey=QLatin1String("Exclude");
@@ -280,11 +281,14 @@ bool Dynamic::save(const Entry &e)
QString string;
QTextStream str(&string);
if (e.numTracks > 10 && e.numTracks <= 500) {
str << constNumTracksKey << constKeyValSep << e.numTracks << '\n';
}
if (e.ratingFrom!=0 || e.ratingTo!=0) {
str << constRatingKey << constKeyValSep << e.ratingFrom << constRangeSep << e.ratingTo<< '\n';
str << constRatingKey << constKeyValSep << e.ratingFrom << constRangeSep << e.ratingTo << '\n';
}
if (e.minDuration!=0 || e.maxDuration!=0) {
str << constDurationKey << constKeyValSep << e.minDuration << constRangeSep << e.maxDuration<< '\n';
str << constDurationKey << constKeyValSep << e.minDuration << constRangeSep << e.maxDuration << '\n';
}
foreach (const Rule &rule, e.rules) {
if (!rule.isEmpty()) {

View File

@@ -57,7 +57,7 @@ public:
typedef QMap<QString, QString> Rule;
struct Entry {
Entry(const QString &n=QString()) : name(n), ratingFrom(0), ratingTo(0), minDuration(0), maxDuration(0) { }
Entry(const QString &n=QString()) : name(n), ratingFrom(0), ratingTo(0), minDuration(0), maxDuration(0), numTracks(10) { }
bool operator==(const Entry &o) const { return name==o.name; }
bool haveRating() const { return ratingFrom>=0 && ratingTo>0; }
QString name;
@@ -66,6 +66,7 @@ public:
int ratingTo;
int minDuration;
int maxDuration;
int numTracks;
};
static Dynamic * self();
@@ -82,6 +83,7 @@ public:
static const QString constDateKey;
static const QString constRatingKey;
static const QString constDurationKey;
static const QString constNumTracksKey;
static const QString constFileKey;
static const QString constExactKey;
static const QString constExcludeKey;

View File

@@ -195,9 +195,29 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labela">
<property name="text">
<string>Number of songs in play queue:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="numTracks">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>500</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="UrlLabel" name="aboutLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
@@ -210,7 +230,7 @@
</property>
</widget>
</item>
<item row="6" column="1" colspan="2">
<item row="7" column="1" colspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>

View File

@@ -191,6 +191,7 @@ void DynamicRulesDialog::edit(const QString &name)
ratingTo->setValue(e.ratingTo);
minDuration->setValue(e.minDuration);
maxDuration->setValue(e.maxDuration);
numTracks->setValue(e.numTracks);
show();
}
@@ -304,7 +305,7 @@ void DynamicRulesDialog::showAbout()
"To have Cantata look for 'Songs by Wibble but not from album Abc', you would need the following: "
"<ul><li>Include AlbumArtist=Wibble</li><li>Exclude AlbumArtist=Wibble Album=Abc</li></ul>"
"After the set of usable songs has been created, Cantata will randomly select songs to "
"keep the play queue filled with 10 entries. If a range of ratings has been specified, then "
"keep the play queue filled with specified number of entries (10 by default). If a range of ratings has been specified, then "
"only songs with a rating within this range will be used. Likewise, if a duration has been set.</p>")
);
@@ -353,6 +354,7 @@ bool DynamicRulesDialog::save()
entry.minDuration=from;
entry.maxDuration=to;
}
entry.numTracks=numTracks->value();
for (int i=0; i<model->rowCount(); ++i) {
QStandardItem *itm=model->item(i);