chiark / gitweb /
New queue_pad option defines how big to keep the queue (by adding
authorrjk@greenend.org.uk <>
Tue, 10 Jul 2007 23:08:49 +0000 (00:08 +0100)
committerrjk@greenend.org.uk <>
Tue, 10 Jul 2007 23:08:49 +0000 (00:08 +0100)
random tracks).  User-chosen tracks are added before the final block
of random tracks.

Also updated CHANGES a bit.

doc/disorder_config.5.in
lib/configuration.c
lib/configuration.h
lib/queue.c
server/play.c

index 8a03b4985db14317cad3ac6edf4d26abb9550904..3ddeb4702224467a56722e345802e1f0235ff52f 100644 (file)
@@ -296,6 +296,10 @@ If multiple player commands match a track then the first match is used.
 The interval at which the preferences log file will be synchronised.  Defaults
 to 3600, i.e. one hour.
 .TP
+.B queue_pad \fICOUNT\fR
+The target size of the queue.  If random play is enabled then randomly picked
+tracks will be added until the queue is at least this big.
+.TP
 .B sample_format \fIBITS\fB/\fIRATE\fB/\fICHANNELS
 Describes the sample format expected by the \fBspeaker_command\fR (below).  The
 components of the format specification are as follows:
index 0282630d9ed7133c291ea2d6e89286ed3776c725..845c32a0c7266662a62ba52a290465dfd6671520 100644 (file)
@@ -749,6 +749,7 @@ static const struct conf conf[] = {
   { C(player),           &type_stringlist_accum, validate_player },
   { C(plugins),          &type_string_accum,     validate_isdir },
   { C(prefsync),         &type_integer,          validate_positive },
+  { C(queue_pad),        &type_integer,          validate_positive },
   { C(refresh),          &type_integer,          validate_positive },
   { C2(restrict, restrictions),         &type_restrict,         validate_any },
   { C(sample_format),    &type_sample_format,    validate_sample_format },
@@ -873,6 +874,7 @@ static struct config *config_default(void) {
   c->sample_format.rate = 44100;
   c->sample_format.channels = 2;
   c->sample_format.byte_format = AO_FMT_NATIVE;
+  c->queue_pad = 10;
   return c;
 }
 
index dbdb65b651d45cbb23f4be70dfd286df56826f5d..c3049215e79aaeadb15964c0e9446f4a139b7c28 100644 (file)
@@ -112,6 +112,8 @@ struct config {
   const char *url;                     /* canonical URL */
   long refresh;                                /* maximum refresh period */
   unsigned restrictions;               /* restrictions */
+  long queue_pad;                      /* how far to pad queue with
+                                        * random tracks */
 #define RESTRICT_SCRATCH 1
 #define RESTRICT_REMOVE 2
 #define RESTRICT_MOVE 4
index 1e5c1d4d38b48923720a799d8877e3ba5eab696d..940fde38abd4896af929e214aa24e41cc99257ec 100644 (file)
@@ -353,7 +353,7 @@ void queue_id(struct queue_entry *q) {
 
 struct queue_entry *queue_add(const char *track, const char *submitter,
                              int where) {
-  struct queue_entry *q;
+  struct queue_entry *q, *beforeme;
 
   q = xmalloc(sizeof *q);
   q->track = xstrdup(track);
@@ -369,11 +369,13 @@ struct queue_entry *queue_add(const char *track, const char *submitter,
     l_add(qhead.prev, q);
     break;
   case WHERE_BEFORE_RANDOM:
-    if(qhead.prev == &qhead            /* Empty queue. */
-       || qhead.prev->state != playing_random) /* No random track */
-      l_add(qhead.prev, q);
-    else
-      l_add(qhead.prev->prev, q);      /* Before random track. */
+    /* We want to find the point in the queue before the block of random tracks
+     * at the end. */
+    beforeme = &qhead;
+    while(beforeme->prev != &qhead
+         && beforeme->prev->state == playing_random)
+      beforeme = beforeme->prev;
+    l_add(beforeme->prev, q);
     break;
   }
   /* submitter will be a null pointer for a scratch */
index 3b18891a4b566ae57465e428399750f110121f79..e8df3e8407a039d61f55b5d8aedb9d020679bd65 100644 (file)
@@ -458,24 +458,31 @@ void abandon(ev_source attribute((unused)) *ev,
 int add_random_track(void) {
   struct queue_entry *q;
   const char *p;
+  long qlen = 0;
+  int rc = 0;
 
   /* If random play is not enabled then do nothing. */
   if(shutting_down || !random_is_enabled())
     return 0;
-  /* If there is already a random track, do nothing. */
+  /* Count how big the queue is */
   for(q = qhead.next; q != &qhead; q = q->next)
-    if(q->state == playing_random)
-      return 0;
-  /* Try to pick a random track */
-  if(!(p = trackdb_random(16)))
-    return -1;
-  /* Add it to the end of the queue. */
-  q = queue_add(p, 0, WHERE_END);
-  q->state = playing_random;
+    ++qlen;
+  /* Add random tracks until the queue is at the right size */
+  while(qlen < config->queue_pad) {
+    /* Try to pick a random track */
+    if(!(p = trackdb_random(16))) {
+      rc = -1;
+      break;
+    }
+    /* Add it to the end of the queue. */
+    q = queue_add(p, 0, WHERE_END);
+    q->state = playing_random;
+    D(("picked %p (%s) at random", (void *)q, q->track));
+    ++qlen;
+  }
   /* Commit the queue */
   queue_write();
-  D(("picked %p (%s) at random", (void *)q, q->track));
-  return 0;
+  return rc;
 }
 
 /* try to play a track */