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

@ -23,5 +23,6 @@
#define AVERAGE_FILENAME_LENGTH 40 #define AVERAGE_FILENAME_LENGTH 40
#define MAX_DIR_LEVELS 10 #define MAX_DIR_LEVELS 10
#define MAX_PLAYLIST_SIZE 10000 #define MAX_PLAYLIST_SIZE 10000
#define MAX_QUEUED_FILES 100
#endif #endif

View file

@ -1221,3 +1221,18 @@ id: LANG_BATTERY_CAPACITY
desc: in settings_menu desc: in settings_menu
eng: "Battery Capacity" eng: "Battery Capacity"
new: new:
id: LANG_QUEUE_QUEUED
desc: queued track name %s
eng: "Queued: %s"
new:
id: LANG_QUEUE_TOTAL
desc: number of queued tracks %d
eng: "Total queued: %d"
new:
id: LANG_QUEUE_FULL
desc: queue buffer full
eng: "Queue buffer full"
new:

View file

@ -21,7 +21,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "playlist.h" #include "playlist.h"
#include <file.h> #include "file.h"
#include "sprintf.h" #include "sprintf.h"
#include "debug.h" #include "debug.h"
#include "mpeg.h" #include "mpeg.h"
@ -39,6 +39,7 @@
static struct playlist_info playlist; static struct playlist_info playlist;
#define QUEUE_FILE ROCKBOX_DIR "/.queue_file"
#define PLAYLIST_BUFFER_SIZE (AVERAGE_FILENAME_LENGTH*MAX_FILES_IN_DIR) #define PLAYLIST_BUFFER_SIZE (AVERAGE_FILENAME_LENGTH*MAX_FILES_IN_DIR)
static unsigned char playlist_buffer[PLAYLIST_BUFFER_SIZE]; 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]; 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) void playlist_clear(void)
{ {
playlist_end_pos = 0; playlist_end_pos = 0;
@ -66,73 +268,81 @@ int playlist_add(char *filename)
return 0; 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 fd, seek, result;
int next_index = -1; 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: close(fd);
if (current_index < playlist.first_index) return -1;
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;
} }
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 */ close(fd);
int playlist_amount(void)
{
return playlist.amount;
}
int playlist_first_index(void) if (playlist.num_queued <= 0)
{ playlist.start_queue = 1;
return playlist.first_index;
}
char *playlist_name(char *buf, int buf_size) playlist.queue_indices[playlist.last_queue_index] = seek;
{ playlist.last_queue_index =
char *sep; (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 playlist.num_queued;
return NULL;
/* Remove extension */
sep = strrchr(buf, '.');
if (NULL != sep)
*sep = 0;
return buf;
} }
int playlist_next(int steps) 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) char* playlist_peek(int steps)
@ -145,24 +355,19 @@ char* playlist_peek(int steps)
char dir_buf[MAX_PATH+1]; char dir_buf[MAX_PATH+1];
char *dir_end; char *dir_end;
int index; int index;
bool queue;
index = get_next_index(steps); index = get_next_index(steps, &queue);
if (index >= 0) if (index < 0)
seek = playlist.indices[index];
else
return NULL; return NULL;
if(playlist.in_ram) if (queue)
{ {
buf = playlist_buffer + seek; seek = playlist.queue_indices[index];
max = playlist_end_pos - seek; fd = open(QUEUE_FILE, O_RDONLY);
}
else
{
fd = open(playlist.filename, O_RDONLY);
if(-1 != fd) if(-1 != fd)
{ {
buf = playlist_buffer; buf = dir_buf;
lseek(fd, seek, SEEK_SET); lseek(fd, seek, SEEK_SET);
max = read(fd, buf, MAX_PATH); max = read(fd, buf, MAX_PATH);
close(fd); close(fd);
@ -170,6 +375,29 @@ char* playlist_peek(int steps)
else else
return NULL; 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 */ /* Zero-terminate the file name */
seek=0; seek=0;
@ -260,11 +488,13 @@ int play_list(char *dir, /* "current directory" */
playlist AFTER the shuffle */ playlist AFTER the shuffle */
int start_offset, /* offset in the file */ int start_offset, /* offset in the file */
int random_seed, /* used for shuffling */ 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=""; char *sep="";
int dirlen; int dirlen;
empty_playlist(); empty_playlist(queue_resume);
playlist.index = start_index; playlist.index = start_index;
playlist.first_index = first_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) { if(!playlist.in_ram) {
lcd_puts(0,0,str(LANG_PLAYLIST_PLAY)); lcd_puts(0,0,str(LANG_PLAYLIST_PLAY));
status_draw(); status_draw();
@ -354,16 +596,6 @@ int play_list(char *dir, /* "current directory" */
return playlist.index; 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 * calculate track offsets within a playlist file
*/ */

View file

@ -36,6 +36,13 @@ struct playlist_info
int seed; /* random seed */ int seed; /* random seed */
int amount; /* number of tracks in the index */ int amount; /* number of tracks in the index */
bool in_ram; /* True if the playlist is RAM-based */ bool in_ram; /* True if the playlist is RAM-based */
/* Queue function */
int queue_indices[MAX_QUEUED_FILES]; /* array of queue indices */
int last_queue_index; /* index of last queued track */
int queue_index; /* index of current playing queued track */
int num_queued; /* number of songs queued */
int start_queue; /* the first song was queued */
}; };
extern struct playlist_info playlist; extern struct playlist_info playlist;
@ -43,18 +50,23 @@ extern bool playlist_shuffle;
int play_list(char *dir, char *file, int start_index, int play_list(char *dir, char *file, int start_index,
bool shuffled_index, int start_offset, bool shuffled_index, int start_offset,
int random_seed, int first_index); int random_seed, int first_index, int queue_resume,
int queue_resume_index);
char* playlist_peek(int steps); char* playlist_peek(int steps);
char* playlist_name(char *name, int name_size); char* playlist_name(char *name, int name_size);
int playlist_next(int steps); int playlist_next(int steps);
void randomise_playlist( unsigned int seed ); void randomise_playlist( unsigned int seed );
void sort_playlist(bool start_current); void sort_playlist(bool start_current);
void empty_playlist(void);
void add_indices_to_playlist(void); void add_indices_to_playlist(void);
void playlist_clear(void); void playlist_clear(void);
int playlist_add(char *filename); int playlist_add(char *filename);
int queue_add(char *filename);
int playlist_amount(void); int playlist_amount(void);
int playlist_first_index(void); int playlist_first_index(void);
int playlist_get_resume_info(int *resume_index, int *queue_resume,
int *queue_resume_index);
enum { QUEUE_OFF, QUEUE_BEGIN_QUEUE, QUEUE_BEGIN_PLAYLIST, NUM_QUEUE_MODES };
#endif /* __PLAYLIST_H__ */ #endif /* __PLAYLIST_H__ */

View file

@ -92,14 +92,10 @@ offset abs
0x12 0x26 <(int) Resume playlist index, or -1 if no playlist resume> 0x12 0x26 <(int) Resume playlist index, or -1 if no playlist resume>
0x16 0x2a <(int) Byte offset into resume file> 0x16 0x2a <(int) Byte offset into resume file>
0x1a 0x2e <time until disk spindown> 0x1a 0x2e <time until disk spindown>
0x1b 0x2f <browse current, play selected> 0x1b 0x2f <browse current, play selected, queue_resume>
0x1c 0x30 <peak meter hold timeout (bit 0-4)>, 0x1c 0x30 <peak meter hold timeout (bit 0-4)>,
peak_meter_performance (bit 7) peak_meter_performance (bit 7)
0x1d 0x31 <peak meter clip hold timeout (bit 0-4) 0x1d 0x31 <(int) queue resume index>
0x1e 0x32 <peak meter release step size,
peak_meter_dbfs (bit 7)
0x1f 0x33 <peak meter min either in -db or in percent>
0x20 0x34 <peak meter max either in -db or in percent>
0x21 0x35 <repeat mode (bit 0-1), rec. channels (bit 2), 0x21 0x35 <repeat mode (bit 0-1), rec. channels (bit 2),
mic gain (bit 4-7)> mic gain (bit 4-7)>
0x22 0x36 <rec. quality (bit 0-2), source (bit 3-4), frequency (bit 5-7)> 0x22 0x36 <rec. quality (bit 0-2), source (bit 3-4), frequency (bit 5-7)>
@ -125,7 +121,10 @@ modified unless the header & checksum test fails.
Rest of config block, only saved to disk: Rest of config block, only saved to disk:
0xB0 peak meter clip hold timeout (bit 0-4)
0xB1 peak meter release step size, peak_meter_dbfs (bit 7)
0xB2 peak meter min either in -db or in percent
0xB3 peak meter max either in -db or in percent
0xB4 battery capacity 0xB4 battery capacity
0xB5 scroll step in pixels 0xB5 scroll step in pixels
0xB6 scroll start and endpoint delay 0xB6 scroll start and endpoint delay
@ -330,15 +329,13 @@ int settings_save( void )
config_block[0x1a] = (unsigned char)global_settings.disk_spindown; config_block[0x1a] = (unsigned char)global_settings.disk_spindown;
config_block[0x1b] = (unsigned char) config_block[0x1b] = (unsigned char)
(((global_settings.browse_current & 1)) | (((global_settings.browse_current & 1)) |
((global_settings.play_selected & 1) << 1)); ((global_settings.play_selected & 1) << 1) |
((global_settings.queue_resume & 3) << 2));
config_block[0x1c] = (unsigned char)global_settings.peak_meter_hold; config_block[0x1c] = (unsigned char)global_settings.peak_meter_hold;
config_block[0x1d] = (unsigned char)global_settings.peak_meter_clip_hold |
(global_settings.peak_meter_performance ? 0x80 : 0); memcpy(&config_block[0x1d], &global_settings.queue_resume_index, 4);
config_block[0x1e] = global_settings.peak_meter_release |
(global_settings.peak_meter_dbfs ? 0x80 : 0);
config_block[0x1f] = (unsigned char)global_settings.peak_meter_min;
config_block[0x20] = (unsigned char)global_settings.peak_meter_max;
config_block[0x21] = (unsigned char) config_block[0x21] = (unsigned char)
((global_settings.repeat_mode & 3) | ((global_settings.repeat_mode & 3) |
((global_settings.rec_channels & 1) << 2) | ((global_settings.rec_channels & 1) << 2) |
@ -369,6 +366,13 @@ int settings_save( void )
config_block[0x29]=(unsigned char)(global_settings.topruntime >> 8); config_block[0x29]=(unsigned char)(global_settings.topruntime >> 8);
} }
config_block[0xb0] = (unsigned char)global_settings.peak_meter_clip_hold |
(global_settings.peak_meter_performance ? 0x80 : 0);
config_block[0xb1] = global_settings.peak_meter_release |
(global_settings.peak_meter_dbfs ? 0x80 : 0);
config_block[0xb2] = (unsigned char)global_settings.peak_meter_min;
config_block[0xb3] = (unsigned char)global_settings.peak_meter_max;
config_block[0xb4]=(global_settings.battery_capacity - 1000) / 50; config_block[0xb4]=(global_settings.battery_capacity - 1000) / 50;
config_block[0xb5]=(unsigned char)global_settings.scroll_step; config_block[0xb5]=(unsigned char)global_settings.scroll_step;
config_block[0xb6]=(unsigned char)global_settings.scroll_delay; config_block[0xb6]=(unsigned char)global_settings.scroll_delay;
@ -595,27 +599,15 @@ void settings_load(void)
if (config_block[0x1b] != 0xFF) { if (config_block[0x1b] != 0xFF) {
global_settings.browse_current = (config_block[0x1b]) & 1; global_settings.browse_current = (config_block[0x1b]) & 1;
global_settings.play_selected = (config_block[0x1b] >> 1) & 1; global_settings.play_selected = (config_block[0x1b] >> 1) & 1;
global_settings.queue_resume = (config_block[0x1b] >> 2) & 3;
} }
if (config_block[0x1c] != 0xFF) if (config_block[0x1c] != 0xFF)
global_settings.peak_meter_hold = (config_block[0x1c]) & 0x1f; global_settings.peak_meter_hold = (config_block[0x1c]) & 0x1f;
if (config_block[0x1d] != 0xFF) { if (config_block[0x1d] != 0xFF)
global_settings.peak_meter_clip_hold = (config_block[0x1d]) & 0x1f; memcpy(&global_settings.queue_resume_index, &config_block[0x1d],
global_settings.peak_meter_performance = 4);
(config_block[0x1d] & 0x80) != 0;
}
if (config_block[0x1e] != 0xFF) {
global_settings.peak_meter_release = config_block[0x1e] & 0x7f;
global_settings.peak_meter_dbfs = (config_block[0x1e] & 0x80) != 0;
}
if (config_block[0x1f] != 0xFF)
global_settings.peak_meter_min = config_block[0x1f];
if (config_block[0x20] != 0xFF)
global_settings.peak_meter_max = config_block[0x20];
if (config_block[0x21] != 0xFF) if (config_block[0x21] != 0xFF)
{ {
@ -652,6 +644,16 @@ void settings_load(void)
global_settings.topruntime = global_settings.topruntime =
config_block[0x28] | (config_block[0x29] << 8); config_block[0x28] | (config_block[0x29] << 8);
global_settings.peak_meter_clip_hold = (config_block[0xb0]) & 0x1f;
global_settings.peak_meter_performance =
(config_block[0xb0] & 0x80) != 0;
global_settings.peak_meter_release = config_block[0xb1] & 0x7f;
global_settings.peak_meter_dbfs = (config_block[0xb1] & 0x80) != 0;
global_settings.peak_meter_min = config_block[0xb2];
global_settings.peak_meter_max = config_block[0xb3];
global_settings.battery_capacity = config_block[0xb4]*50 + 1000; global_settings.battery_capacity = config_block[0xb4]*50 + 1000;
if (config_block[0xb5] != 0xff) if (config_block[0xb5] != 0xff)
@ -857,6 +859,9 @@ void settings_reset(void) {
global_settings.ff_rewind_accel = DEFAULT_FF_REWIND_ACCEL_SETTING; global_settings.ff_rewind_accel = DEFAULT_FF_REWIND_ACCEL_SETTING;
global_settings.resume_index = -1; global_settings.resume_index = -1;
global_settings.resume_offset = -1; global_settings.resume_offset = -1;
global_settings.save_queue_resume = true;
global_settings.queue_resume = 0;
global_settings.queue_resume_index = -1;
global_settings.disk_spindown = 5; global_settings.disk_spindown = 5;
global_settings.disk_poweroff = false; global_settings.disk_poweroff = false;
global_settings.buffer_margin = 0; global_settings.buffer_margin = 0;

View file

@ -94,6 +94,13 @@ struct user_settings
int resume_offset; /* byte offset in mp3 file */ int resume_offset; /* byte offset in mp3 file */
int resume_seed; /* random seed for playlist shuffle */ int resume_seed; /* random seed for playlist shuffle */
int resume_first_index; /* first index of playlist */ int resume_first_index; /* first index of playlist */
bool save_queue_resume; /* save queued songs for resume */
int queue_resume; /* resume queue file?: 0 = no
1 = resume at queue index
2 = resume at playlist index */
int queue_resume_index; /* queue index (seek point in queue file) */
unsigned char resume_file[MAX_PATH+1]; /* playlist name (or dir) */ unsigned char resume_file[MAX_PATH+1]; /* playlist name (or dir) */
unsigned char font_file[MAX_FILENAME+1]; /* last font */ unsigned char font_file[MAX_FILENAME+1]; /* last font */
unsigned char wps_file[MAX_FILENAME+1]; /* last wps */ unsigned char wps_file[MAX_FILENAME+1]; /* last wps */

View file

@ -452,6 +452,36 @@ static int showdir(char *path, int start)
return filesindir; return filesindir;
} }
static void show_queue_display(int queue_count, char *filename)
{
#ifdef HAVE_LCD_CHARCELLS
lcd_double_height(false);
#endif
#ifdef HAVE_LCD_BITMAP
lcd_setmargins(0,0);
#endif
lcd_clear_display();
if (queue_count > 0)
{
char s[32];
snprintf(s, sizeof(s), str(LANG_QUEUE_QUEUED), filename);
lcd_puts(0,0,s);
snprintf(s, sizeof(s), str(LANG_QUEUE_TOTAL), queue_count);
lcd_puts(0,1,s);
}
else
{
lcd_puts(0,0,str(LANG_QUEUE_FULL));
}
lcd_update();
sleep(HZ);
lcd_clear_display();
}
bool ask_resume(void) bool ask_resume(void)
{ {
#ifdef HAVE_LCD_CHARCELLS #ifdef HAVE_LCD_CHARCELLS
@ -518,7 +548,9 @@ void start_resume(void)
true, /* the index is AFTER shuffle */ true, /* the index is AFTER shuffle */
global_settings.resume_offset, global_settings.resume_offset,
global_settings.resume_seed, global_settings.resume_seed,
global_settings.resume_first_index); global_settings.resume_first_index,
global_settings.queue_resume,
global_settings.queue_resume_index);
*slash='/'; *slash='/';
} }
else { else {
@ -537,7 +569,9 @@ void start_resume(void)
true, true,
global_settings.resume_offset, global_settings.resume_offset,
global_settings.resume_seed, global_settings.resume_seed,
global_settings.resume_first_index); global_settings.resume_first_index,
global_settings.queue_resume,
global_settings.queue_resume_index);
} }
} }
else { else {
@ -556,7 +590,9 @@ void start_resume(void)
true, true,
global_settings.resume_offset, global_settings.resume_offset,
global_settings.resume_seed, global_settings.resume_seed,
global_settings.resume_first_index); global_settings.resume_first_index,
global_settings.queue_resume,
global_settings.queue_resume_index);
} }
status_set_playmode(STATUS_PLAY); status_set_playmode(STATUS_PLAY);
@ -774,10 +810,10 @@ bool dirbrowse(char *root)
break; break;
case TREE_ENTER: case TREE_ENTER | BUTTON_REL:
case TREE_ENTER | BUTTON_REPEAT: case TREE_ENTER | BUTTON_REPEAT:
#ifdef HAVE_RECORDER_KEYPAD #ifdef HAVE_RECORDER_KEYPAD
case BUTTON_PLAY: case BUTTON_PLAY | BUTTON_REL:
case BUTTON_PLAY | BUTTON_REPEAT: case BUTTON_PLAY | BUTTON_REPEAT:
#endif #endif
if ( !numentries ) if ( !numentries )
@ -798,6 +834,7 @@ bool dirbrowse(char *root)
dircursor=0; dircursor=0;
dirstart=0; dirstart=0;
} else { } else {
static int repeat_count = 0;
int seed = current_tick; int seed = current_tick;
bool play = false; bool play = false;
int start_index=0; int start_index=0;
@ -810,23 +847,40 @@ bool dirbrowse(char *root)
MAX_PATH, "%s/%s", MAX_PATH, "%s/%s",
currdir, file->name); currdir, file->name);
play_list(currdir, file->name, 0, false, 0, play_list(currdir, file->name, 0, false, 0,
seed, 0); seed, 0, 0, -1);
start_index = 0; start_index = 0;
play = true; play = true;
break; break;
case TREE_ATTR_MPA: case TREE_ATTR_MPA:
if ( global_settings.resume ) if (button & BUTTON_REPEAT &&
strncpy(global_settings.resume_file, mpeg_status() & MPEG_STATUS_PLAY)
currdir, MAX_PATH); {
start_index = build_playlist(dircursor+dirstart); int queue_count = queue_add(buf);
show_queue_display(queue_count,
/* it is important that we get back the index in file->name);
the (shuffled) list and stor that */
start_index = play_list(currdir, NULL, while( !(button_get(true) & BUTTON_REL) ) ;
start_index, false,
0, seed, 0); repeat_count = 0;
play = true; restore = true;
}
else
{
repeat_count = 0;
if ( global_settings.resume )
strncpy(global_settings.resume_file,
currdir, MAX_PATH);
start_index =
build_playlist(dircursor+dirstart);
/* it is important that we get back the index
in the (shuffled) list and store that */
start_index = play_list(currdir, NULL,
start_index, false,
0, seed, 0, 0, -1);
play = true;
}
break; break;
/* wps config file */ /* wps config file */

View file

@ -38,6 +38,7 @@
#include "main_menu.h" #include "main_menu.h"
#include "ata.h" #include "ata.h"
#include "screens.h" #include "screens.h"
#include "playlist.h"
#ifdef HAVE_LCD_BITMAP #ifdef HAVE_LCD_BITMAP
#include "icons.h" #include "icons.h"
#include "peakmeter.h" #include "peakmeter.h"
@ -437,9 +438,14 @@ static bool update(void)
global_settings.resume_offset != id3->offset ) { global_settings.resume_offset != id3->offset ) {
DEBUGF("R%X,%X (%X)\n", global_settings.resume_offset, DEBUGF("R%X,%X (%X)\n", global_settings.resume_offset,
id3->offset,id3); id3->offset,id3);
global_settings.resume_index = id3->index;
global_settings.resume_offset = id3->offset; if (!playlist_get_resume_info(&global_settings.resume_index,
settings_save(); &global_settings.queue_resume,
&global_settings.queue_resume_index))
{
global_settings.resume_offset = id3->offset;
settings_save();
}
} }
else if ( !id3 && track_changed ) { else if ( !id3 && track_changed ) {
global_settings.resume_index = -1; global_settings.resume_index = -1;

View file

@ -21,13 +21,18 @@
#include <sys/types.h> #include <sys/types.h>
int x11_open(char *name, int opts); int x11_open(char *name, int opts);
int x11_creat(char *name, int mode);
int x11_remove(char *name);
#define open(x,y) x11_open(x,y) #define open(x,y) x11_open(x,y)
#define creat(x,y) x11_open(x,y)
#define remove(x) x11_remove(x)
#include "../../firmware/common/file.h" #include "../../firmware/common/file.h"
extern int open(char* pathname, int flags); extern int open(char* pathname, int flags);
extern int close(int fd); extern int close(int fd);
extern int read(int fd, void* buf, int count); extern int read(int fd, void* buf, int count);
extern int write(int fd, void* buf, int count);
extern int lseek(int fd, int offset, int whence); extern int lseek(int fd, int offset, int whence);
extern int printf(const char *format, ...); extern int printf(const char *format, ...);

View file

@ -109,6 +109,32 @@ int x11_open(char *name, int opts)
return open(name, opts); return open(name, opts);
} }
int x11_creat(char *name, int mode)
{
char buffer[256]; /* sufficiently big */
if(name[0] == '/') {
sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name);
debugf("We open the real file '%s'\n", buffer);
return creat(buffer, mode);
}
return creat(name, mode);
}
int x11_remove(char *name)
{
char buffer[256]; /* sufficiently big */
if(name[0] == '/') {
sprintf(buffer, "%s%s", SIMULATOR_ARCHOS_ROOT, name);
debugf("We open the real file '%s'\n", buffer);
return remove(buffer);
}
return remove(name);
}
void fat_size(unsigned int* size, unsigned int* free) void fat_size(unsigned int* size, unsigned int* free)
{ {
struct statfs fs; struct statfs fs;