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
This commit is contained in:
Björn Stenberg 2003-01-09 00:55:00 +00:00
parent 0e342181c3
commit c78e1b07fe
10 changed files with 492 additions and 129 deletions

View file

@ -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,6 +47,207 @@ static int playlist_end_pos = 0;
static char now_playing[MAX_PATH+1];
/*
* remove any files and indices associated with the playlist
*/
static void empty_playlist(bool queue_resume)
{
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);
}
}
/* update queue list after resume */
static void add_indices_to_queuelist(int seek)
{
int nread;
int fd = -1;
int i = seek;
int count = 0;
bool store_index;
char buf[MAX_PATH];
unsigned char *p = buf;
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, 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 (*queue)
next_index = (playlist.queue_index+steps) % MAX_QUEUED_FILES;
else
{
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:
if (*queue && !playlist.start_queue)
next_index = playlist.queue_index;
else
{
next_index = current_index;
*queue = false;
}
break;
case REPEAT_ALL:
default:
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;
}
int playlist_amount(void)
{
return playlist.amount + playlist.num_queued;
}
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;
snprintf(buf, buf_size, "%s", playlist.filename+playlist.dirlen);
if (0 == buf[0])
return NULL;
/* Remove extension */
sep = strrchr(buf, '.');
if (NULL != sep)
*sep = 0;
return buf;
}
void playlist_clear(void)
{
playlist_end_pos = 0;
@ -66,73 +268,81 @@ int playlist_add(char *filename)
return 0;
}
static int get_next_index(int steps)
/* Add track to queue file */
int queue_add(char *filename)
{
int current_index = playlist.index;
int next_index = -1;
int fd, seek, result;
int len = strlen(filename);
switch (global_settings.repeat_mode)
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)
{
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;
else
next_index = (next_index+playlist.first_index)%playlist.amount;
break;
case REPEAT_ONE:
next_index = current_index;
break;
case REPEAT_ALL:
default:
next_index = (current_index+steps) % playlist.amount;
while (next_index < 0)
next_index += playlist.amount;
break;
close(fd);
return -1;
}
return next_index;
}
filename[len] = '\n';
result = write(fd, filename, len+1);
if (result < 0)
{
close(fd);
return -1;
}
filename[len] = '\0';
/* the mpeg thread might ask us */
int playlist_amount(void)
{
return playlist.amount;
}
close(fd);
int playlist_first_index(void)
{
return playlist.first_index;
}
if (playlist.num_queued <= 0)
playlist.start_queue = 1;
char *playlist_name(char *buf, int buf_size)
{
char *sep;
playlist.queue_indices[playlist.last_queue_index] = seek;
playlist.last_queue_index =
(playlist.last_queue_index + 1) % MAX_QUEUED_FILES;
playlist.num_queued++;
snprintf(buf, buf_size, "%s", playlist.filename+playlist.dirlen);
mpeg_flush_and_reload_tracks();
if (0 == buf[0])
return NULL;
/* Remove extension */
sep = strrchr(buf, '.');
if (NULL != sep)
*sep = 0;
return buf;
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();
@ -354,16 +596,6 @@ int play_list(char *dir, /* "current directory" */
return playlist.index;
}
/*
* 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
*/