mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 21:25:19 -05:00
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:
parent
1224d578e8
commit
74d082c038
10 changed files with 107 additions and 29 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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; i<j; i++)
|
||||
{
|
||||
index = get_next_index(playlist, i);
|
||||
index = get_next_index(playlist, i, -1);
|
||||
|
||||
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;
|
||||
|
||||
if (playlist->last_insert_pos >= 0 && steps > 0)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ void status_draw(bool force_redraw)
|
|||
break;
|
||||
|
||||
case REPEAT_ALL:
|
||||
case REPEAT_SHUFFLE:
|
||||
statusbar_icon_play_mode(Icon_Repeat);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -862,14 +862,15 @@ static void stop_playing(void)
|
|||
|
||||
static void update_playlist(void)
|
||||
{
|
||||
int index;
|
||||
struct trackdata *track;
|
||||
|
||||
if (num_tracks_in_memory() > 0)
|
||||
{
|
||||
track = get_trackdata(0);
|
||||
index = playlist_next(track->id3.index);
|
||||
track->id3.index = index;
|
||||
struct trackdata *track = get_trackdata(0);
|
||||
track->id3.index = playlist_next(track->id3.index);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* End of playlist */
|
||||
playlist_next(playlist_amount());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1189,6 +1190,9 @@ static void mpeg_thread(void)
|
|||
if (new_file(1) < 0) {
|
||||
DEBUGF("No more files to play\n");
|
||||
filling = false;
|
||||
|
||||
update_playlist();
|
||||
current_track_counter++;
|
||||
} else {
|
||||
/* Make it read more data */
|
||||
filling = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue