mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
patch 1328447: folder skip routines in playlist API plus next/prev folder navigation for iRiver's remote
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7735 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
0263ece7f8
commit
d102e1f345
8 changed files with 166 additions and 22 deletions
|
|
@ -172,12 +172,18 @@ static int compare(const void* p1, const void* p2)
|
||||||
return t1 - t2;
|
return t1 - t2;
|
||||||
/* else fall through to alphabetical sorting */
|
/* else fall through to alphabetical sorting */
|
||||||
}
|
}
|
||||||
case 0: /* sort alphabetically */
|
case 0: /* sort alphabetically asc */
|
||||||
if (global_settings.sort_case)
|
if (global_settings.sort_case)
|
||||||
return strncmp(e1->name, e2->name, MAX_PATH);
|
return strncmp(e1->name, e2->name, MAX_PATH);
|
||||||
else
|
else
|
||||||
return strncasecmp(e1->name, e2->name, MAX_PATH);
|
return strncasecmp(e1->name, e2->name, MAX_PATH);
|
||||||
|
|
||||||
|
case 4: /* sort alphabetically desc */
|
||||||
|
if (global_settings.sort_case)
|
||||||
|
return strncmp(e2->name, e1->name, MAX_PATH);
|
||||||
|
else
|
||||||
|
return strncasecmp(e2->name, e1->name, MAX_PATH);
|
||||||
|
|
||||||
case 1: /* sort date */
|
case 1: /* sort date */
|
||||||
return e1->time_write - e2->time_write;
|
return e1->time_write - e2->time_write;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3144,9 +3144,9 @@ voice: "Optical output"
|
||||||
new:
|
new:
|
||||||
|
|
||||||
id: LANG_NEXT_FOLDER
|
id: LANG_NEXT_FOLDER
|
||||||
desc: in settings_menu. Should we move to next folder when current one ends
|
desc: in settings_menu. Should we allow skip directories and move to next folder when current one ends
|
||||||
eng: "Move to Next Folder"
|
eng: "Directory navigation"
|
||||||
voice: "Move to Next Folder"
|
voice: "Directory navigation"
|
||||||
new:
|
new:
|
||||||
|
|
||||||
id: LANG_RUNTIMEDB_ACTIVE
|
id: LANG_RUNTIMEDB_ACTIVE
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,8 @@ static volatile bool paused;
|
||||||
#define AUDIO_CODEC_DONE 9
|
#define AUDIO_CODEC_DONE 9
|
||||||
#define AUDIO_FLUSH 10
|
#define AUDIO_FLUSH 10
|
||||||
#define AUDIO_TRACK_CHANGED 11
|
#define AUDIO_TRACK_CHANGED 11
|
||||||
|
#define AUDIO_DIR_NEXT 12
|
||||||
|
#define AUDIO_DIR_PREV 13
|
||||||
|
|
||||||
#define CODEC_LOAD 1
|
#define CODEC_LOAD 1
|
||||||
#define CODEC_LOAD_DISK 2
|
#define CODEC_LOAD_DISK 2
|
||||||
|
|
@ -1653,6 +1655,24 @@ static void initiate_track_change(int peek_index)
|
||||||
codec_track_changed();
|
codec_track_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void initiate_dir_change(int direction)
|
||||||
|
{
|
||||||
|
if(!playlist_next_dir(direction))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Detect if disk is spinning.. */
|
||||||
|
if (filling) {
|
||||||
|
queue_post(&audio_queue, AUDIO_PLAY, 0);
|
||||||
|
} else {
|
||||||
|
new_track = 0;
|
||||||
|
ci.reload_codec = true;
|
||||||
|
if (!pcmbuf_is_crossfade_enabled())
|
||||||
|
pcmbuf_flush_audio();
|
||||||
|
}
|
||||||
|
|
||||||
|
codec_track_changed();
|
||||||
|
}
|
||||||
|
|
||||||
void audio_thread(void)
|
void audio_thread(void)
|
||||||
{
|
{
|
||||||
struct event ev;
|
struct event ev;
|
||||||
|
|
@ -1735,6 +1755,21 @@ void audio_thread(void)
|
||||||
initiate_track_change(-1);
|
initiate_track_change(-1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case AUDIO_DIR_NEXT:
|
||||||
|
logf("audio_dir_next");
|
||||||
|
if (global_settings.beep)
|
||||||
|
pcmbuf_beep(5000, 100, 2500*global_settings.beep);
|
||||||
|
initiate_dir_change(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AUDIO_DIR_PREV:
|
||||||
|
logf("audio_dir_prev");
|
||||||
|
if (global_settings.beep)
|
||||||
|
pcmbuf_beep(5000, 100, 2500*global_settings.beep);
|
||||||
|
initiate_dir_change(-1);
|
||||||
|
break;
|
||||||
|
|
||||||
case AUDIO_FLUSH:
|
case AUDIO_FLUSH:
|
||||||
audio_invalidate_tracks();
|
audio_invalidate_tracks();
|
||||||
break ;
|
break ;
|
||||||
|
|
@ -2008,6 +2043,16 @@ void audio_prev(void)
|
||||||
queue_post(&audio_queue, AUDIO_PREV, 0);
|
queue_post(&audio_queue, AUDIO_PREV, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void audio_next_dir(void)
|
||||||
|
{
|
||||||
|
queue_post(&audio_queue, AUDIO_DIR_NEXT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void audio_prev_dir(void)
|
||||||
|
{
|
||||||
|
queue_post(&audio_queue, AUDIO_DIR_PREV, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void audio_ff_rewind(int newpos)
|
void audio_ff_rewind(int newpos)
|
||||||
{
|
{
|
||||||
logf("rewind: %d", newpos);
|
logf("rewind: %d", newpos);
|
||||||
|
|
|
||||||
110
apps/playlist.c
110
apps/playlist.c
|
|
@ -162,6 +162,8 @@ static int compare(const void* p1, const void* p2);
|
||||||
static int get_filename(struct playlist_info* playlist, int seek,
|
static int get_filename(struct playlist_info* playlist, int seek,
|
||||||
bool control_file, char *buf, int buf_length);
|
bool control_file, char *buf, int buf_length);
|
||||||
static int get_next_directory(char *dir);
|
static int get_next_directory(char *dir);
|
||||||
|
static int get_next_dir(char *dir, bool is_forward, bool recursion);
|
||||||
|
static int get_previous_directory(char *dir);
|
||||||
static int check_subdir_for_music(char *dir, char *subdir);
|
static int check_subdir_for_music(char *dir, char *subdir);
|
||||||
static int format_track_path(char *dest, char *src, int buf_length, int max,
|
static int format_track_path(char *dest, char *src, int buf_length, int max,
|
||||||
char *dir);
|
char *dir);
|
||||||
|
|
@ -1098,26 +1100,53 @@ static int get_filename(struct playlist_info* playlist, int seek,
|
||||||
return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf));
|
return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_next_directory(char *dir){
|
||||||
|
return get_next_dir(dir,true,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_previous_directory(char *dir){
|
||||||
|
return get_next_dir(dir,false,false);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* search through all the directories (starting with the current) to find
|
* search through all the directories (starting with the current) to find
|
||||||
* one that has tracks to play
|
* one that has tracks to play
|
||||||
*/
|
*/
|
||||||
static int get_next_directory(char *dir)
|
static int get_next_dir(char *dir, bool is_forward, bool recursion)
|
||||||
{
|
{
|
||||||
struct playlist_info* playlist = ¤t_playlist;
|
struct playlist_info* playlist = ¤t_playlist;
|
||||||
int result = -1;
|
int result = -1;
|
||||||
int dirfilter = global_settings.dirfilter;
|
int dirfilter = global_settings.dirfilter;
|
||||||
|
int sort_dir = global_settings.sort_dir;
|
||||||
char *start_dir = NULL;
|
char *start_dir = NULL;
|
||||||
bool exit = false;
|
bool exit = false;
|
||||||
struct tree_context* tc = tree_get_context();
|
struct tree_context* tc = tree_get_context();
|
||||||
|
|
||||||
/* start with current directory */
|
if (recursion){
|
||||||
strncpy(dir, playlist->filename, playlist->dirlen-1);
|
/* start with root */
|
||||||
dir[playlist->dirlen-1] = '\0';
|
dir[0] = '\0';
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/* start with current directory */
|
||||||
|
strncpy(dir, playlist->filename, playlist->dirlen-1);
|
||||||
|
dir[playlist->dirlen-1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
/* use the tree browser dircache to load files */
|
/* use the tree browser dircache to load files */
|
||||||
global_settings.dirfilter = SHOW_ALL;
|
global_settings.dirfilter = SHOW_ALL;
|
||||||
|
|
||||||
|
/* sort in another direction if previous dir is requested */
|
||||||
|
if(!is_forward){
|
||||||
|
if ((global_settings.sort_dir == 0) || (global_settings.sort_dir == 3))
|
||||||
|
global_settings.sort_dir = 4;
|
||||||
|
else if (global_settings.sort_dir == 1)
|
||||||
|
global_settings.sort_dir = 2;
|
||||||
|
else if (global_settings.sort_dir == 2)
|
||||||
|
global_settings.sort_dir = 1;
|
||||||
|
else if (global_settings.sort_dir == 4)
|
||||||
|
global_settings.sort_dir = 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (!exit)
|
while (!exit)
|
||||||
{
|
{
|
||||||
struct entry *files;
|
struct entry *files;
|
||||||
|
|
@ -1180,8 +1209,14 @@ static int get_next_directory(char *dir)
|
||||||
reloaded */
|
reloaded */
|
||||||
reload_directory();
|
reload_directory();
|
||||||
|
|
||||||
/* restore dirfilter */
|
/* restore dirfilter & sort_dir */
|
||||||
global_settings.dirfilter = dirfilter;
|
global_settings.dirfilter = dirfilter;
|
||||||
|
global_settings.sort_dir = sort_dir;
|
||||||
|
|
||||||
|
/* special case if nothing found: try start searching again from root */
|
||||||
|
if (result == -1 && !recursion){
|
||||||
|
result = get_next_dir(dir,is_forward, true);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -1922,13 +1957,14 @@ int playlist_start(int start_index, int offset)
|
||||||
bool playlist_check(int steps)
|
bool playlist_check(int steps)
|
||||||
{
|
{
|
||||||
struct playlist_info* playlist = ¤t_playlist;
|
struct playlist_info* playlist = ¤t_playlist;
|
||||||
|
|
||||||
|
/* always allow folder navigation */
|
||||||
|
if (global_settings.next_folder && playlist->in_ram)
|
||||||
|
return true;
|
||||||
|
|
||||||
int index = get_next_index(playlist, steps, -1);
|
int index = get_next_index(playlist, steps, -1);
|
||||||
|
|
||||||
if (index < 0 && steps >= 0 &&
|
if (index < 0 && steps >= 0 && global_settings.repeat_mode == REPEAT_SHUFFLE)
|
||||||
(global_settings.repeat_mode == REPEAT_SHUFFLE ||
|
|
||||||
(global_settings.next_folder && playlist->in_ram)))
|
|
||||||
/* shuffle repeat and move to next folder are the same as repeat all
|
|
||||||
for check purposes */
|
|
||||||
index = get_next_index(playlist, steps, REPEAT_ALL);
|
index = get_next_index(playlist, steps, REPEAT_ALL);
|
||||||
|
|
||||||
return (index >= 0);
|
return (index >= 0);
|
||||||
|
|
@ -2031,23 +2067,40 @@ int playlist_next(int steps)
|
||||||
playlist_start(0, 0);
|
playlist_start(0, 0);
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
else if (global_settings.next_folder && playlist->in_ram)
|
else if (playlist->in_ram && global_settings.next_folder)
|
||||||
{
|
{
|
||||||
char dir[MAX_PATH+1];
|
char dir[MAX_PATH+1];
|
||||||
|
|
||||||
if (!get_next_directory(dir))
|
if (steps > 0)
|
||||||
{
|
{
|
||||||
/* start playing new directory */
|
if (!get_next_directory(dir))
|
||||||
|
{
|
||||||
|
/* start playing next directory */
|
||||||
|
if (playlist_create(dir, NULL) != -1)
|
||||||
|
{
|
||||||
|
ft_build_playlist(tree_get_context(), 0);
|
||||||
|
if (global_settings.playlist_shuffle)
|
||||||
|
playlist_shuffle(current_tick, -1);
|
||||||
|
playlist_start(0, 0);
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!get_previous_directory(dir))
|
||||||
|
{
|
||||||
|
/* start playing previous directory */
|
||||||
if (playlist_create(dir, NULL) != -1)
|
if (playlist_create(dir, NULL) != -1)
|
||||||
{
|
{
|
||||||
ft_build_playlist(tree_get_context(), 0);
|
ft_build_playlist(tree_get_context(), 0);
|
||||||
if (global_settings.playlist_shuffle)
|
if (global_settings.playlist_shuffle)
|
||||||
playlist_shuffle(current_tick, -1);
|
playlist_shuffle(current_tick, -1);
|
||||||
|
playlist_start(current_playlist.amount-1,0);
|
||||||
playlist_start(0, 0);
|
index = current_playlist.amount-1;
|
||||||
index = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
|
@ -2096,6 +2149,29 @@ int playlist_next(int steps)
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* try playing next or previous folder */
|
||||||
|
bool playlist_next_dir(int direction)
|
||||||
|
{
|
||||||
|
char dir[MAX_PATH+1];
|
||||||
|
|
||||||
|
if (((direction > 0) && !get_next_directory(dir)) ||
|
||||||
|
((direction < 0) && !get_previous_directory(dir)))
|
||||||
|
{
|
||||||
|
if (playlist_create(dir, NULL) != -1)
|
||||||
|
{
|
||||||
|
ft_build_playlist(tree_get_context(), 0);
|
||||||
|
if (global_settings.playlist_shuffle)
|
||||||
|
playlist_shuffle(current_tick, -1);
|
||||||
|
playlist_start(0,0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get resume info for current playing song. If return value is -1 then
|
/* Get resume info for current playing song. If return value is -1 then
|
||||||
settings shouldn't be saved. */
|
settings shouldn't be saved. */
|
||||||
int playlist_get_resume_info(int *resume_index)
|
int playlist_get_resume_info(int *resume_index)
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ int playlist_start(int start_index, int offset);
|
||||||
bool playlist_check(int steps);
|
bool playlist_check(int steps);
|
||||||
char *playlist_peek(int steps);
|
char *playlist_peek(int steps);
|
||||||
int playlist_next(int steps);
|
int playlist_next(int steps);
|
||||||
|
bool playlist_next_dir(int direction);
|
||||||
int playlist_get_resume_info(int *resume_index);
|
int playlist_get_resume_info(int *resume_index);
|
||||||
int playlist_update_resume_info(const struct mp3entry* id3);
|
int playlist_update_resume_info(const struct mp3entry* id3);
|
||||||
int playlist_get_display_index(void);
|
int playlist_get_display_index(void);
|
||||||
|
|
|
||||||
|
|
@ -429,7 +429,7 @@ static const struct bit_entry hd_bits[] =
|
||||||
{1, S_O(spdif_enable), false, "spdif enable", off_on},
|
{1, S_O(spdif_enable), false, "spdif enable", off_on},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{1, S_O(next_folder), false, "move to next folder", off_on },
|
{1, S_O(next_folder), true, "folder navigation", off_on },
|
||||||
{1, S_O(runtimedb), false, "gather runtime data", off_on },
|
{1, S_O(runtimedb), false, "gather runtime data", off_on },
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
|
|
||||||
14
apps/wps.c
14
apps/wps.c
|
|
@ -64,6 +64,9 @@ static struct mp3entry* id3 = NULL;
|
||||||
static struct mp3entry* nid3 = NULL;
|
static struct mp3entry* nid3 = NULL;
|
||||||
static char current_track_path[MAX_PATH+1];
|
static char current_track_path[MAX_PATH+1];
|
||||||
|
|
||||||
|
void audio_next_dir(void);
|
||||||
|
void audio_prev_dir(void);
|
||||||
|
|
||||||
/* set volume
|
/* set volume
|
||||||
return true if screen restore is needed
|
return true if screen restore is needed
|
||||||
return false otherwise
|
return false otherwise
|
||||||
|
|
@ -601,6 +604,17 @@ long wps_show(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef WPS_RC_NEXT_DIR
|
||||||
|
case WPS_RC_NEXT_DIR:
|
||||||
|
audio_next_dir();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef WPS_RC_PREV_DIR
|
||||||
|
case WPS_RC_PREV_DIR:
|
||||||
|
audio_prev_dir();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* next */
|
/* next */
|
||||||
case WPS_NEXT:
|
case WPS_NEXT:
|
||||||
#ifdef WPS_NEXT_PRE
|
#ifdef WPS_NEXT_PRE
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,8 @@
|
||||||
#define WPS_CONTEXT (BUTTON_SELECT | BUTTON_REPEAT)
|
#define WPS_CONTEXT (BUTTON_SELECT | BUTTON_REPEAT)
|
||||||
#define WPS_QUICK (BUTTON_MODE | BUTTON_REPEAT)
|
#define WPS_QUICK (BUTTON_MODE | BUTTON_REPEAT)
|
||||||
|
|
||||||
|
#define WPS_RC_NEXT_DIR (BUTTON_RC_BITRATE | BUTTON_REL)
|
||||||
|
#define WPS_RC_PREV_DIR (BUTTON_RC_SOURCE | BUTTON_REL)
|
||||||
#define WPS_RC_NEXT (BUTTON_RC_FF | BUTTON_REL)
|
#define WPS_RC_NEXT (BUTTON_RC_FF | BUTTON_REL)
|
||||||
#define WPS_RC_NEXT_PRE BUTTON_RC_FF
|
#define WPS_RC_NEXT_PRE BUTTON_RC_FF
|
||||||
#define WPS_RC_PREV (BUTTON_RC_REW | BUTTON_REL)
|
#define WPS_RC_PREV (BUTTON_RC_REW | BUTTON_REL)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue