summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHardeep Sidhu <dyp@pobox.com>2005-06-25 04:46:25 +0000
committerHardeep Sidhu <dyp@pobox.com>2005-06-25 04:46:25 +0000
commit74d082c03892ae551cf4a72bb27af91fe8e1ed28 (patch)
tree227ede22869e6aa2e4f919a38cc3638ee0d76cfe
parent1224d578e8ef250cacc86ba3e97408446867baa6 (diff)
downloadrockbox-74d082c03892ae551cf4a72bb27af91fe8e1ed28.zip
rockbox-74d082c03892ae551cf4a72bb27af91fe8e1ed28.tar.gz
rockbox-74d082c03892ae551cf4a72bb27af91fe8e1ed28.tar.bz2
rockbox-74d082c03892ae551cf4a72bb27af91fe8e1ed28.tar.xz
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
-rw-r--r--apps/lang/english.lang5
-rw-r--r--apps/onplay.c9
-rw-r--r--apps/playlist.c84
-rw-r--r--apps/playlist.h3
-rw-r--r--apps/screens.c6
-rw-r--r--apps/settings.c2
-rw-r--r--apps/settings.h5
-rw-r--r--apps/settings_menu.c5
-rw-r--r--apps/status.c1
-rw-r--r--firmware/mpeg.c16
10 files changed, 107 insertions, 29 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index dbeaa92..8464e06 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 dbb2ba4..d1b5285 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 8c9d6d1..ce2818e 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 = &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);
}
@@ -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)
diff --git a/apps/playlist.h b/apps/playlist.h
index b5a6e17..5346cc8 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 1ae7030..8136614 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 77bb4cd..60e41fc 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 7e0be44..bb4f5fb 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 efca1a8..b10c7d3 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 ac11c17..535337e 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;
}
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index e4ea8d6..092447f 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -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;