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:
parent
0e342181c3
commit
c78e1b07fe
10 changed files with 492 additions and 129 deletions
|
@ -23,5 +23,6 @@
|
|||
#define AVERAGE_FILENAME_LENGTH 40
|
||||
#define MAX_DIR_LEVELS 10
|
||||
#define MAX_PLAYLIST_SIZE 10000
|
||||
#define MAX_QUEUED_FILES 100
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1221,3 +1221,18 @@ id: LANG_BATTERY_CAPACITY
|
|||
desc: in settings_menu
|
||||
eng: "Battery Capacity"
|
||||
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:
|
||||
|
|
386
apps/playlist.c
386
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,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
|
||||
*/
|
||||
|
|
|
@ -36,6 +36,13 @@ struct playlist_info
|
|||
int seed; /* random seed */
|
||||
int amount; /* number of tracks in the index */
|
||||
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;
|
||||
|
@ -43,18 +50,23 @@ extern bool playlist_shuffle;
|
|||
|
||||
int play_list(char *dir, char *file, int start_index,
|
||||
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_name(char *name, int name_size);
|
||||
int playlist_next(int steps);
|
||||
void randomise_playlist( unsigned int seed );
|
||||
void sort_playlist(bool start_current);
|
||||
void empty_playlist(void);
|
||||
void add_indices_to_playlist(void);
|
||||
void playlist_clear(void);
|
||||
int playlist_add(char *filename);
|
||||
int queue_add(char *filename);
|
||||
int playlist_amount(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__ */
|
||||
|
||||
|
|
|
@ -92,14 +92,10 @@ offset abs
|
|||
0x12 0x26 <(int) Resume playlist index, or -1 if no playlist resume>
|
||||
0x16 0x2a <(int) Byte offset into resume file>
|
||||
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)>,
|
||||
peak_meter_performance (bit 7)
|
||||
0x1d 0x31 <peak meter clip hold timeout (bit 0-4)
|
||||
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>
|
||||
0x1d 0x31 <(int) queue resume index>
|
||||
0x21 0x35 <repeat mode (bit 0-1), rec. channels (bit 2),
|
||||
mic gain (bit 4-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:
|
||||
|
||||
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
|
||||
0xB5 scroll step in pixels
|
||||
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[0x1b] = (unsigned char)
|
||||
(((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[0x1d] = (unsigned char)global_settings.peak_meter_clip_hold |
|
||||
(global_settings.peak_meter_performance ? 0x80 : 0);
|
||||
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;
|
||||
|
||||
memcpy(&config_block[0x1d], &global_settings.queue_resume_index, 4);
|
||||
|
||||
config_block[0x21] = (unsigned char)
|
||||
((global_settings.repeat_mode & 3) |
|
||||
((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[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[0xb5]=(unsigned char)global_settings.scroll_step;
|
||||
config_block[0xb6]=(unsigned char)global_settings.scroll_delay;
|
||||
|
@ -595,27 +599,15 @@ void settings_load(void)
|
|||
if (config_block[0x1b] != 0xFF) {
|
||||
global_settings.browse_current = (config_block[0x1b]) & 1;
|
||||
global_settings.play_selected = (config_block[0x1b] >> 1) & 1;
|
||||
global_settings.queue_resume = (config_block[0x1b] >> 2) & 3;
|
||||
}
|
||||
|
||||
if (config_block[0x1c] != 0xFF)
|
||||
global_settings.peak_meter_hold = (config_block[0x1c]) & 0x1f;
|
||||
|
||||
if (config_block[0x1d] != 0xFF) {
|
||||
global_settings.peak_meter_clip_hold = (config_block[0x1d]) & 0x1f;
|
||||
global_settings.peak_meter_performance =
|
||||
(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[0x1d] != 0xFF)
|
||||
memcpy(&global_settings.queue_resume_index, &config_block[0x1d],
|
||||
4);
|
||||
|
||||
if (config_block[0x21] != 0xFF)
|
||||
{
|
||||
|
@ -652,6 +644,16 @@ void settings_load(void)
|
|||
global_settings.topruntime =
|
||||
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;
|
||||
|
||||
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.resume_index = -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_poweroff = false;
|
||||
global_settings.buffer_margin = 0;
|
||||
|
|
|
@ -94,6 +94,13 @@ struct user_settings
|
|||
int resume_offset; /* byte offset in mp3 file */
|
||||
int resume_seed; /* random seed for playlist shuffle */
|
||||
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 font_file[MAX_FILENAME+1]; /* last font */
|
||||
unsigned char wps_file[MAX_FILENAME+1]; /* last wps */
|
||||
|
|
86
apps/tree.c
86
apps/tree.c
|
@ -452,6 +452,36 @@ static int showdir(char *path, int start)
|
|||
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)
|
||||
{
|
||||
#ifdef HAVE_LCD_CHARCELLS
|
||||
|
@ -518,7 +548,9 @@ void start_resume(void)
|
|||
true, /* the index is AFTER shuffle */
|
||||
global_settings.resume_offset,
|
||||
global_settings.resume_seed,
|
||||
global_settings.resume_first_index);
|
||||
global_settings.resume_first_index,
|
||||
global_settings.queue_resume,
|
||||
global_settings.queue_resume_index);
|
||||
*slash='/';
|
||||
}
|
||||
else {
|
||||
|
@ -537,7 +569,9 @@ void start_resume(void)
|
|||
true,
|
||||
global_settings.resume_offset,
|
||||
global_settings.resume_seed,
|
||||
global_settings.resume_first_index);
|
||||
global_settings.resume_first_index,
|
||||
global_settings.queue_resume,
|
||||
global_settings.queue_resume_index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -556,7 +590,9 @@ void start_resume(void)
|
|||
true,
|
||||
global_settings.resume_offset,
|
||||
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);
|
||||
|
@ -774,10 +810,10 @@ bool dirbrowse(char *root)
|
|||
break;
|
||||
|
||||
|
||||
case TREE_ENTER:
|
||||
case TREE_ENTER | BUTTON_REL:
|
||||
case TREE_ENTER | BUTTON_REPEAT:
|
||||
#ifdef HAVE_RECORDER_KEYPAD
|
||||
case BUTTON_PLAY:
|
||||
case BUTTON_PLAY | BUTTON_REL:
|
||||
case BUTTON_PLAY | BUTTON_REPEAT:
|
||||
#endif
|
||||
if ( !numentries )
|
||||
|
@ -798,6 +834,7 @@ bool dirbrowse(char *root)
|
|||
dircursor=0;
|
||||
dirstart=0;
|
||||
} else {
|
||||
static int repeat_count = 0;
|
||||
int seed = current_tick;
|
||||
bool play = false;
|
||||
int start_index=0;
|
||||
|
@ -810,23 +847,40 @@ bool dirbrowse(char *root)
|
|||
MAX_PATH, "%s/%s",
|
||||
currdir, file->name);
|
||||
play_list(currdir, file->name, 0, false, 0,
|
||||
seed, 0);
|
||||
seed, 0, 0, -1);
|
||||
start_index = 0;
|
||||
play = true;
|
||||
break;
|
||||
|
||||
case TREE_ATTR_MPA:
|
||||
if ( global_settings.resume )
|
||||
strncpy(global_settings.resume_file,
|
||||
currdir, MAX_PATH);
|
||||
start_index = build_playlist(dircursor+dirstart);
|
||||
if (button & BUTTON_REPEAT &&
|
||||
mpeg_status() & MPEG_STATUS_PLAY)
|
||||
{
|
||||
int queue_count = queue_add(buf);
|
||||
show_queue_display(queue_count,
|
||||
file->name);
|
||||
|
||||
/* it is important that we get back the index in
|
||||
the (shuffled) list and stor that */
|
||||
start_index = play_list(currdir, NULL,
|
||||
start_index, false,
|
||||
0, seed, 0);
|
||||
play = true;
|
||||
while( !(button_get(true) & BUTTON_REL) ) ;
|
||||
|
||||
repeat_count = 0;
|
||||
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;
|
||||
|
||||
/* wps config file */
|
||||
|
|
12
apps/wps.c
12
apps/wps.c
|
@ -38,6 +38,7 @@
|
|||
#include "main_menu.h"
|
||||
#include "ata.h"
|
||||
#include "screens.h"
|
||||
#include "playlist.h"
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "icons.h"
|
||||
#include "peakmeter.h"
|
||||
|
@ -437,9 +438,14 @@ static bool update(void)
|
|||
global_settings.resume_offset != id3->offset ) {
|
||||
DEBUGF("R%X,%X (%X)\n", global_settings.resume_offset,
|
||||
id3->offset,id3);
|
||||
global_settings.resume_index = id3->index;
|
||||
global_settings.resume_offset = id3->offset;
|
||||
settings_save();
|
||||
|
||||
if (!playlist_get_resume_info(&global_settings.resume_index,
|
||||
&global_settings.queue_resume,
|
||||
&global_settings.queue_resume_index))
|
||||
{
|
||||
global_settings.resume_offset = id3->offset;
|
||||
settings_save();
|
||||
}
|
||||
}
|
||||
else if ( !id3 && track_changed ) {
|
||||
global_settings.resume_index = -1;
|
||||
|
|
|
@ -21,13 +21,18 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
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 creat(x,y) x11_open(x,y)
|
||||
#define remove(x) x11_remove(x)
|
||||
|
||||
#include "../../firmware/common/file.h"
|
||||
|
||||
extern int open(char* pathname, int flags);
|
||||
extern int close(int fd);
|
||||
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 printf(const char *format, ...);
|
||||
|
|
|
@ -109,6 +109,32 @@ int x11_open(char *name, int 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)
|
||||
{
|
||||
struct statfs fs;
|
||||
|
|
Loading…
Reference in a new issue