summaryrefslogtreecommitdiff
path: root/apps/playlist.c
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2003-01-09 00:55:00 +0000
committerBjörn Stenberg <bjorn@haxx.se>2003-01-09 00:55:00 +0000
commitc78e1b07fead2b5861fb6fc4c9ba130660fb323f (patch)
tree267406ed9e1e3c68238f688934d2088a1fa7c8e3 /apps/playlist.c
parent0e342181c3f96890506aa8720ac2d680b97c12e4 (diff)
The much-anticipated queue patch by Hardeep Sidhu. Queue a file by holding down PLAY on it while playing other music.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3040 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/playlist.c')
-rw-r--r--apps/playlist.c340
1 files changed, 286 insertions, 54 deletions
diff --git a/apps/playlist.c b/apps/playlist.c
index 38eca09fc9..0a99cb91f4 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include "playlist.h"
-#include <file.h>
+#include "file.h"
#include "sprintf.h"
#include "debug.h"
#include "mpeg.h"
@@ -39,6 +39,7 @@
static struct playlist_info playlist;
+#define QUEUE_FILE ROCKBOX_DIR "/.queue_file"
#define PLAYLIST_BUFFER_SIZE (AVERAGE_FILENAME_LENGTH*MAX_FILES_IN_DIR)
static unsigned char playlist_buffer[PLAYLIST_BUFFER_SIZE];
@@ -46,64 +47,153 @@ static int playlist_end_pos = 0;
static char now_playing[MAX_PATH+1];
-void playlist_clear(void)
+/*
+ * remove any files and indices associated with the playlist
+ */
+static void empty_playlist(bool queue_resume)
{
- playlist_end_pos = 0;
- playlist_buffer[0] = 0;
+ int fd;
+
+ playlist.filename[0] = '\0';
+ playlist.index = 0;
+ playlist.queue_index = 0;
+ playlist.last_queue_index = 0;
+ playlist.amount = 0;
+ playlist.num_queued = 0;
+ playlist.start_queue = 0;
+
+ if (!queue_resume)
+ {
+ /* start with fresh queue file when starting new playlist */
+ remove(QUEUE_FILE);
+ fd = creat(QUEUE_FILE, 0);
+ if (fd > 0)
+ close(fd);
+ }
}
-int playlist_add(char *filename)
+/* update queue list after resume */
+static void add_indices_to_queuelist(int seek)
{
- int len = strlen(filename);
+ int nread;
+ int fd = -1;
+ int i = seek;
+ int count = 0;
+ bool store_index;
+ char buf[MAX_PATH];
- if(len+2 > PLAYLIST_BUFFER_SIZE - playlist_end_pos)
- return -1;
+ unsigned char *p = buf;
- strcpy(&playlist_buffer[playlist_end_pos], filename);
- playlist_end_pos += len;
- playlist_buffer[playlist_end_pos++] = '\n';
- playlist_buffer[playlist_end_pos] = '\0';
- return 0;
+ fd = open(QUEUE_FILE, O_RDONLY);
+ if(fd < 0)
+ return;
+
+ nread = lseek(fd, seek, SEEK_SET);
+ if (nread < 0)
+ return;
+
+ store_index = true;
+
+ while(1)
+ {
+ nread = read(fd, buf, MAX_PATH);
+ if(nread <= 0)
+ break;
+
+ p = buf;
+
+ for(count=0; count < nread; count++,p++) {
+ if(*p == '\n')
+ store_index = true;
+ else if(store_index)
+ {
+ store_index = false;
+
+ playlist.queue_indices[playlist.last_queue_index] = i+count;
+ playlist.last_queue_index =
+ (playlist.last_queue_index + 1) % MAX_QUEUED_FILES;
+ playlist.num_queued++;
+ }
+ }
+
+ i += count;
+ }
}
-static int get_next_index(int steps)
+static int get_next_index(int steps, bool *queue)
{
int current_index = playlist.index;
int next_index = -1;
+ if (global_settings.repeat_mode == REPEAT_ONE)
+ steps = 0;
+ else if (steps >= 0)
+ steps -= playlist.start_queue;
+
+ if (steps >= 0 && playlist.num_queued > 0 &&
+ playlist.num_queued - steps > 0)
+ *queue = true;
+ else
+ {
+ *queue = false;
+ if (playlist.num_queued)
+ {
+ if (steps >= 0)
+ steps -= (playlist.num_queued - 1);
+ else if (!playlist.start_queue)
+ steps += 1;
+ }
+ }
+
switch (global_settings.repeat_mode)
{
case REPEAT_OFF:
- if (current_index < playlist.first_index)
- current_index += playlist.amount;
- current_index -= playlist.first_index;
-
- next_index = current_index+steps;
- if ((next_index < 0) || (next_index >= playlist.amount))
- next_index = -1;
+ if (*queue)
+ next_index = (playlist.queue_index+steps) % MAX_QUEUED_FILES;
else
- next_index = (next_index+playlist.first_index)%playlist.amount;
+ {
+ if (current_index < playlist.first_index)
+ current_index += playlist.amount;
+ current_index -= playlist.first_index;
+
+ next_index = current_index+steps;
+ if ((next_index < 0) || (next_index >= playlist.amount))
+ next_index = -1;
+ else
+ next_index = (next_index+playlist.first_index) %
+ playlist.amount;
+ }
break;
case REPEAT_ONE:
- next_index = current_index;
+ if (*queue && !playlist.start_queue)
+ next_index = playlist.queue_index;
+ else
+ {
+ next_index = current_index;
+ *queue = false;
+ }
break;
case REPEAT_ALL:
default:
- next_index = (current_index+steps) % playlist.amount;
- while (next_index < 0)
- next_index += playlist.amount;
+ if (*queue)
+ next_index = (playlist.queue_index+steps) % MAX_QUEUED_FILES;
+ else
+ {
+ next_index = (current_index+steps) % playlist.amount;
+ while (next_index < 0)
+ next_index += playlist.amount;
+ }
break;
}
return next_index;
}
-/* the mpeg thread might ask us */
int playlist_amount(void)
{
- return playlist.amount;
+ return playlist.amount + playlist.num_queued;
}
int playlist_first_index(void)
@@ -111,6 +201,36 @@ int playlist_first_index(void)
return playlist.first_index;
}
+int playlist_get_resume_info(int *resume_index, int *queue_resume,
+ int *queue_resume_index)
+{
+ int result = 0;
+
+ *resume_index = playlist.index;
+
+ if (playlist.num_queued > 0)
+ {
+ if (global_settings.save_queue_resume)
+ {
+ *queue_resume_index =
+ playlist.queue_indices[playlist.queue_index];
+ if (playlist.start_queue)
+ *queue_resume = QUEUE_BEGIN_PLAYLIST;
+ else
+ *queue_resume = QUEUE_BEGIN_QUEUE;
+ }
+ else if (!playlist.start_queue)
+ {
+ *queue_resume = QUEUE_OFF;
+ result = -1;
+ }
+ }
+ else
+ *queue_resume = QUEUE_OFF;
+
+ return result;
+}
+
char *playlist_name(char *buf, int buf_size)
{
char *sep;
@@ -128,11 +248,101 @@ char *playlist_name(char *buf, int buf_size)
return buf;
}
+void playlist_clear(void)
+{
+ playlist_end_pos = 0;
+ playlist_buffer[0] = 0;
+}
+
+int playlist_add(char *filename)
+{
+ int len = strlen(filename);
+
+ if(len+2 > PLAYLIST_BUFFER_SIZE - playlist_end_pos)
+ return -1;
+
+ strcpy(&playlist_buffer[playlist_end_pos], filename);
+ playlist_end_pos += len;
+ playlist_buffer[playlist_end_pos++] = '\n';
+ playlist_buffer[playlist_end_pos] = '\0';
+ return 0;
+}
+
+/* Add track to queue file */
+int queue_add(char *filename)
+{
+ int fd, seek, result;
+ int len = strlen(filename);
+
+ if(playlist.num_queued >= MAX_QUEUED_FILES)
+ return -1;
+
+ fd = open(QUEUE_FILE, O_WRONLY);
+ if (fd < 0)
+ return -1;
+
+ seek = lseek(fd, 0, SEEK_END);
+ if (seek < 0)
+ {
+ close(fd);
+ return -1;
+ }
+
+ filename[len] = '\n';
+ result = write(fd, filename, len+1);
+ if (result < 0)
+ {
+ close(fd);
+ return -1;
+ }
+ filename[len] = '\0';
+
+ close(fd);
+
+ if (playlist.num_queued <= 0)
+ playlist.start_queue = 1;
+
+ playlist.queue_indices[playlist.last_queue_index] = seek;
+ playlist.last_queue_index =
+ (playlist.last_queue_index + 1) % MAX_QUEUED_FILES;
+ playlist.num_queued++;
+
+ mpeg_flush_and_reload_tracks();
+
+ return playlist.num_queued;
+}
+
int playlist_next(int steps)
{
- playlist.index = get_next_index(steps);
+ bool queue;
+ int index = get_next_index(steps, &queue);
- return playlist.index;
+ if (queue)
+ {
+ int queue_diff = index - playlist.queue_index;
+ if (queue_diff < 0)
+ queue_diff += MAX_QUEUED_FILES;
+
+ playlist.num_queued -= queue_diff;
+ playlist.queue_index = index;
+ playlist.start_queue = 0;
+ }
+ else
+ {
+ playlist.index = index;
+ if (playlist.num_queued > 0 && !playlist.start_queue)
+ {
+ if (steps >= 0)
+ {
+ playlist.queue_index = playlist.last_queue_index;
+ playlist.num_queued = 0;
+ }
+ else
+ playlist.start_queue = true;
+ }
+ }
+
+ return index;
}
char* playlist_peek(int steps)
@@ -145,24 +355,19 @@ char* playlist_peek(int steps)
char dir_buf[MAX_PATH+1];
char *dir_end;
int index;
+ bool queue;
- index = get_next_index(steps);
- if (index >= 0)
- seek = playlist.indices[index];
- else
+ index = get_next_index(steps, &queue);
+ if (index < 0)
return NULL;
- if(playlist.in_ram)
+ if (queue)
{
- buf = playlist_buffer + seek;
- max = playlist_end_pos - seek;
- }
- else
- {
- fd = open(playlist.filename, O_RDONLY);
+ seek = playlist.queue_indices[index];
+ fd = open(QUEUE_FILE, O_RDONLY);
if(-1 != fd)
{
- buf = playlist_buffer;
+ buf = dir_buf;
lseek(fd, seek, SEEK_SET);
max = read(fd, buf, MAX_PATH);
close(fd);
@@ -170,6 +375,29 @@ char* playlist_peek(int steps)
else
return NULL;
}
+ else
+ {
+ seek = playlist.indices[index];
+
+ if(playlist.in_ram)
+ {
+ buf = playlist_buffer + seek;
+ max = playlist_end_pos - seek;
+ }
+ else
+ {
+ fd = open(playlist.filename, O_RDONLY);
+ if(-1 != fd)
+ {
+ buf = playlist_buffer;
+ lseek(fd, seek, SEEK_SET);
+ max = read(fd, buf, MAX_PATH);
+ close(fd);
+ }
+ else
+ return NULL;
+ }
+ }
/* Zero-terminate the file name */
seek=0;
@@ -260,11 +488,13 @@ int play_list(char *dir, /* "current directory" */
playlist AFTER the shuffle */
int start_offset, /* offset in the file */
int random_seed, /* used for shuffling */
- int first_index ) /* first index of playlist */
+ int first_index, /* first index of playlist */
+ int queue_resume, /* resume queue list? */
+ int queue_resume_index ) /* queue list seek pos */
{
char *sep="";
int dirlen;
- empty_playlist();
+ empty_playlist(queue_resume);
playlist.index = start_index;
playlist.first_index = first_index;
@@ -343,6 +573,18 @@ int play_list(char *dir, /* "current directory" */
}
}
+ /* update the queue indices */
+ if (queue_resume)
+ {
+ add_indices_to_queuelist(queue_resume_index);
+
+ if (queue_resume == QUEUE_BEGIN_PLAYLIST)
+ {
+ playlist.start_queue = 1;
+ playlist.index++; /* so we begin at the correct track */
+ }
+ }
+
if(!playlist.in_ram) {
lcd_puts(0,0,str(LANG_PLAYLIST_PLAY));
status_draw();
@@ -355,16 +597,6 @@ int play_list(char *dir, /* "current directory" */
}
/*
- * remove any filename and indices associated with the playlist
- */
-void empty_playlist(void)
-{
- playlist.filename[0] = '\0';
- playlist.index = 0;
- playlist.amount = 0;
-}
-
-/*
* calculate track offsets within a playlist file
*/
void add_indices_to_playlist(void)