diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/lang/english.lang | 5 | ||||
-rw-r--r-- | apps/onplay.c | 9 | ||||
-rw-r--r-- | apps/playlist.c | 84 | ||||
-rw-r--r-- | apps/playlist.h | 3 | ||||
-rw-r--r-- | apps/screens.c | 6 | ||||
-rw-r--r-- | apps/settings.c | 2 | ||||
-rw-r--r-- | apps/settings.h | 5 | ||||
-rw-r--r-- | apps/settings_menu.c | 5 | ||||
-rw-r--r-- | apps/status.c | 1 |
9 files changed, 97 insertions, 23 deletions
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 | |||
3111 | eng: "Reshuffle" | 3111 | eng: "Reshuffle" |
3112 | voice: "Reshuffle" | 3112 | voice: "Reshuffle" |
3113 | new: | 3113 | new: |
3114 | |||
3115 | id: LANG_INSERT_SHUFFLED | ||
3116 | desc: in onplay menu. insert a track/playlist randomly into dynamic playlist | ||
3117 | eng: "Insert shuffled" | ||
3118 | 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) | |||
244 | /* Sub-menu for playlist options */ | 244 | /* Sub-menu for playlist options */ |
245 | static bool playlist_options(void) | 245 | static bool playlist_options(void) |
246 | { | 246 | { |
247 | struct menu_item items[11]; | 247 | struct menu_item items[12]; |
248 | struct playlist_args args[11]; /* increase these 2 if you add entries! */ | 248 | struct playlist_args args[12]; /* increase these 2 if you add entries! */ |
249 | int m, i=0, pstart=0, result; | 249 | int m, i=0, pstart=0, result; |
250 | bool ret = false; | 250 | bool ret = false; |
251 | 251 | ||
@@ -296,6 +296,11 @@ static bool playlist_options(void) | |||
296 | args[i].queue = false; | 296 | args[i].queue = false; |
297 | i++; | 297 | i++; |
298 | 298 | ||
299 | items[i].desc = ID2P(LANG_INSERT_SHUFFLED); | ||
300 | args[i].position = PLAYLIST_INSERT_SHUFFLED; | ||
301 | args[i].queue = false; | ||
302 | i++; | ||
303 | |||
299 | items[i].desc = ID2P(LANG_QUEUE); | 304 | items[i].desc = ID2P(LANG_QUEUE); |
300 | args[i].position = PLAYLIST_INSERT; | 305 | args[i].position = PLAYLIST_INSERT; |
301 | args[i].queue = true; | 306 | 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, | |||
149 | bool write); | 149 | bool write); |
150 | static int sort_playlist(struct playlist_info* playlist, bool start_current, | 150 | static int sort_playlist(struct playlist_info* playlist, bool start_current, |
151 | bool write); | 151 | bool write); |
152 | static int get_next_index(const struct playlist_info* playlist, int steps); | 152 | static int get_next_index(struct playlist_info* playlist, int steps, |
153 | int repeat_mode); | ||
153 | static void find_and_set_playlist_index(struct playlist_info* playlist, | 154 | static void find_and_set_playlist_index(struct playlist_info* playlist, |
154 | unsigned int seek); | 155 | unsigned int seek); |
155 | static int compare(const void* p1, const void* p2); | 156 | static int compare(const void* p1, const void* p2); |
@@ -399,13 +400,15 @@ static int add_indices_to_playlist(struct playlist_info* playlist, | |||
399 | /* | 400 | /* |
400 | * Add track to playlist at specified position. There are three special | 401 | * Add track to playlist at specified position. There are three special |
401 | * positions that can be specified: | 402 | * positions that can be specified: |
402 | * PLAYLIST_PREPEND - Add track at beginning of playlist | 403 | * PLAYLIST_PREPEND - Add track at beginning of playlist |
403 | * PLAYLIST_INSERT - Add track after current song. NOTE: If there | 404 | * PLAYLIST_INSERT - Add track after current song. NOTE: If |
404 | * are already inserted tracks then track is added | 405 | * there are already inserted tracks then track |
405 | * to the end of the insertion list. | 406 | * is added to the end of the insertion list |
406 | * PLAYLIST_INSERT_FIRST - Add track immediately after current song, no | 407 | * PLAYLIST_INSERT_FIRST - Add track immediately after current song, no |
407 | * matter what other tracks have been inserted. | 408 | * matter what other tracks have been inserted |
408 | * PLAYLIST_INSERT_LAST - Add track to end of playlist | 409 | * PLAYLIST_INSERT_LAST - Add track to end of playlist |
410 | * PLAYLIST_INSERT_SHUFFLED - Add track at some random point between the | ||
411 | * current playing track and end of playlist | ||
409 | */ | 412 | */ |
410 | static int add_track_to_playlist(struct playlist_info* playlist, | 413 | static int add_track_to_playlist(struct playlist_info* playlist, |
411 | const char *filename, int position, | 414 | const char *filename, int position, |
@@ -459,6 +462,24 @@ static int add_track_to_playlist(struct playlist_info* playlist, | |||
459 | 462 | ||
460 | flags = PLAYLIST_INSERT_TYPE_APPEND; | 463 | flags = PLAYLIST_INSERT_TYPE_APPEND; |
461 | break; | 464 | break; |
465 | case PLAYLIST_INSERT_SHUFFLED: | ||
466 | { | ||
467 | int offset; | ||
468 | int n = playlist->amount - | ||
469 | rotate_index(playlist, playlist->index); | ||
470 | |||
471 | if (n > 0) | ||
472 | offset = rand() % n; | ||
473 | else | ||
474 | offset = 0; | ||
475 | |||
476 | position = playlist->index + offset + 1; | ||
477 | if (position >= playlist->amount) | ||
478 | position -= playlist->amount; | ||
479 | |||
480 | insert_position = position; | ||
481 | break; | ||
482 | } | ||
462 | } | 483 | } |
463 | 484 | ||
464 | if (queue) | 485 | if (queue) |
@@ -807,7 +828,8 @@ static int sort_playlist(struct playlist_info* playlist, bool start_current, | |||
807 | * returns the index of the track that is "steps" away from current playing | 828 | * returns the index of the track that is "steps" away from current playing |
808 | * track. | 829 | * track. |
809 | */ | 830 | */ |
810 | static int get_next_index(const struct playlist_info* playlist, int steps) | 831 | static int get_next_index(struct playlist_info* playlist, int steps, |
832 | int repeat_mode) | ||
811 | { | 833 | { |
812 | int current_index = playlist->index; | 834 | int current_index = playlist->index; |
813 | int next_index = -1; | 835 | int next_index = -1; |
@@ -815,8 +837,18 @@ static int get_next_index(const struct playlist_info* playlist, int steps) | |||
815 | if (playlist->amount <= 0) | 837 | if (playlist->amount <= 0) |
816 | return -1; | 838 | return -1; |
817 | 839 | ||
818 | switch (global_settings.repeat_mode) | 840 | if (repeat_mode == -1) |
841 | repeat_mode = global_settings.repeat_mode; | ||
842 | |||
843 | if (repeat_mode == REPEAT_SHUFFLE && | ||
844 | (!global_settings.playlist_shuffle || playlist->amount <= 1)) | ||
845 | repeat_mode = REPEAT_ALL; | ||
846 | |||
847 | switch (repeat_mode) | ||
819 | { | 848 | { |
849 | case REPEAT_SHUFFLE: | ||
850 | /* Treat repeat shuffle just like repeat off. At end of playlist, | ||
851 | play will be resumed in playlist_next() */ | ||
820 | case REPEAT_OFF: | 852 | case REPEAT_OFF: |
821 | { | 853 | { |
822 | current_index = rotate_index(playlist, current_index); | 854 | current_index = rotate_index(playlist, current_index); |
@@ -1634,7 +1666,13 @@ int playlist_start(int start_index, int offset) | |||
1634 | bool playlist_check(int steps) | 1666 | bool playlist_check(int steps) |
1635 | { | 1667 | { |
1636 | struct playlist_info* playlist = ¤t_playlist; | 1668 | struct playlist_info* playlist = ¤t_playlist; |
1637 | int index = get_next_index(playlist, steps); | 1669 | int index = get_next_index(playlist, steps, -1); |
1670 | |||
1671 | if (index < 0 && steps >= 0 && | ||
1672 | global_settings.repeat_mode == REPEAT_SHUFFLE) | ||
1673 | /* shuffle repeat is the same as repeat all for check purposes */ | ||
1674 | index = get_next_index(playlist, steps, REPEAT_ALL); | ||
1675 | |||
1638 | return (index >= 0); | 1676 | return (index >= 0); |
1639 | } | 1677 | } |
1640 | 1678 | ||
@@ -1649,7 +1687,7 @@ char* playlist_peek(int steps) | |||
1649 | int index; | 1687 | int index; |
1650 | bool control_file; | 1688 | bool control_file; |
1651 | 1689 | ||
1652 | index = get_next_index(playlist, steps); | 1690 | index = get_next_index(playlist, steps, -1); |
1653 | if (index < 0) | 1691 | if (index < 0) |
1654 | return NULL; | 1692 | return NULL; |
1655 | 1693 | ||
@@ -1705,7 +1743,7 @@ int playlist_next(int steps) | |||
1705 | /* We need to delete all the queued songs */ | 1743 | /* We need to delete all the queued songs */ |
1706 | for (i=0, j=steps; i<j; i++) | 1744 | for (i=0, j=steps; i<j; i++) |
1707 | { | 1745 | { |
1708 | index = get_next_index(playlist, i); | 1746 | index = get_next_index(playlist, i, -1); |
1709 | 1747 | ||
1710 | if (playlist->indices[index] & PLAYLIST_QUEUE_MASK) | 1748 | if (playlist->indices[index] & PLAYLIST_QUEUE_MASK) |
1711 | { | 1749 | { |
@@ -1715,7 +1753,25 @@ int playlist_next(int steps) | |||
1715 | } | 1753 | } |
1716 | } | 1754 | } |
1717 | 1755 | ||
1718 | index = get_next_index(playlist, steps); | 1756 | index = get_next_index(playlist, steps, -1); |
1757 | |||
1758 | if (index < 0) | ||
1759 | { | ||
1760 | /* end of playlist... or is it */ | ||
1761 | if (global_settings.repeat_mode == REPEAT_SHUFFLE && | ||
1762 | global_settings.playlist_shuffle && | ||
1763 | playlist->amount > 1) | ||
1764 | { | ||
1765 | /* Repeat shuffle mode. Re-shuffle playlist and resume play */ | ||
1766 | playlist->first_index = global_settings.resume_first_index = 0; | ||
1767 | sort_playlist(playlist, false, false); | ||
1768 | randomise_playlist(playlist, current_tick, false, true); | ||
1769 | playlist_start(0, 0); | ||
1770 | } | ||
1771 | |||
1772 | return index; | ||
1773 | } | ||
1774 | |||
1719 | playlist->index = index; | 1775 | playlist->index = index; |
1720 | 1776 | ||
1721 | if (playlist->last_insert_pos >= 0 && steps > 0) | 1777 | 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 { | |||
118 | PLAYLIST_PREPEND = -1, | 118 | PLAYLIST_PREPEND = -1, |
119 | PLAYLIST_INSERT = -2, | 119 | PLAYLIST_INSERT = -2, |
120 | PLAYLIST_INSERT_LAST = -3, | 120 | PLAYLIST_INSERT_LAST = -3, |
121 | PLAYLIST_INSERT_FIRST = -4 | 121 | PLAYLIST_INSERT_FIRST = -4, |
122 | PLAYLIST_INSERT_SHUFFLED = -5 | ||
122 | }; | 123 | }; |
123 | 124 | ||
124 | enum { | 125 | 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) | |||
585 | case REPEAT_ONE: | 585 | case REPEAT_ONE: |
586 | ptr = str(LANG_REPEAT_ONE); | 586 | ptr = str(LANG_REPEAT_ONE); |
587 | break; | 587 | break; |
588 | |||
589 | case REPEAT_SHUFFLE: | ||
590 | ptr = str(LANG_SHUFFLE); | ||
591 | break; | ||
588 | } | 592 | } |
589 | 593 | ||
590 | lcd_getstringsize(str(LANG_REPEAT),&w,&h); | 594 | lcd_getstringsize(str(LANG_SHUFFLE),&w,&h); |
591 | lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 - h*2, str(LANG_REPEAT)); | 595 | lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 - h*2, str(LANG_REPEAT)); |
592 | lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 - h, str(LANG_F2_MODE)); | 596 | lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2 - h, str(LANG_F2_MODE)); |
593 | lcd_putsxy(LCD_WIDTH - w, LCD_HEIGHT/2, ptr); | 597 | 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[] = | |||
203 | {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL }, | 203 | {16 | SIGNED, S_O(resume_first_index), 0, NULL, NULL }, |
204 | {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL }, | 204 | {32 | SIGNED, S_O(resume_offset), -1, NULL, NULL }, |
205 | {32 | SIGNED, S_O(resume_seed), -1, NULL, NULL }, | 205 | {32 | SIGNED, S_O(resume_seed), -1, NULL, NULL }, |
206 | {2, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one" }, | 206 | {2, S_O(repeat_mode), REPEAT_ALL, "repeat", "off,all,one,shuffle" }, |
207 | /* LCD */ | 207 | /* LCD */ |
208 | {6, S_O(contrast), 40, "contrast", NULL }, | 208 | {6, S_O(contrast), 40, "contrast", NULL }, |
209 | #ifdef CONFIG_BACKLIGHT | 209 | #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 | |||
224 | 224 | ||
225 | /* misc options */ | 225 | /* misc options */ |
226 | 226 | ||
227 | int repeat_mode; /* 0=off 1=repeat all 2=repeat one */ | 227 | int repeat_mode; /* 0=off 1=repeat all 2=repeat one 3=shuffle */ |
228 | int dirfilter; /* 0=display all, 1=only supported, 2=only music, | 228 | int dirfilter; /* 0=display all, 1=only supported, 2=only music, |
229 | 3=dirs+playlists, 4=ID3 database */ | 229 | 3=dirs+playlists, 4=ID3 database */ |
230 | bool sort_case; /* dir sort order: 0=case insensitive, 1=sensitive */ | 230 | bool sort_case; /* dir sort order: 0=case insensitive, 1=sensitive */ |
@@ -387,7 +387,8 @@ extern const char rec_base_directory[]; | |||
387 | #define SETTINGS_ALL 3 /* both */ | 387 | #define SETTINGS_ALL 3 /* both */ |
388 | 388 | ||
389 | /* repeat mode options */ | 389 | /* repeat mode options */ |
390 | enum { REPEAT_OFF, REPEAT_ALL, REPEAT_ONE, NUM_REPEAT_MODES }; | 390 | enum { REPEAT_OFF, REPEAT_ALL, REPEAT_ONE, REPEAT_SHUFFLE, |
391 | NUM_REPEAT_MODES }; | ||
391 | 392 | ||
392 | /* dir filter options */ | 393 | /* dir filter options */ |
393 | /* Note: Any new filter modes need to be added before NUM_FILTER_MODES. | 394 | /* 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) | |||
584 | static const struct opt_items names[] = { | 584 | static const struct opt_items names[] = { |
585 | { STR(LANG_OFF) }, | 585 | { STR(LANG_OFF) }, |
586 | { STR(LANG_REPEAT_ALL) }, | 586 | { STR(LANG_REPEAT_ALL) }, |
587 | { STR(LANG_REPEAT_ONE) } | 587 | { STR(LANG_REPEAT_ONE) }, |
588 | { STR(LANG_SHUFFLE) }, | ||
588 | }; | 589 | }; |
589 | int old_repeat = global_settings.repeat_mode; | 590 | int old_repeat = global_settings.repeat_mode; |
590 | 591 | ||
591 | result = set_option( str(LANG_REPEAT), &global_settings.repeat_mode, | 592 | result = set_option( str(LANG_REPEAT), &global_settings.repeat_mode, |
592 | INT, names, 3, NULL ); | 593 | INT, names, 4, NULL ); |
593 | 594 | ||
594 | if (old_repeat != global_settings.repeat_mode) | 595 | if (old_repeat != global_settings.repeat_mode) |
595 | audio_flush_and_reload_tracks(); | 596 | 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) | |||
260 | break; | 260 | break; |
261 | 261 | ||
262 | case REPEAT_ALL: | 262 | case REPEAT_ALL: |
263 | case REPEAT_SHUFFLE: | ||
263 | statusbar_icon_play_mode(Icon_Repeat); | 264 | statusbar_icon_play_mode(Icon_Repeat); |
264 | break; | 265 | break; |
265 | } | 266 | } |