forked from len0rd/rockbox
Added new feature to move to next folder once the current one completes when playing directories
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6963 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
50264b243e
commit
71d2281d8b
6 changed files with 230 additions and 31 deletions
|
|
@ -3142,3 +3142,9 @@ desc: in playback settings menu. enable/disable the optical out
|
|||
eng: "Optical output"
|
||||
voice:
|
||||
new:
|
||||
|
||||
id: LANG_NEXT_FOLDER
|
||||
desc: in settings_menu. Should we move to next folder when current one ends
|
||||
eng: "Move to Next Folder"
|
||||
voice:
|
||||
new:
|
||||
|
|
|
|||
214
apps/playlist.c
214
apps/playlist.c
|
|
@ -140,8 +140,8 @@ static int add_track_to_playlist(struct playlist_info* playlist,
|
|||
const char *filename, int position,
|
||||
bool queue, int seek_pos);
|
||||
static int add_directory_to_playlist(struct playlist_info* playlist,
|
||||
const char *dirname, int *position, bool queue,
|
||||
int *count, bool recurse);
|
||||
const char *dirname, int *position,
|
||||
bool queue, int *count, bool recurse);
|
||||
static int remove_track_from_playlist(struct playlist_info* playlist,
|
||||
int position, bool write);
|
||||
static int randomise_playlist(struct playlist_info* playlist,
|
||||
|
|
@ -156,6 +156,8 @@ static void find_and_set_playlist_index(struct playlist_info* playlist,
|
|||
static int compare(const void* p1, const void* p2);
|
||||
static int get_filename(struct playlist_info* playlist, int seek,
|
||||
bool control_file, char *buf, int buf_length);
|
||||
static int get_next_directory(char *dir);
|
||||
static int check_subdir_for_music(char *dir, char *subdir);
|
||||
static int format_track_path(char *dest, char *src, int buf_length, int max,
|
||||
char *dir);
|
||||
static void display_playlist_count(int count, const char *fmt);
|
||||
|
|
@ -251,7 +253,8 @@ static void create_control(struct playlist_info* playlist)
|
|||
{
|
||||
if (check_rockboxdir())
|
||||
{
|
||||
splash(HZ*2, true, "%s (%d)", str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR),
|
||||
splash(HZ*2, true, "%s (%d)",
|
||||
str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR),
|
||||
playlist->control_fd);
|
||||
}
|
||||
playlist->control_created = false;
|
||||
|
|
@ -316,8 +319,7 @@ static void update_playlist_filename(struct playlist_info* playlist,
|
|||
playlist->dirlen = dirlen;
|
||||
|
||||
snprintf(playlist->filename, sizeof(playlist->filename),
|
||||
"%s%s%s",
|
||||
dir, sep, file);
|
||||
"%s%s%s", dir, sep, file);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -398,7 +400,7 @@ static int add_indices_to_playlist(struct playlist_info* playlist,
|
|||
}
|
||||
|
||||
/*
|
||||
* Add track to playlist at specified position. There are three special
|
||||
* Add track to playlist at specified position. There are five special
|
||||
* positions that can be specified:
|
||||
* PLAYLIST_PREPEND - Add track at beginning of playlist
|
||||
* PLAYLIST_INSERT - Add track after current song. NOTE: If
|
||||
|
|
@ -552,8 +554,8 @@ static int add_track_to_playlist(struct playlist_info* playlist,
|
|||
* Insert directory into playlist. May be called recursively.
|
||||
*/
|
||||
static int add_directory_to_playlist(struct playlist_info* playlist,
|
||||
const char *dirname, int *position, bool queue,
|
||||
int *count, bool recurse)
|
||||
const char *dirname, int *position,
|
||||
bool queue, int *count, bool recurse)
|
||||
{
|
||||
char buf[MAX_PATH+1];
|
||||
char *count_str;
|
||||
|
|
@ -801,8 +803,8 @@ static int sort_playlist(struct playlist_info* playlist, bool start_current,
|
|||
unsigned int current = playlist->indices[playlist->index];
|
||||
|
||||
if (playlist->amount > 0)
|
||||
qsort(playlist->indices, playlist->amount, sizeof(playlist->indices[0]),
|
||||
compare);
|
||||
qsort(playlist->indices, playlist->amount,
|
||||
sizeof(playlist->indices[0]), compare);
|
||||
|
||||
if (start_current)
|
||||
find_and_set_playlist_index(playlist, current);
|
||||
|
|
@ -1017,6 +1019,166 @@ static int get_filename(struct playlist_info* playlist, int seek,
|
|||
return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* search through all the directories (starting with the current) to find
|
||||
* one that has tracks to play
|
||||
*/
|
||||
static int get_next_directory(char *dir)
|
||||
{
|
||||
struct playlist_info* playlist = ¤t_playlist;
|
||||
int result = -1;
|
||||
int dirfilter = global_settings.dirfilter;
|
||||
char *start_dir = NULL;
|
||||
bool exit = false;
|
||||
struct tree_context* tc = tree_get_context();
|
||||
|
||||
/* start with current directory */
|
||||
strncpy(dir, playlist->filename, playlist->dirlen-1);
|
||||
dir[playlist->dirlen-1] = '\0';
|
||||
|
||||
/* use the tree browser dircache to load files */
|
||||
global_settings.dirfilter = SHOW_ALL;
|
||||
|
||||
while (!exit)
|
||||
{
|
||||
struct entry *files;
|
||||
int num_files = 0;
|
||||
int i;
|
||||
|
||||
if (ft_load(tc, (dir[0]=='\0')?"/":dir) < 0)
|
||||
{
|
||||
splash(HZ*2, true, str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR));
|
||||
exit = true;
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
files = (struct entry*) tc->dircache;
|
||||
num_files = tc->filesindir;
|
||||
|
||||
for (i=0; i<num_files; i++)
|
||||
{
|
||||
/* user abort */
|
||||
if (button_get(false) == SETTINGS_CANCEL)
|
||||
{
|
||||
result = -1;
|
||||
exit = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (files[i].attr & ATTR_DIRECTORY)
|
||||
{
|
||||
if (!start_dir)
|
||||
{
|
||||
result = check_subdir_for_music(dir, files[i].name);
|
||||
if (result != -1)
|
||||
{
|
||||
exit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(start_dir, files[i].name))
|
||||
start_dir = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exit)
|
||||
{
|
||||
/* move down to parent directory. current directory name is
|
||||
stored as the starting point for the search in parent */
|
||||
start_dir = strrchr(dir, '/');
|
||||
if (start_dir)
|
||||
{
|
||||
*start_dir = '\0';
|
||||
start_dir++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* we've overwritten the dircache so tree browser will need to be
|
||||
reloaded */
|
||||
reload_directory();
|
||||
|
||||
/* restore dirfilter */
|
||||
global_settings.dirfilter = dirfilter;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if there are any music files in the dir or any of its
|
||||
* subdirectories. May be called recursively.
|
||||
*/
|
||||
static int check_subdir_for_music(char *dir, char *subdir)
|
||||
{
|
||||
int result = -1;
|
||||
int dirlen = strlen(dir);
|
||||
int num_files = 0;
|
||||
int i;
|
||||
struct entry *files;
|
||||
bool has_music = false;
|
||||
bool has_subdir = false;
|
||||
struct tree_context* tc = tree_get_context();
|
||||
|
||||
snprintf(dir+dirlen, MAX_PATH-dirlen, "/%s", subdir);
|
||||
|
||||
if (ft_load(tc, dir) < 0)
|
||||
{
|
||||
splash(HZ*2, true, str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR));
|
||||
return -2;
|
||||
}
|
||||
|
||||
files = (struct entry*) tc->dircache;
|
||||
num_files = tc->filesindir;
|
||||
|
||||
for (i=0; i<num_files; i++)
|
||||
{
|
||||
if (files[i].attr & ATTR_DIRECTORY)
|
||||
has_subdir = true;
|
||||
else if ((files[i].attr & TREE_ATTR_MASK) == TREE_ATTR_MPA)
|
||||
{
|
||||
has_music = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_music)
|
||||
return 0;
|
||||
|
||||
if (has_subdir)
|
||||
{
|
||||
for (i=0; i<num_files; i++)
|
||||
{
|
||||
if (button_get(false) == SETTINGS_CANCEL)
|
||||
{
|
||||
result = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (files[i].attr & ATTR_DIRECTORY)
|
||||
{
|
||||
result = check_subdir_for_music(dir, files[i].name);
|
||||
if (!result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
dir[dirlen] = '\0';
|
||||
|
||||
/* we now need to reload our current directory */
|
||||
if(ft_load(tc, dir) < 0)
|
||||
splash(HZ*2, true,
|
||||
str(LANG_PLAYLIST_DIRECTORY_ACCESS_ERROR));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns absolute path of track
|
||||
*/
|
||||
|
|
@ -1189,7 +1351,8 @@ void playlist_init(void)
|
|||
playlist->fd = -1;
|
||||
playlist->control_fd = -1;
|
||||
playlist->max_playlist_size = global_settings.max_files_in_playlist;
|
||||
playlist->indices = buffer_alloc(playlist->max_playlist_size * sizeof(int));
|
||||
playlist->indices = buffer_alloc(
|
||||
playlist->max_playlist_size * sizeof(int));
|
||||
playlist->buffer_size =
|
||||
AVERAGE_FILENAME_LENGTH * global_settings.max_files_in_dir;
|
||||
playlist->buffer = buffer_alloc(playlist->buffer_size);
|
||||
|
|
@ -1669,8 +1832,10 @@ bool playlist_check(int steps)
|
|||
int index = get_next_index(playlist, steps, -1);
|
||||
|
||||
if (index < 0 && steps >= 0 &&
|
||||
global_settings.repeat_mode == REPEAT_SHUFFLE)
|
||||
/* shuffle repeat is the same as repeat all for check purposes */
|
||||
(global_settings.repeat_mode == REPEAT_SHUFFLE ||
|
||||
global_settings.next_folder))
|
||||
/* shuffle repeat and move to next folder are the same as repeat all
|
||||
for check purposes */
|
||||
index = get_next_index(playlist, steps, REPEAT_ALL);
|
||||
|
||||
return (index >= 0);
|
||||
|
|
@ -1767,6 +1932,25 @@ int playlist_next(int steps)
|
|||
sort_playlist(playlist, false, false);
|
||||
randomise_playlist(playlist, current_tick, false, true);
|
||||
playlist_start(0, 0);
|
||||
index = 0;
|
||||
}
|
||||
else if (global_settings.next_folder && playlist->in_ram)
|
||||
{
|
||||
char dir[MAX_PATH+1];
|
||||
|
||||
if (!get_next_directory(dir))
|
||||
{
|
||||
/* start playing new 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
|
|
@ -1969,8 +2153,8 @@ void playlist_close(struct playlist_info* playlist)
|
|||
* Insert track into playlist at specified position (or one of the special
|
||||
* positions). Returns position where track was inserted or -1 if error.
|
||||
*/
|
||||
int playlist_insert_track(struct playlist_info* playlist, const char *filename,
|
||||
int position, bool queue)
|
||||
int playlist_insert_track(struct playlist_info* playlist,
|
||||
const char *filename, int position, bool queue)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
|
|
|||
|
|
@ -405,6 +405,8 @@ static const struct bit_entry hd_bits[] =
|
|||
{1, S_O(spdif_enable), false, "spdif enable", off_on},
|
||||
#endif
|
||||
|
||||
{1, S_O(next_folder), false, "move to next folder", off_on },
|
||||
|
||||
/* new stuff to be added at the end */
|
||||
|
||||
/* Sum of all bit sizes must not grow beyond 0xB8*8 = 1472 */
|
||||
|
|
|
|||
|
|
@ -321,6 +321,7 @@ struct user_settings
|
|||
then according to timeout_values[] */
|
||||
#endif
|
||||
|
||||
bool next_folder; /* move to next folder */
|
||||
};
|
||||
|
||||
enum optiontype { INT, BOOL };
|
||||
|
|
|
|||
|
|
@ -1119,6 +1119,11 @@ static bool crossfade(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static bool next_folder(void)
|
||||
{
|
||||
return set_bool( str(LANG_NEXT_FOLDER), &global_settings.next_folder );
|
||||
}
|
||||
|
||||
static bool playback_settings_menu(void)
|
||||
{
|
||||
int m;
|
||||
|
|
@ -1139,6 +1144,7 @@ static bool playback_settings_menu(void)
|
|||
{ ID2P(LANG_SPDIF_ENABLE), spdif },
|
||||
#endif
|
||||
{ ID2P(LANG_ID3_ORDER), id3_order },
|
||||
{ ID2P(LANG_NEXT_FOLDER), next_folder },
|
||||
};
|
||||
|
||||
bool old_shuffle = global_settings.playlist_shuffle;
|
||||
|
|
|
|||
|
|
@ -731,7 +731,6 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
|
|||
|
||||
queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
|
||||
playing = false;
|
||||
is_playing = false;
|
||||
}
|
||||
*psize = 0; /* no more transfer */
|
||||
}
|
||||
|
|
@ -869,8 +868,9 @@ static void update_playlist(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* End of playlist */
|
||||
playlist_next(playlist_amount());
|
||||
/* End of playlist? */
|
||||
if (playlist_next(playlist_amount()) < 0)
|
||||
is_playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue