diff options
-rw-r--r-- | apps/filetree.c | 8 | ||||
-rw-r--r-- | apps/lang/english.lang | 6 | ||||
-rw-r--r-- | apps/playback.c | 45 | ||||
-rw-r--r-- | apps/playlist.c | 110 | ||||
-rw-r--r-- | apps/playlist.h | 1 | ||||
-rw-r--r-- | apps/settings.c | 2 | ||||
-rw-r--r-- | apps/wps.c | 14 | ||||
-rw-r--r-- | apps/wps.h | 2 |
8 files changed, 166 insertions, 22 deletions
diff --git a/apps/filetree.c b/apps/filetree.c index e8b8df73ad..8a365cc574 100644 --- a/apps/filetree.c +++ b/apps/filetree.c | |||
@@ -172,12 +172,18 @@ static int compare(const void* p1, const void* p2) | |||
172 | return t1 - t2; | 172 | return t1 - t2; |
173 | /* else fall through to alphabetical sorting */ | 173 | /* else fall through to alphabetical sorting */ |
174 | } | 174 | } |
175 | case 0: /* sort alphabetically */ | 175 | case 0: /* sort alphabetically asc */ |
176 | if (global_settings.sort_case) | 176 | if (global_settings.sort_case) |
177 | return strncmp(e1->name, e2->name, MAX_PATH); | 177 | return strncmp(e1->name, e2->name, MAX_PATH); |
178 | else | 178 | else |
179 | return strncasecmp(e1->name, e2->name, MAX_PATH); | 179 | return strncasecmp(e1->name, e2->name, MAX_PATH); |
180 | 180 | ||
181 | case 4: /* sort alphabetically desc */ | ||
182 | if (global_settings.sort_case) | ||
183 | return strncmp(e2->name, e1->name, MAX_PATH); | ||
184 | else | ||
185 | return strncasecmp(e2->name, e1->name, MAX_PATH); | ||
186 | |||
181 | case 1: /* sort date */ | 187 | case 1: /* sort date */ |
182 | return e1->time_write - e2->time_write; | 188 | return e1->time_write - e2->time_write; |
183 | 189 | ||
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 94f434f2f4..3d9486a79f 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -3144,9 +3144,9 @@ voice: "Optical output" | |||
3144 | new: | 3144 | new: |
3145 | 3145 | ||
3146 | id: LANG_NEXT_FOLDER | 3146 | id: LANG_NEXT_FOLDER |
3147 | desc: in settings_menu. Should we move to next folder when current one ends | 3147 | desc: in settings_menu. Should we allow skip directories and move to next folder when current one ends |
3148 | eng: "Move to Next Folder" | 3148 | eng: "Directory navigation" |
3149 | voice: "Move to Next Folder" | 3149 | voice: "Directory navigation" |
3150 | new: | 3150 | new: |
3151 | 3151 | ||
3152 | id: LANG_RUNTIMEDB_ACTIVE | 3152 | id: LANG_RUNTIMEDB_ACTIVE |
diff --git a/apps/playback.c b/apps/playback.c index caaee8c5f5..8d869ceda3 100644 --- a/apps/playback.c +++ b/apps/playback.c | |||
@@ -92,6 +92,8 @@ static volatile bool paused; | |||
92 | #define AUDIO_CODEC_DONE 9 | 92 | #define AUDIO_CODEC_DONE 9 |
93 | #define AUDIO_FLUSH 10 | 93 | #define AUDIO_FLUSH 10 |
94 | #define AUDIO_TRACK_CHANGED 11 | 94 | #define AUDIO_TRACK_CHANGED 11 |
95 | #define AUDIO_DIR_NEXT 12 | ||
96 | #define AUDIO_DIR_PREV 13 | ||
95 | 97 | ||
96 | #define CODEC_LOAD 1 | 98 | #define CODEC_LOAD 1 |
97 | #define CODEC_LOAD_DISK 2 | 99 | #define CODEC_LOAD_DISK 2 |
@@ -1653,6 +1655,24 @@ static void initiate_track_change(int peek_index) | |||
1653 | codec_track_changed(); | 1655 | codec_track_changed(); |
1654 | } | 1656 | } |
1655 | 1657 | ||
1658 | static void initiate_dir_change(int direction) | ||
1659 | { | ||
1660 | if(!playlist_next_dir(direction)) | ||
1661 | return; | ||
1662 | |||
1663 | /* Detect if disk is spinning.. */ | ||
1664 | if (filling) { | ||
1665 | queue_post(&audio_queue, AUDIO_PLAY, 0); | ||
1666 | } else { | ||
1667 | new_track = 0; | ||
1668 | ci.reload_codec = true; | ||
1669 | if (!pcmbuf_is_crossfade_enabled()) | ||
1670 | pcmbuf_flush_audio(); | ||
1671 | } | ||
1672 | |||
1673 | codec_track_changed(); | ||
1674 | } | ||
1675 | |||
1656 | void audio_thread(void) | 1676 | void audio_thread(void) |
1657 | { | 1677 | { |
1658 | struct event ev; | 1678 | struct event ev; |
@@ -1735,6 +1755,21 @@ void audio_thread(void) | |||
1735 | initiate_track_change(-1); | 1755 | initiate_track_change(-1); |
1736 | break; | 1756 | break; |
1737 | 1757 | ||
1758 | |||
1759 | case AUDIO_DIR_NEXT: | ||
1760 | logf("audio_dir_next"); | ||
1761 | if (global_settings.beep) | ||
1762 | pcmbuf_beep(5000, 100, 2500*global_settings.beep); | ||
1763 | initiate_dir_change(1); | ||
1764 | break; | ||
1765 | |||
1766 | case AUDIO_DIR_PREV: | ||
1767 | logf("audio_dir_prev"); | ||
1768 | if (global_settings.beep) | ||
1769 | pcmbuf_beep(5000, 100, 2500*global_settings.beep); | ||
1770 | initiate_dir_change(-1); | ||
1771 | break; | ||
1772 | |||
1738 | case AUDIO_FLUSH: | 1773 | case AUDIO_FLUSH: |
1739 | audio_invalidate_tracks(); | 1774 | audio_invalidate_tracks(); |
1740 | break ; | 1775 | break ; |
@@ -2008,6 +2043,16 @@ void audio_prev(void) | |||
2008 | queue_post(&audio_queue, AUDIO_PREV, 0); | 2043 | queue_post(&audio_queue, AUDIO_PREV, 0); |
2009 | } | 2044 | } |
2010 | 2045 | ||
2046 | void audio_next_dir(void) | ||
2047 | { | ||
2048 | queue_post(&audio_queue, AUDIO_DIR_NEXT, 0); | ||
2049 | } | ||
2050 | |||
2051 | void audio_prev_dir(void) | ||
2052 | { | ||
2053 | queue_post(&audio_queue, AUDIO_DIR_PREV, 0); | ||
2054 | } | ||
2055 | |||
2011 | void audio_ff_rewind(int newpos) | 2056 | void audio_ff_rewind(int newpos) |
2012 | { | 2057 | { |
2013 | logf("rewind: %d", newpos); | 2058 | logf("rewind: %d", newpos); |
diff --git a/apps/playlist.c b/apps/playlist.c index 2646a27040..9ab1ad9f4a 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -162,6 +162,8 @@ static int compare(const void* p1, const void* p2); | |||
162 | static int get_filename(struct playlist_info* playlist, int seek, | 162 | static int get_filename(struct playlist_info* playlist, int seek, |
163 | bool control_file, char *buf, int buf_length); | 163 | bool control_file, char *buf, int buf_length); |
164 | static int get_next_directory(char *dir); | 164 | static int get_next_directory(char *dir); |
165 | static int get_next_dir(char *dir, bool is_forward, bool recursion); | ||
166 | static int get_previous_directory(char *dir); | ||
165 | static int check_subdir_for_music(char *dir, char *subdir); | 167 | static int check_subdir_for_music(char *dir, char *subdir); |
166 | static int format_track_path(char *dest, char *src, int buf_length, int max, | 168 | static int format_track_path(char *dest, char *src, int buf_length, int max, |
167 | char *dir); | 169 | char *dir); |
@@ -1098,26 +1100,53 @@ static int get_filename(struct playlist_info* playlist, int seek, | |||
1098 | return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf)); | 1100 | return (format_track_path(buf, tmp_buf, buf_length, max, dir_buf)); |
1099 | } | 1101 | } |
1100 | 1102 | ||
1103 | static int get_next_directory(char *dir){ | ||
1104 | return get_next_dir(dir,true,false); | ||
1105 | } | ||
1106 | |||
1107 | static int get_previous_directory(char *dir){ | ||
1108 | return get_next_dir(dir,false,false); | ||
1109 | } | ||
1110 | |||
1101 | /* | 1111 | /* |
1102 | * search through all the directories (starting with the current) to find | 1112 | * search through all the directories (starting with the current) to find |
1103 | * one that has tracks to play | 1113 | * one that has tracks to play |
1104 | */ | 1114 | */ |
1105 | static int get_next_directory(char *dir) | 1115 | static int get_next_dir(char *dir, bool is_forward, bool recursion) |
1106 | { | 1116 | { |
1107 | struct playlist_info* playlist = ¤t_playlist; | 1117 | struct playlist_info* playlist = ¤t_playlist; |
1108 | int result = -1; | 1118 | int result = -1; |
1109 | int dirfilter = global_settings.dirfilter; | 1119 | int dirfilter = global_settings.dirfilter; |
1120 | int sort_dir = global_settings.sort_dir; | ||
1110 | char *start_dir = NULL; | 1121 | char *start_dir = NULL; |
1111 | bool exit = false; | 1122 | bool exit = false; |
1112 | struct tree_context* tc = tree_get_context(); | 1123 | struct tree_context* tc = tree_get_context(); |
1113 | 1124 | ||
1114 | /* start with current directory */ | 1125 | if (recursion){ |
1115 | strncpy(dir, playlist->filename, playlist->dirlen-1); | 1126 | /* start with root */ |
1116 | dir[playlist->dirlen-1] = '\0'; | 1127 | dir[0] = '\0'; |
1128 | } | ||
1129 | else{ | ||
1130 | /* start with current directory */ | ||
1131 | strncpy(dir, playlist->filename, playlist->dirlen-1); | ||
1132 | dir[playlist->dirlen-1] = '\0'; | ||
1133 | } | ||
1117 | 1134 | ||
1118 | /* use the tree browser dircache to load files */ | 1135 | /* use the tree browser dircache to load files */ |
1119 | global_settings.dirfilter = SHOW_ALL; | 1136 | global_settings.dirfilter = SHOW_ALL; |
1120 | 1137 | ||
1138 | /* sort in another direction if previous dir is requested */ | ||
1139 | if(!is_forward){ | ||
1140 | if ((global_settings.sort_dir == 0) || (global_settings.sort_dir == 3)) | ||
1141 | global_settings.sort_dir = 4; | ||
1142 | else if (global_settings.sort_dir == 1) | ||
1143 | global_settings.sort_dir = 2; | ||
1144 | else if (global_settings.sort_dir == 2) | ||
1145 | global_settings.sort_dir = 1; | ||
1146 | else if (global_settings.sort_dir == 4) | ||
1147 | global_settings.sort_dir = 0; | ||
1148 | } | ||
1149 | |||
1121 | while (!exit) | 1150 | while (!exit) |
1122 | { | 1151 | { |
1123 | struct entry *files; | 1152 | struct entry *files; |
@@ -1180,8 +1209,14 @@ static int get_next_directory(char *dir) | |||
1180 | reloaded */ | 1209 | reloaded */ |
1181 | reload_directory(); | 1210 | reload_directory(); |
1182 | 1211 | ||
1183 | /* restore dirfilter */ | 1212 | /* restore dirfilter & sort_dir */ |
1184 | global_settings.dirfilter = dirfilter; | 1213 | global_settings.dirfilter = dirfilter; |
1214 | global_settings.sort_dir = sort_dir; | ||
1215 | |||
1216 | /* special case if nothing found: try start searching again from root */ | ||
1217 | if (result == -1 && !recursion){ | ||
1218 | result = get_next_dir(dir,is_forward, true); | ||
1219 | } | ||
1185 | 1220 | ||
1186 | return result; | 1221 | return result; |
1187 | } | 1222 | } |
@@ -1922,13 +1957,14 @@ int playlist_start(int start_index, int offset) | |||
1922 | bool playlist_check(int steps) | 1957 | bool playlist_check(int steps) |
1923 | { | 1958 | { |
1924 | struct playlist_info* playlist = ¤t_playlist; | 1959 | struct playlist_info* playlist = ¤t_playlist; |
1960 | |||
1961 | /* always allow folder navigation */ | ||
1962 | if (global_settings.next_folder && playlist->in_ram) | ||
1963 | return true; | ||
1964 | |||
1925 | int index = get_next_index(playlist, steps, -1); | 1965 | int index = get_next_index(playlist, steps, -1); |
1926 | 1966 | ||
1927 | if (index < 0 && steps >= 0 && | 1967 | if (index < 0 && steps >= 0 && global_settings.repeat_mode == REPEAT_SHUFFLE) |
1928 | (global_settings.repeat_mode == REPEAT_SHUFFLE || | ||
1929 | (global_settings.next_folder && playlist->in_ram))) | ||
1930 | /* shuffle repeat and move to next folder are the same as repeat all | ||
1931 | for check purposes */ | ||
1932 | index = get_next_index(playlist, steps, REPEAT_ALL); | 1968 | index = get_next_index(playlist, steps, REPEAT_ALL); |
1933 | 1969 | ||
1934 | return (index >= 0); | 1970 | return (index >= 0); |
@@ -2031,23 +2067,40 @@ int playlist_next(int steps) | |||
2031 | playlist_start(0, 0); | 2067 | playlist_start(0, 0); |
2032 | index = 0; | 2068 | index = 0; |
2033 | } | 2069 | } |
2034 | else if (global_settings.next_folder && playlist->in_ram) | 2070 | else if (playlist->in_ram && global_settings.next_folder) |
2035 | { | 2071 | { |
2036 | char dir[MAX_PATH+1]; | 2072 | char dir[MAX_PATH+1]; |
2037 | 2073 | ||
2038 | if (!get_next_directory(dir)) | 2074 | if (steps > 0) |
2039 | { | 2075 | { |
2040 | /* start playing new directory */ | 2076 | if (!get_next_directory(dir)) |
2077 | { | ||
2078 | /* start playing next directory */ | ||
2079 | if (playlist_create(dir, NULL) != -1) | ||
2080 | { | ||
2081 | ft_build_playlist(tree_get_context(), 0); | ||
2082 | if (global_settings.playlist_shuffle) | ||
2083 | playlist_shuffle(current_tick, -1); | ||
2084 | playlist_start(0, 0); | ||
2085 | index = 0; | ||
2086 | } | ||
2087 | } | ||
2088 | } | ||
2089 | else | ||
2090 | { | ||
2091 | if (!get_previous_directory(dir)) | ||
2092 | { | ||
2093 | /* start playing previous directory */ | ||
2041 | if (playlist_create(dir, NULL) != -1) | 2094 | if (playlist_create(dir, NULL) != -1) |
2042 | { | 2095 | { |
2043 | ft_build_playlist(tree_get_context(), 0); | 2096 | ft_build_playlist(tree_get_context(), 0); |
2044 | if (global_settings.playlist_shuffle) | 2097 | if (global_settings.playlist_shuffle) |
2045 | playlist_shuffle(current_tick, -1); | 2098 | playlist_shuffle(current_tick, -1); |
2046 | 2099 | playlist_start(current_playlist.amount-1,0); | |
2047 | playlist_start(0, 0); | 2100 | index = current_playlist.amount-1; |
2048 | index = 0; | ||
2049 | } | 2101 | } |
2050 | } | 2102 | } |
2103 | } | ||
2051 | } | 2104 | } |
2052 | 2105 | ||
2053 | return index; | 2106 | return index; |
@@ -2096,6 +2149,29 @@ int playlist_next(int steps) | |||
2096 | return index; | 2149 | return index; |
2097 | } | 2150 | } |
2098 | 2151 | ||
2152 | /* try playing next or previous folder */ | ||
2153 | bool playlist_next_dir(int direction) | ||
2154 | { | ||
2155 | char dir[MAX_PATH+1]; | ||
2156 | |||
2157 | if (((direction > 0) && !get_next_directory(dir)) || | ||
2158 | ((direction < 0) && !get_previous_directory(dir))) | ||
2159 | { | ||
2160 | if (playlist_create(dir, NULL) != -1) | ||
2161 | { | ||
2162 | ft_build_playlist(tree_get_context(), 0); | ||
2163 | if (global_settings.playlist_shuffle) | ||
2164 | playlist_shuffle(current_tick, -1); | ||
2165 | playlist_start(0,0); | ||
2166 | return true; | ||
2167 | } | ||
2168 | else | ||
2169 | return false; | ||
2170 | } | ||
2171 | else | ||
2172 | return false; | ||
2173 | } | ||
2174 | |||
2099 | /* Get resume info for current playing song. If return value is -1 then | 2175 | /* Get resume info for current playing song. If return value is -1 then |
2100 | settings shouldn't be saved. */ | 2176 | settings shouldn't be saved. */ |
2101 | int playlist_get_resume_info(int *resume_index) | 2177 | int playlist_get_resume_info(int *resume_index) |
diff --git a/apps/playlist.h b/apps/playlist.h index 1937c48a12..efac303f30 100644 --- a/apps/playlist.h +++ b/apps/playlist.h | |||
@@ -80,6 +80,7 @@ int playlist_start(int start_index, int offset); | |||
80 | bool playlist_check(int steps); | 80 | bool playlist_check(int steps); |
81 | char *playlist_peek(int steps); | 81 | char *playlist_peek(int steps); |
82 | int playlist_next(int steps); | 82 | int playlist_next(int steps); |
83 | bool playlist_next_dir(int direction); | ||
83 | int playlist_get_resume_info(int *resume_index); | 84 | int playlist_get_resume_info(int *resume_index); |
84 | int playlist_update_resume_info(const struct mp3entry* id3); | 85 | int playlist_update_resume_info(const struct mp3entry* id3); |
85 | int playlist_get_display_index(void); | 86 | int playlist_get_display_index(void); |
diff --git a/apps/settings.c b/apps/settings.c index 0f3c95d979..4924669059 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -429,7 +429,7 @@ static const struct bit_entry hd_bits[] = | |||
429 | {1, S_O(spdif_enable), false, "spdif enable", off_on}, | 429 | {1, S_O(spdif_enable), false, "spdif enable", off_on}, |
430 | #endif | 430 | #endif |
431 | 431 | ||
432 | {1, S_O(next_folder), false, "move to next folder", off_on }, | 432 | {1, S_O(next_folder), true, "folder navigation", off_on }, |
433 | {1, S_O(runtimedb), false, "gather runtime data", off_on }, | 433 | {1, S_O(runtimedb), false, "gather runtime data", off_on }, |
434 | 434 | ||
435 | #if CONFIG_CODEC == SWCODEC | 435 | #if CONFIG_CODEC == SWCODEC |
diff --git a/apps/wps.c b/apps/wps.c index 784289ada4..84f862de9c 100644 --- a/apps/wps.c +++ b/apps/wps.c | |||
@@ -64,6 +64,9 @@ static struct mp3entry* id3 = NULL; | |||
64 | static struct mp3entry* nid3 = NULL; | 64 | static struct mp3entry* nid3 = NULL; |
65 | static char current_track_path[MAX_PATH+1]; | 65 | static char current_track_path[MAX_PATH+1]; |
66 | 66 | ||
67 | void audio_next_dir(void); | ||
68 | void audio_prev_dir(void); | ||
69 | |||
67 | /* set volume | 70 | /* set volume |
68 | return true if screen restore is needed | 71 | return true if screen restore is needed |
69 | return false otherwise | 72 | return false otherwise |
@@ -601,6 +604,17 @@ long wps_show(void) | |||
601 | } | 604 | } |
602 | break; | 605 | break; |
603 | 606 | ||
607 | #ifdef WPS_RC_NEXT_DIR | ||
608 | case WPS_RC_NEXT_DIR: | ||
609 | audio_next_dir(); | ||
610 | break; | ||
611 | #endif | ||
612 | #ifdef WPS_RC_PREV_DIR | ||
613 | case WPS_RC_PREV_DIR: | ||
614 | audio_prev_dir(); | ||
615 | break; | ||
616 | #endif | ||
617 | |||
604 | /* next */ | 618 | /* next */ |
605 | case WPS_NEXT: | 619 | case WPS_NEXT: |
606 | #ifdef WPS_NEXT_PRE | 620 | #ifdef WPS_NEXT_PRE |
diff --git a/apps/wps.h b/apps/wps.h index e32bd3c815..e1f053a3d2 100644 --- a/apps/wps.h +++ b/apps/wps.h | |||
@@ -43,6 +43,8 @@ | |||
43 | #define WPS_CONTEXT (BUTTON_SELECT | BUTTON_REPEAT) | 43 | #define WPS_CONTEXT (BUTTON_SELECT | BUTTON_REPEAT) |
44 | #define WPS_QUICK (BUTTON_MODE | BUTTON_REPEAT) | 44 | #define WPS_QUICK (BUTTON_MODE | BUTTON_REPEAT) |
45 | 45 | ||
46 | #define WPS_RC_NEXT_DIR (BUTTON_RC_BITRATE | BUTTON_REL) | ||
47 | #define WPS_RC_PREV_DIR (BUTTON_RC_SOURCE | BUTTON_REL) | ||
46 | #define WPS_RC_NEXT (BUTTON_RC_FF | BUTTON_REL) | 48 | #define WPS_RC_NEXT (BUTTON_RC_FF | BUTTON_REL) |
47 | #define WPS_RC_NEXT_PRE BUTTON_RC_FF | 49 | #define WPS_RC_NEXT_PRE BUTTON_RC_FF |
48 | #define WPS_RC_PREV (BUTTON_RC_REW | BUTTON_REL) | 50 | #define WPS_RC_PREV (BUTTON_RC_REW | BUTTON_REL) |