From 74d082c03892ae551cf4a72bb27af91fe8e1ed28 Mon Sep 17 00:00:00 2001 From: Hardeep Sidhu Date: Sat, 25 Jun 2005 04:46:25 +0000 Subject: Added new shuffle repeat mode that reshuffles playlist before repeating. Also added new shuffled insert mode that randomly inserts selected track(s) somewhere between current track and end of playlist. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6861 a1c6a512-1295-4272-9138-f99709370657 --- apps/lang/english.lang | 5 +++ apps/onplay.c | 9 ++++-- apps/playlist.c | 84 +++++++++++++++++++++++++++++++++++++++++--------- apps/playlist.h | 3 +- apps/screens.c | 6 +++- apps/settings.c | 2 +- apps/settings.h | 5 +-- apps/settings_menu.c | 5 +-- apps/status.c | 1 + 9 files changed, 97 insertions(+), 23 deletions(-) (limited to 'apps') diff --git a/apps/lang/english.lang b/apps/lang/english.lang index dbeaa929e0..8464e06126 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -3111,3 +3111,8 @@ desc: in playlist menu, reshuffles the order in which songs are played eng: "Reshuffle" voice: "Reshuffle" new: + +id: LANG_INSERT_SHUFFLED +desc: in onplay menu. insert a track/playlist randomly into dynamic playlist +eng: "Insert shuffled" +new: diff --git a/apps/onplay.c b/apps/onplay.c index dbb2ba42b9..d1b5285faa 100644 --- a/apps/onplay.c +++ b/apps/onplay.c @@ -244,8 +244,8 @@ static bool view_playlist(void) /* Sub-menu for playlist options */ static bool playlist_options(void) { - struct menu_item items[11]; - struct playlist_args args[11]; /* increase these 2 if you add entries! */ + struct menu_item items[12]; + struct playlist_args args[12]; /* increase these 2 if you add entries! */ int m, i=0, pstart=0, result; bool ret = false; @@ -296,6 +296,11 @@ static bool playlist_options(void) args[i].queue = false; i++; + items[i].desc = ID2P(LANG_INSERT_SHUFFLED); + args[i].position = PLAYLIST_INSERT_SHUFFLED; + args[i].queue = false; + i++; + items[i].desc = ID2P(LANG_QUEUE); args[i].position = PLAYLIST_INSERT; args[i].queue = true; diff --git a/apps/playlist.c b/apps/playlist.c index 8c9d6d11c7..ce2818eded 100644 --- a/apps/playlist.c +++ b/apps/playlist.c @@ -149,7 +149,8 @@ static int randomise_playlist(struct playlist_info* playlist, bool write); static int sort_playlist(struct playlist_info* playlist, bool start_current, bool write); -static int get_next_index(const struct playlist_info* playlist, int steps); +static int get_next_index(struct playlist_info* playlist, int steps, + int repeat_mode); static void find_and_set_playlist_index(struct playlist_info* playlist, unsigned int seek); static int compare(const void* p1, const void* p2); @@ -399,13 +400,15 @@ static int add_indices_to_playlist(struct playlist_info* playlist, /* * Add track to playlist at specified position. There are three special * positions that can be specified: - * PLAYLIST_PREPEND - Add track at beginning of playlist - * PLAYLIST_INSERT - Add track after current song. NOTE: If there - * are already inserted tracks then track is added - * to the end of the insertion list. - * PLAYLIST_INSERT_FIRST - Add track immediately after current song, no - * matter what other tracks have been inserted. - * PLAYLIST_INSERT_LAST - Add track to end of playlist + * PLAYLIST_PREPEND - Add track at beginning of playlist + * PLAYLIST_INSERT - Add track after current song. NOTE: If + * there are already inserted tracks then track + * is added to the end of the insertion list + * PLAYLIST_INSERT_FIRST - Add track immediately after current song, no + * matter what other tracks have been inserted + * PLAYLIST_INSERT_LAST - Add track to end of playlist + * PLAYLIST_INSERT_SHUFFLED - Add track at some random point between the + * current playing track and end of playlist */ static int add_track_to_playlist(struct playlist_info* playlist, const char *filename, int position, @@ -459,6 +462,24 @@ static int add_track_to_playlist(struct playlist_info* playlist, flags = PLAYLIST_INSERT_TYPE_APPEND; break; + case PLAYLIST_INSERT_SHUFFLED: + { + int offset; + int n = playlist->amount - + rotate_index(playlist, playlist->index); + + if (n > 0) + offset = rand() % n; + else + offset = 0; + + position = playlist->index + offset + 1; + if (position >= playlist->amount) + position -= playlist->amount; + + insert_position = position; + break; + } } if (queue) @@ -807,7 +828,8 @@ static int sort_playlist(struct playlist_info* playlist, bool start_current, * returns the index of the track that is "steps" away from current playing * track. */ -static int get_next_index(const struct playlist_info* playlist, int steps) +static int get_next_index(struct playlist_info* playlist, int steps, + int repeat_mode) { int current_index = playlist->index; int next_index = -1; @@ -815,8 +837,18 @@ static int get_next_index(const struct playlist_info* playlist, int steps) if (playlist->amount <= 0) return -1; - switch (global_settings.repeat_mode) + if (repeat_mode == -1) + repeat_mode = global_settings.repeat_mode; + + if (repeat_mode == REPEAT_SHUFFLE && + (!global_settings.playlist_shuffle || playlist->amount <= 1)) + repeat_mode = REPEAT_ALL; + + switch (repeat_mode) { + case REPEAT_SHUFFLE: + /* Treat repeat shuffle just like repeat off. At end of playlist, + play will be resumed in playlist_next() */ case REPEAT_OFF: { current_index = rotate_index(playlist, current_index); @@ -1634,7 +1666,13 @@ int playlist_start(int start_index, int offset) bool playlist_check(int steps) { struct playlist_info* playlist = ¤t_playlist; - int index = get_next_index(playlist, 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 */ + index = get_next_index(playlist, steps, REPEAT_ALL); + return (index >= 0); } @@ -1649,7 +1687,7 @@ char* playlist_peek(int steps) int index; bool control_file; - index = get_next_index(playlist, steps); + index = get_next_index(playlist, steps, -1); if (index < 0) return NULL; @@ -1705,7 +1743,7 @@ int playlist_next(int steps) /* We need to delete all the queued songs */ for (i=0, j=steps; iindices[index] & PLAYLIST_QUEUE_MASK) { @@ -1715,7 +1753,25 @@ int playlist_next(int steps) } } - index = get_next_index(playlist, steps); + index = get_next_index(playlist, steps, -1); + + if (index < 0) + { + /* end of playlist... or is it */ + if (global_settings.repeat_mode == REPEAT_SHUFFLE && + global_settings.playlist_shuffle && + playlist->amount > 1) + { + /* Repeat shuffle mode. Re-shuffle playlist and resume play */ + playlist->first_index = global_settings.resume_first_index = 0; + sort_playlist(playlist, false, false); + randomise_playlist(playlist, current_tick, false, true); + playlist_start(0, 0); + } + + return index; + } + playlist->index = index; if (playlist->last_insert_pos >= 0 && steps > 0) diff --git a/apps/playlist.h b/apps/playlist.h index b5a6e17426..5346cc8663 100644 --- a/apps/playlist.h +++ b/apps/playlist.h @@ -118,7 +118,8 @@ enum { PLAYLIST_PREPEND = -1, PLAYLIST_INSERT = -2, PLAYLIST_INSERT_LAST = -3, - PLAYLIST_INSERT_FIRST = -4 + PLAYLIST_INSERT_FIRST = -4, + PLAYLIST_INSERT_SHUFFLED = -5 }; enum { diff --git a/apps/screens.c b/apps/screens.c index 1ae7030822..81366141bb 100644 --- a/apps/screens.c +++ b/apps/screens.c @@ -585,9 +585,13 @@ bool quick_screen(int context, int button) case REPEAT_ONE: ptr = str(LANG_REPEAT_ONE); break; + + case REPEAT_SHUFFLE: + ptr = str(LANG_SHUFFLE); + break; } - lcd_getstringsize(str(LANG_REPEAT),&w,&h); + lcd_getstringsize(str(LANG_SHUFFLE),&w,&h); lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 - h*2, str(LANG_REPEAT)); lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 - h, str(LANG_F2_MODE)); lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2, ptr); diff --git a/apps/settings.c b/apps/settings.c index 77bb4cdbf4..60e41fcfdd 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -203,7 +203,7 @@ static const struct bit_entry rtc_bits[] = {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL }, {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL }, {32 | SIGNED, S_O(resume_seed), -1, NULL, NULL }, - {2, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one" }, + {2, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one,shuffle" }, /* LCD */ {6, S_O(contrast), 40, "contrast", NULL }, #ifdef CONFIG_BACKLIGHT diff --git a/apps/settings.h b/apps/settings.h index 7e0be44c41..bb4f5fbf32 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -224,7 +224,7 @@ struct user_settings /* misc options */ - int repeat_mode; /* 0=off 1=repeat all 2=repeat one */ + int repeat_mode; /* 0=off 1=repeat all 2=repeat one 3=shuffle */ int dirfilter; /* 0=display all, 1=only supported, 2=only music, 3=dirs+playlists, 4=ID3 database */ bool sort_case; /* dir sort order: 0=case insensitive, 1=sensitive */ @@ -387,7 +387,8 @@ extern const char rec_base_directory[]; #define SETTINGS_ALL 3 /* both */ /* repeat mode options */ -enum { REPEAT_OFF, REPEAT_ALL, REPEAT_ONE, NUM_REPEAT_MODES }; +enum { REPEAT_OFF, REPEAT_ALL, REPEAT_ONE, REPEAT_SHUFFLE, +NUM_REPEAT_MODES }; /* dir filter options */ /* Note: Any new filter modes need to be added before NUM_FILTER_MODES. diff --git a/apps/settings_menu.c b/apps/settings_menu.c index efca1a85fb..b10c7d32ab 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c @@ -584,12 +584,13 @@ static bool repeat_mode(void) static const struct opt_items names[] = { { STR(LANG_OFF) }, { STR(LANG_REPEAT_ALL) }, - { STR(LANG_REPEAT_ONE) } + { STR(LANG_REPEAT_ONE) }, + { STR(LANG_SHUFFLE) }, }; int old_repeat = global_settings.repeat_mode; result = set_option( str(LANG_REPEAT), &global_settings.repeat_mode, - INT, names, 3, NULL ); + INT, names, 4, NULL ); if (old_repeat != global_settings.repeat_mode) audio_flush_and_reload_tracks(); diff --git a/apps/status.c b/apps/status.c index ac11c17e1b..535337e8c1 100644 --- a/apps/status.c +++ b/apps/status.c @@ -260,6 +260,7 @@ void status_draw(bool force_redraw) break; case REPEAT_ALL: + case REPEAT_SHUFFLE: statusbar_icon_play_mode(Icon_Repeat); break; } -- cgit v1.2.3