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"
|
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:
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 = ¤t_playlist;
|
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);
|
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)
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue