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
This commit is contained in:
Hardeep Sidhu 2005-06-25 04:46:25 +00:00
parent 1224d578e8
commit 74d082c038
10 changed files with 107 additions and 29 deletions

View file

@ -3111,3 +3111,8 @@ desc: in playlist menu, reshuffles the order in which songs are played
eng: "Reshuffle" eng: "Reshuffle"
voice: "Reshuffle" voice: "Reshuffle"
new: new:
id: LANG_INSERT_SHUFFLED
desc: in onplay menu. insert a track/playlist randomly into dynamic playlist
eng: "Insert shuffled"
new:

View file

@ -244,8 +244,8 @@ static bool view_playlist(void)
/* Sub-menu for playlist options */ /* Sub-menu for playlist options */
static bool playlist_options(void) static bool playlist_options(void)
{ {
struct menu_item items[11]; struct menu_item items[12];
struct playlist_args args[11]; /* increase these 2 if you add entries! */ struct playlist_args args[12]; /* increase these 2 if you add entries! */
int m, i=0, pstart=0, result; int m, i=0, pstart=0, result;
bool ret = false; bool ret = false;
@ -296,6 +296,11 @@ static bool playlist_options(void)
args[i].queue = false; args[i].queue = false;
i++; 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); items[i].desc = ID2P(LANG_QUEUE);
args[i].position = PLAYLIST_INSERT; args[i].position = PLAYLIST_INSERT;
args[i].queue = true; args[i].queue = true;

View file

@ -149,7 +149,8 @@ static int randomise_playlist(struct playlist_info* playlist,
bool write); bool write);
static int sort_playlist(struct playlist_info* playlist, bool start_current, static int sort_playlist(struct playlist_info* playlist, bool start_current,
bool write); 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, static void find_and_set_playlist_index(struct playlist_info* playlist,
unsigned int seek); unsigned int seek);
static int compare(const void* p1, const void* p2); static int compare(const void* p1, const void* p2);
@ -400,12 +401,14 @@ 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 three special
* positions that can be specified: * positions that can be specified:
* PLAYLIST_PREPEND - Add track at beginning of playlist * PLAYLIST_PREPEND - Add track at beginning of playlist
* PLAYLIST_INSERT - Add track after current song. NOTE: If there * PLAYLIST_INSERT - Add track after current song. NOTE: If
* are already inserted tracks then track is added * there are already inserted tracks then track
* to the end of the insertion list. * is added to the end of the insertion list
* PLAYLIST_INSERT_FIRST - Add track immediately after current song, no * PLAYLIST_INSERT_FIRST - Add track immediately after current song, no
* matter what other tracks have been inserted. * matter what other tracks have been inserted
* PLAYLIST_INSERT_LAST - Add track to end of playlist * 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, static int add_track_to_playlist(struct playlist_info* playlist,
const char *filename, int position, const char *filename, int position,
@ -459,6 +462,24 @@ static int add_track_to_playlist(struct playlist_info* playlist,
flags = PLAYLIST_INSERT_TYPE_APPEND; flags = PLAYLIST_INSERT_TYPE_APPEND;
break; 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) 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 * returns the index of the track that is "steps" away from current playing
* track. * 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 current_index = playlist->index;
int next_index = -1; int next_index = -1;
@ -815,8 +837,18 @@ static int get_next_index(const struct playlist_info* playlist, int steps)
if (playlist->amount <= 0) if (playlist->amount <= 0)
return -1; 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: case REPEAT_OFF:
{ {
current_index = rotate_index(playlist, current_index); current_index = rotate_index(playlist, current_index);
@ -1634,7 +1666,13 @@ int playlist_start(int start_index, int offset)
bool playlist_check(int steps) bool playlist_check(int steps)
{ {
struct playlist_info* playlist = &current_playlist; struct playlist_info* playlist = &current_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); return (index >= 0);
} }
@ -1649,7 +1687,7 @@ char* playlist_peek(int steps)
int index; int index;
bool control_file; bool control_file;
index = get_next_index(playlist, steps); index = get_next_index(playlist, steps, -1);
if (index < 0) if (index < 0)
return NULL; return NULL;
@ -1705,7 +1743,7 @@ int playlist_next(int steps)
/* We need to delete all the queued songs */ /* We need to delete all the queued songs */
for (i=0, j=steps; i<j; i++) for (i=0, j=steps; i<j; i++)
{ {
index = get_next_index(playlist, i); index = get_next_index(playlist, i, -1);
if (playlist->indices[index] & PLAYLIST_QUEUE_MASK) if (playlist->indices[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; playlist->index = index;
if (playlist->last_insert_pos >= 0 && steps > 0) if (playlist->last_insert_pos >= 0 && steps > 0)

View file

@ -118,7 +118,8 @@ enum {
PLAYLIST_PREPEND = -1, PLAYLIST_PREPEND = -1,
PLAYLIST_INSERT = -2, PLAYLIST_INSERT = -2,
PLAYLIST_INSERT_LAST = -3, PLAYLIST_INSERT_LAST = -3,
PLAYLIST_INSERT_FIRST = -4 PLAYLIST_INSERT_FIRST = -4,
PLAYLIST_INSERT_SHUFFLED = -5
}; };
enum { enum {

View file

@ -585,9 +585,13 @@ bool quick_screen(int context, int button)
case REPEAT_ONE: case REPEAT_ONE:
ptr = str(LANG_REPEAT_ONE); ptr = str(LANG_REPEAT_ONE);
break; 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*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 - h, str(LANG_F2_MODE));
lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2, ptr); lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2, ptr);

View file

@ -203,7 +203,7 @@ static const struct bit_entry rtc_bits[] =
{16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL }, {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL },
{32 | SIGNED, S_O(resume_offset), -1, NULL, NULL }, {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL },
{32 | SIGNED, S_O(resume_seed), -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 */ /* LCD */
{6, S_O(contrast), 40, "contrast", NULL }, {6, S_O(contrast), 40, "contrast", NULL },
#ifdef CONFIG_BACKLIGHT #ifdef CONFIG_BACKLIGHT

View file

@ -224,7 +224,7 @@ struct user_settings
/* misc options */ /* 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, int dirfilter; /* 0=display all, 1=only supported, 2=only music,
3=dirs+playlists, 4=ID3 database */ 3=dirs+playlists, 4=ID3 database */
bool sort_case; /* dir sort order: 0=case insensitive, 1=sensitive */ 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 */ #define SETTINGS_ALL 3 /* both */
/* repeat mode options */ /* 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 */ /* dir filter options */
/* Note: Any new filter modes need to be added before NUM_FILTER_MODES. /* Note: Any new filter modes need to be added before NUM_FILTER_MODES.

View file

@ -584,12 +584,13 @@ static bool repeat_mode(void)
static const struct opt_items names[] = { static const struct opt_items names[] = {
{ STR(LANG_OFF) }, { STR(LANG_OFF) },
{ STR(LANG_REPEAT_ALL) }, { STR(LANG_REPEAT_ALL) },
{ STR(LANG_REPEAT_ONE) } { STR(LANG_REPEAT_ONE) },
{ STR(LANG_SHUFFLE) },
}; };
int old_repeat = global_settings.repeat_mode; int old_repeat = global_settings.repeat_mode;
result = set_option( str(LANG_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) if (old_repeat != global_settings.repeat_mode)
audio_flush_and_reload_tracks(); audio_flush_and_reload_tracks();

View file

@ -260,6 +260,7 @@ void status_draw(bool force_redraw)
break; break;
case REPEAT_ALL: case REPEAT_ALL:
case REPEAT_SHUFFLE:
statusbar_icon_play_mode(Icon_Repeat); statusbar_icon_play_mode(Icon_Repeat);
break; break;
} }

View file

@ -862,14 +862,15 @@ static void stop_playing(void)
static void update_playlist(void) static void update_playlist(void)
{ {
int index;
struct trackdata *track;
if (num_tracks_in_memory() > 0) if (num_tracks_in_memory() > 0)
{ {
track = get_trackdata(0); struct trackdata *track = get_trackdata(0);
index = playlist_next(track->id3.index); track->id3.index = playlist_next(track->id3.index);
track->id3.index = index; }
else
{
/* End of playlist */
playlist_next(playlist_amount());
} }
} }
@ -1189,6 +1190,9 @@ static void mpeg_thread(void)
if (new_file(1) < 0) { if (new_file(1) < 0) {
DEBUGF("No more files to play\n"); DEBUGF("No more files to play\n");
filling = false; filling = false;
update_playlist();
current_track_counter++;
} else { } else {
/* Make it read more data */ /* Make it read more data */
filling = true; filling = true;