diff options
-rw-r--r-- | apps/lang/english.lang | 54 | ||||
-rw-r--r-- | apps/menu.c | 4 | ||||
-rw-r--r-- | apps/settings.c | 40 | ||||
-rw-r--r-- | apps/settings.h | 5 | ||||
-rw-r--r-- | apps/settings_menu.c | 51 | ||||
-rw-r--r-- | apps/sleeptimer.c | 2 | ||||
-rw-r--r-- | apps/sound_menu.c | 3 | ||||
-rw-r--r-- | apps/talk.c | 12 | ||||
-rw-r--r-- | apps/talk.h | 3 | ||||
-rw-r--r-- | apps/tree.c | 74 |
10 files changed, 239 insertions, 9 deletions
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index 5af10d4ab8..ad98416b60 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -2373,3 +2373,57 @@ new: | |||
2373 | 2373 | ||
2374 | #carry on adding normal LANG_ strings below | 2374 | #carry on adding normal LANG_ strings below |
2375 | 2375 | ||
2376 | id: LANG_VOICE | ||
2377 | desc: root of voice menu | ||
2378 | eng: "Voice" | ||
2379 | voice: "Voice" | ||
2380 | new: | ||
2381 | |||
2382 | id: LANG_VOICE_MENU | ||
2383 | desc: item of voice menu, enable/disable the voice UI | ||
2384 | eng: "Voice Menus" | ||
2385 | voice: "Voice Menus" | ||
2386 | new: | ||
2387 | |||
2388 | id: LANG_VOICE_DIR | ||
2389 | desc: item of voice menu, set the "talkbox" mode for directories | ||
2390 | eng: "Voice Directories" | ||
2391 | voice: "Voice Directories" | ||
2392 | new: | ||
2393 | |||
2394 | id: LANG_VOICE_FILE | ||
2395 | desc: item of voice menu, set the voive mode for files | ||
2396 | eng: "Voice Filenames" | ||
2397 | voice: "Voice Filenames" | ||
2398 | new: | ||
2399 | |||
2400 | id: LANG_VOICE_NUMBER | ||
2401 | desc: "talkbox" mode for files+directories | ||
2402 | eng: "Numbers" | ||
2403 | voice: "Numbers" | ||
2404 | new: | ||
2405 | |||
2406 | id: LANG_VOICE_DIR_ENTER | ||
2407 | desc: "talkbox" mode for directories | ||
2408 | eng: "on enter" | ||
2409 | voice: "on enter" | ||
2410 | new: | ||
2411 | |||
2412 | id: LANG_VOICE_DIR_HOVER | ||
2413 | desc: "talkbox" mode for directories | ||
2414 | eng: "while hovering" | ||
2415 | voice: "while hovering" | ||
2416 | new: | ||
2417 | |||
2418 | id: VOICE_FILE | ||
2419 | desc: spoken only, prefix for file number | ||
2420 | eng: "" | ||
2421 | voice: "file" | ||
2422 | new: | ||
2423 | |||
2424 | id: VOICE_DIR | ||
2425 | desc: spoken only, prefix for directory number | ||
2426 | eng: "" | ||
2427 | voice: "folder" | ||
2428 | new: | ||
2429 | |||
diff --git a/apps/menu.c b/apps/menu.c index d1f073645b..eae5ca2021 100644 --- a/apps/menu.c +++ b/apps/menu.c | |||
@@ -243,7 +243,7 @@ static void put_cursor(int m, int target) | |||
243 | if (do_update) | 243 | if (do_update) |
244 | { /* "say" the entry under the cursor */ | 244 | { /* "say" the entry under the cursor */ |
245 | int voice_id = menus[m].items[menus[m].cursor].voice_id; | 245 | int voice_id = menus[m].items[menus[m].cursor].voice_id; |
246 | if (voice_id >= 0) /* valid ID given? */ | 246 | if (voice_id >= 0 && global_settings.talk_menu) /* valid ID given? */ |
247 | talk_id(voice_id, false); /* say it */ | 247 | talk_id(voice_id, false); /* say it */ |
248 | } | 248 | } |
249 | 249 | ||
@@ -320,7 +320,7 @@ int menu_show(int m) | |||
320 | 320 | ||
321 | /* say current entry */ | 321 | /* say current entry */ |
322 | voice_id = menus[m].items[menus[m].cursor].voice_id; | 322 | voice_id = menus[m].items[menus[m].cursor].voice_id; |
323 | if (voice_id >= 0) /* valid ID given? */ | 323 | if (voice_id >= 0 && global_settings.talk_menu) /* valid ID given? */ |
324 | talk_id(voice_id, false); /* say it */ | 324 | talk_id(voice_id, false); /* say it */ |
325 | 325 | ||
326 | while (!exit) { | 326 | while (!exit) { |
diff --git a/apps/settings.c b/apps/settings.c index 2bc7f45f0b..a9691f3a6a 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -456,6 +456,9 @@ int settings_save( void ) | |||
456 | 456 | ||
457 | config_block[0xf4]=((unsigned char)global_settings.rec_prerecord_time | | 457 | config_block[0xf4]=((unsigned char)global_settings.rec_prerecord_time | |
458 | ((unsigned char)global_settings.rec_directory << 5)); | 458 | ((unsigned char)global_settings.rec_directory << 5)); |
459 | config_block[0xf5] = (global_settings.talk_dir & 7) | | ||
460 | ((global_settings.talk_file & 3) << 3) | | ||
461 | ((global_settings.talk_menu & 1) << 5); | ||
459 | 462 | ||
460 | if(save_config_buffer()) | 463 | if(save_config_buffer()) |
461 | { | 464 | { |
@@ -793,6 +796,11 @@ void settings_load(void) | |||
793 | global_settings.rec_prerecord_time = config_block[0xf4] & 0x1f; | 796 | global_settings.rec_prerecord_time = config_block[0xf4] & 0x1f; |
794 | global_settings.rec_directory = (config_block[0xf4] >> 5) & 3; | 797 | global_settings.rec_directory = (config_block[0xf4] >> 5) & 3; |
795 | } | 798 | } |
799 | if (config_block[0xf5] != 0xff) { | ||
800 | global_settings.talk_dir = config_block[0xf5] & 7; | ||
801 | global_settings.talk_file = (config_block[0xf5] >> 3) & 3; | ||
802 | global_settings.talk_menu = (config_block[0xf5] >> 5) & 1; | ||
803 | } | ||
796 | 804 | ||
797 | #ifdef HAVE_LCD_CHARCELLS | 805 | #ifdef HAVE_LCD_CHARCELLS |
798 | if (config_block[0xa8] != 0xff) | 806 | if (config_block[0xa8] != 0xff) |
@@ -1193,6 +1201,20 @@ bool settings_load_config(char* file) | |||
1193 | set_cfg_option(&global_settings.playlist_viewer_track_display, | 1201 | set_cfg_option(&global_settings.playlist_viewer_track_display, |
1194 | value, options, 2); | 1202 | value, options, 2); |
1195 | } | 1203 | } |
1204 | else if (!strcasecmp(name, "talk dir")) | ||
1205 | { | ||
1206 | static char* options[] = {"off", "number", "enter", "hover"}; | ||
1207 | set_cfg_option(&global_settings.talk_dir, value, options, 4); | ||
1208 | } | ||
1209 | else if (!strcasecmp(name, "talk file")) | ||
1210 | { | ||
1211 | static char* options[] = {"off", "number"}; | ||
1212 | set_cfg_option(&global_settings.talk_dir, value, options, 2); | ||
1213 | } | ||
1214 | else if (!strcasecmp(name, "talk menu")) | ||
1215 | { | ||
1216 | set_cfg_bool(&global_settings.talk_menu, value); | ||
1217 | } | ||
1196 | } | 1218 | } |
1197 | 1219 | ||
1198 | close(fd); | 1220 | close(fd); |
@@ -1539,6 +1561,16 @@ bool settings_save_config(void) | |||
1539 | options[global_settings.playlist_viewer_track_display]); | 1561 | options[global_settings.playlist_viewer_track_display]); |
1540 | } | 1562 | } |
1541 | } | 1563 | } |
1564 | fprintf(fd, "#\r\n# Voice\r\n#\r\n"); | ||
1565 | { | ||
1566 | static char* options[] = {"off", "number", "enter", "hover"}; | ||
1567 | fprintf(fd, "talk dir: %s\r\n", | ||
1568 | options[global_settings.talk_dir]); | ||
1569 | fprintf(fd, "talk file: %s\r\n", /* recycle the options, */ | ||
1570 | options[global_settings.talk_file]); /* first 2 are alike */ | ||
1571 | fprintf(fd, "talk menu: %s\r\n", | ||
1572 | boolopt[global_settings.talk_menu]); | ||
1573 | } | ||
1542 | 1574 | ||
1543 | close(fd); | 1575 | close(fd); |
1544 | 1576 | ||
@@ -1646,6 +1678,10 @@ void settings_reset(void) { | |||
1646 | global_settings.playlist_viewer_icons = true; | 1678 | global_settings.playlist_viewer_icons = true; |
1647 | global_settings.playlist_viewer_indices = true; | 1679 | global_settings.playlist_viewer_indices = true; |
1648 | global_settings.playlist_viewer_track_display = 0; | 1680 | global_settings.playlist_viewer_track_display = 0; |
1681 | /* talking menu on by default, to help the blind (if voice file present) */ | ||
1682 | global_settings.talk_menu = 1; | ||
1683 | global_settings.talk_dir = 0; | ||
1684 | global_settings.talk_file = 0; | ||
1649 | } | 1685 | } |
1650 | 1686 | ||
1651 | bool set_bool(char* string, bool* variable ) | 1687 | bool set_bool(char* string, bool* variable ) |
@@ -1713,7 +1749,7 @@ bool set_int(char* string, | |||
1713 | #endif | 1749 | #endif |
1714 | lcd_update(); | 1750 | lcd_update(); |
1715 | 1751 | ||
1716 | if (*variable != last_value) | 1752 | if (global_settings.talk_menu && *variable != last_value) |
1717 | { | 1753 | { |
1718 | if (voice_unit < UNIT_LAST) | 1754 | if (voice_unit < UNIT_LAST) |
1719 | { /* use the available unit definition */ | 1755 | { /* use the available unit definition */ |
@@ -1829,7 +1865,7 @@ bool set_option(char* string, void* variable, enum optiontype type, | |||
1829 | while ( !done ) { | 1865 | while ( !done ) { |
1830 | index = type==INT ? *intvar : (int)*boolvar; | 1866 | index = type==INT ? *intvar : (int)*boolvar; |
1831 | lcd_puts(0, 1, options[index].string); | 1867 | lcd_puts(0, 1, options[index].string); |
1832 | if (index != oldindex) | 1868 | if (global_settings.talk_menu && index != oldindex) |
1833 | { | 1869 | { |
1834 | talk_id(options[index].voice_id, false); | 1870 | talk_id(options[index].voice_id, false); |
1835 | oldindex = index; | 1871 | oldindex = index; |
diff --git a/apps/settings.h b/apps/settings.h index 350d14a346..0bf67b474b 100644 --- a/apps/settings.h +++ b/apps/settings.h | |||
@@ -202,6 +202,11 @@ struct user_settings | |||
202 | bool playlist_viewer_icons; /* display icons on viewer */ | 202 | bool playlist_viewer_icons; /* display icons on viewer */ |
203 | bool playlist_viewer_indices; /* display playlist indices on viewer */ | 203 | bool playlist_viewer_indices; /* display playlist indices on viewer */ |
204 | int playlist_viewer_track_display; /* how to display tracks in viewer */ | 204 | int playlist_viewer_track_display; /* how to display tracks in viewer */ |
205 | |||
206 | /* voice UI settings */ | ||
207 | bool talk_menu; /* enable voice UI */ | ||
208 | int talk_dir; /* talkbox mode: 0=off 1=number 2=clip@enter 3=clip@hover */ | ||
209 | int talk_file; /* voice filename mode: 0=off, 1=number, other t.b.d. */ | ||
205 | }; | 210 | }; |
206 | 211 | ||
207 | enum optiontype { INT, BOOL }; | 212 | enum optiontype { INT, BOOL }; |
diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 35602f001b..a0f039b9a0 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c | |||
@@ -876,6 +876,56 @@ static bool language_browse(void) | |||
876 | return rockbox_browse(ROCKBOX_DIR LANG_DIR, SHOW_LNG); | 876 | return rockbox_browse(ROCKBOX_DIR LANG_DIR, SHOW_LNG); |
877 | } | 877 | } |
878 | 878 | ||
879 | static bool voice_menus(void) | ||
880 | { | ||
881 | bool ret; | ||
882 | bool temp = global_settings.talk_menu; | ||
883 | /* work on a temp variable first, avoid "life" disabling */ | ||
884 | ret = set_bool( str(LANG_VOICE_MENU), &temp ); | ||
885 | global_settings.talk_menu = temp; | ||
886 | return ret; | ||
887 | } | ||
888 | |||
889 | static bool voice_dirs(void) | ||
890 | { | ||
891 | struct opt_items names[] = { | ||
892 | { STR(LANG_OFF) }, | ||
893 | { STR(LANG_VOICE_NUMBER) }, | ||
894 | { STR(LANG_VOICE_DIR_ENTER) }, | ||
895 | { STR(LANG_VOICE_DIR_HOVER) } | ||
896 | }; | ||
897 | return set_option( str(LANG_VOICE_DIR), | ||
898 | &global_settings.talk_dir, INT, names, 4, NULL); | ||
899 | } | ||
900 | |||
901 | static bool voice_files(void) | ||
902 | { | ||
903 | struct opt_items names[] = { | ||
904 | { STR(LANG_OFF) }, | ||
905 | { STR(LANG_VOICE_NUMBER) } | ||
906 | }; | ||
907 | return set_option( str(LANG_VOICE_DIR), | ||
908 | &global_settings.talk_file, INT, names, 2, NULL); | ||
909 | } | ||
910 | |||
911 | static bool voice_menu(void) | ||
912 | { | ||
913 | int m; | ||
914 | bool result; | ||
915 | |||
916 | struct menu_item items[] = { | ||
917 | { STR(LANG_VOICE_MENU), voice_menus }, | ||
918 | { STR(LANG_VOICE_DIR), voice_dirs }, | ||
919 | { STR(LANG_VOICE_FILE), voice_files } | ||
920 | }; | ||
921 | |||
922 | m=menu_init( items, sizeof(items) / sizeof(*items), NULL, | ||
923 | NULL, NULL, NULL); | ||
924 | result = menu_run(m); | ||
925 | menu_exit(m); | ||
926 | return result; | ||
927 | } | ||
928 | |||
879 | #ifdef HAVE_LCD_BITMAP | 929 | #ifdef HAVE_LCD_BITMAP |
880 | static bool font_browse(void) | 930 | static bool font_browse(void) |
881 | { | 931 | { |
@@ -1283,6 +1333,7 @@ bool settings_menu(void) | |||
1283 | { STR(LANG_SYSTEM), system_settings_menu }, | 1333 | { STR(LANG_SYSTEM), system_settings_menu }, |
1284 | { STR(LANG_BOOKMARK_SETTINGS),bookmark_settings_menu }, | 1334 | { STR(LANG_BOOKMARK_SETTINGS),bookmark_settings_menu }, |
1285 | { STR(LANG_LANGUAGE), language_browse }, | 1335 | { STR(LANG_LANGUAGE), language_browse }, |
1336 | { STR(LANG_VOICE), voice_menu }, | ||
1286 | }; | 1337 | }; |
1287 | 1338 | ||
1288 | m=menu_init( items, sizeof(items) / sizeof(*items), NULL, | 1339 | m=menu_init( items, sizeof(items) / sizeof(*items), NULL, |
diff --git a/apps/sleeptimer.c b/apps/sleeptimer.c index 1a6e3ec844..a236ed9ba7 100644 --- a/apps/sleeptimer.c +++ b/apps/sleeptimer.c | |||
@@ -144,7 +144,7 @@ bool sleeptimer_screen(void) | |||
144 | hours, minutes); | 144 | hours, minutes); |
145 | lcd_puts(0, 1, buf); | 145 | lcd_puts(0, 1, buf); |
146 | 146 | ||
147 | if (sayit) | 147 | if (sayit && global_settings.talk_menu) |
148 | { | 148 | { |
149 | bool enqueue = false; /* first one should not ne queued */ | 149 | bool enqueue = false; /* first one should not ne queued */ |
150 | 150 | ||
diff --git a/apps/sound_menu.c b/apps/sound_menu.c index 67e6999e8d..23d4c811a5 100644 --- a/apps/sound_menu.c +++ b/apps/sound_menu.c | |||
@@ -87,7 +87,8 @@ bool set_sound(char* string, | |||
87 | { | 87 | { |
88 | snprintf(str,sizeof str,"%d %s ", val, unit); | 88 | snprintf(str,sizeof str,"%d %s ", val, unit); |
89 | } | 89 | } |
90 | talk_value(val, talkunit, false); /* speak it */ | 90 | if (global_settings.talk_menu) |
91 | talk_value(val, talkunit, false); /* speak it */ | ||
91 | } | 92 | } |
92 | lcd_puts(0,1,str); | 93 | lcd_puts(0,1,str); |
93 | status_draw(true); | 94 | status_draw(true); |
diff --git a/apps/talk.c b/apps/talk.c index 3849f0e847..6dd0076f06 100644 --- a/apps/talk.c +++ b/apps/talk.c | |||
@@ -30,14 +30,14 @@ | |||
30 | #include "mpeg.h" | 30 | #include "mpeg.h" |
31 | #include "lang.h" | 31 | #include "lang.h" |
32 | #include "talk.h" | 32 | #include "talk.h" |
33 | #include "screens.h" /* test hack */ | 33 | #include "id3.h" |
34 | #include "kernel.h" | ||
35 | extern void bitswap(unsigned char *data, int length); /* no header for this */ | 34 | extern void bitswap(unsigned char *data, int length); /* no header for this */ |
36 | 35 | ||
37 | /***************** Constants *****************/ | 36 | /***************** Constants *****************/ |
38 | 37 | ||
39 | #define QUEUE_SIZE 20 | 38 | #define QUEUE_SIZE 20 |
40 | const char* voicefont_file = "/.rockbox/langs/english.voice"; | 39 | const char* voicefont_file = "/.rockbox/langs/english.voice"; |
40 | const char* dir_thumbnail_name = ".dirname.mp3"; | ||
41 | 41 | ||
42 | 42 | ||
43 | /***************** Data types *****************/ | 43 | /***************** Data types *****************/ |
@@ -317,6 +317,7 @@ int talk_file(char* filename, bool enqueue) | |||
317 | { | 317 | { |
318 | int fd; | 318 | int fd; |
319 | int size; | 319 | int size; |
320 | struct mp3entry info; | ||
320 | 321 | ||
321 | if (mpeg_status()) /* busy, buffer in use */ | 322 | if (mpeg_status()) /* busy, buffer in use */ |
322 | return -1; | 323 | return -1; |
@@ -324,12 +325,19 @@ int talk_file(char* filename, bool enqueue) | |||
324 | if (p_thumbnail == NULL || size_for_thumbnail <= 0) | 325 | if (p_thumbnail == NULL || size_for_thumbnail <= 0) |
325 | return -1; | 326 | return -1; |
326 | 327 | ||
328 | if(mp3info(&info, filename)) /* use this to find real start */ | ||
329 | { | ||
330 | return 0; /* failed to open, or invalid */ | ||
331 | } | ||
332 | |||
327 | fd = open(filename, O_RDONLY); | 333 | fd = open(filename, O_RDONLY); |
328 | if (fd < 0) /* failed to open */ | 334 | if (fd < 0) /* failed to open */ |
329 | { | 335 | { |
330 | return 0; | 336 | return 0; |
331 | } | 337 | } |
332 | 338 | ||
339 | lseek(fd, info.first_frame_offset, SEEK_SET); /* behind ID data */ | ||
340 | |||
333 | size = read(fd, p_thumbnail, size_for_thumbnail); | 341 | size = read(fd, p_thumbnail, size_for_thumbnail); |
334 | close(fd); | 342 | close(fd); |
335 | 343 | ||
diff --git a/apps/talk.h b/apps/talk.h index 518549ed74..f3c1366bb0 100644 --- a/apps/talk.h +++ b/apps/talk.h | |||
@@ -54,6 +54,9 @@ enum { | |||
54 | /* convenience macro to have both string and ID as arguments */ | 54 | /* convenience macro to have both string and ID as arguments */ |
55 | #define STR(id) str(id), id | 55 | #define STR(id) str(id), id |
56 | 56 | ||
57 | /* publish this string, so it's stored only once (better than #define) */ | ||
58 | extern const char* dir_thumbnail_name; | ||
59 | |||
57 | 60 | ||
58 | void talk_init(void); | 61 | void talk_init(void); |
59 | int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ | 62 | int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */ |
diff --git a/apps/tree.c b/apps/tree.c index d56dacc130..9d6a66684e 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include "plugin.h" | 55 | #include "plugin.h" |
56 | #include "power.h" | 56 | #include "power.h" |
57 | #include "action.h" | 57 | #include "action.h" |
58 | #include "talk.h" | ||
58 | 59 | ||
59 | #ifdef HAVE_LCD_BITMAP | 60 | #ifdef HAVE_LCD_BITMAP |
60 | #include "widgets.h" | 61 | #include "widgets.h" |
@@ -112,6 +113,7 @@ static int dircursor; | |||
112 | static int dirstart; | 113 | static int dirstart; |
113 | static int dirlevel; | 114 | static int dirlevel; |
114 | static int filesindir; | 115 | static int filesindir; |
116 | static int dirsindir; /* how many of the dircache entries are directories */ | ||
115 | static int dirpos[MAX_DIR_LEVELS]; | 117 | static int dirpos[MAX_DIR_LEVELS]; |
116 | static int cursorpos[MAX_DIR_LEVELS]; | 118 | static int cursorpos[MAX_DIR_LEVELS]; |
117 | static char lastdir[MAX_PATH]; | 119 | static char lastdir[MAX_PATH]; |
@@ -122,6 +124,7 @@ static bool reload_dir = false; | |||
122 | static int boot_size = 0; | 124 | static int boot_size = 0; |
123 | static int boot_cluster; | 125 | static int boot_cluster; |
124 | static bool boot_changed = false; | 126 | static bool boot_changed = false; |
127 | static bool enqueue_next = false; | ||
125 | 128 | ||
126 | static bool start_wps = false; | 129 | static bool start_wps = false; |
127 | static bool dirbrowse(char *root, int *dirfilter); | 130 | static bool dirbrowse(char *root, int *dirfilter); |
@@ -199,7 +202,8 @@ static int build_playlist(int start_index) | |||
199 | 202 | ||
200 | for(i = 0;i < filesindir;i++) | 203 | for(i = 0;i < filesindir;i++) |
201 | { | 204 | { |
202 | if((dircache[i].attr & TREE_ATTR_MASK) == TREE_ATTR_MPA) | 205 | if((dircache[i].attr & TREE_ATTR_MASK) == TREE_ATTR_MPA |
206 | && (strcmp(dircache[i].name, dir_thumbnail_name) != 0)) | ||
203 | { | 207 | { |
204 | DEBUGF("Adding %s\n", dircache[i].name); | 208 | DEBUGF("Adding %s\n", dircache[i].name); |
205 | if (playlist_add(dircache[i].name) < 0) | 209 | if (playlist_add(dircache[i].name) < 0) |
@@ -216,6 +220,36 @@ static int build_playlist(int start_index) | |||
216 | return start_index; | 220 | return start_index; |
217 | } | 221 | } |
218 | 222 | ||
223 | |||
224 | static int play_dirname(int start_index, bool enqueue) | ||
225 | { | ||
226 | int fd; | ||
227 | char dirname_mp3_filename[MAX_PATH+1]; | ||
228 | |||
229 | if (mpeg_status() & MPEG_STATUS_PLAY) | ||
230 | return 0; | ||
231 | |||
232 | snprintf(dirname_mp3_filename, sizeof(dirname_mp3_filename), "%s/%s/%s", | ||
233 | currdir, dircache[start_index].name, dir_thumbnail_name); | ||
234 | |||
235 | DEBUGF("Checking for %s\n", dirname_mp3_filename); | ||
236 | |||
237 | fd = open(dirname_mp3_filename, O_RDONLY); | ||
238 | if (fd < 0) | ||
239 | { | ||
240 | DEBUGF("Failed to find: %s\n", dirname_mp3_filename); | ||
241 | return -1; | ||
242 | } | ||
243 | |||
244 | close(fd); | ||
245 | |||
246 | DEBUGF("Found: %s\n", dirname_mp3_filename); | ||
247 | |||
248 | talk_file(dirname_mp3_filename, enqueue); | ||
249 | return 1; | ||
250 | } | ||
251 | |||
252 | |||
219 | static int compare(const void* p1, const void* p2) | 253 | static int compare(const void* p1, const void* p2) |
220 | { | 254 | { |
221 | struct entry* e1 = (struct entry*)p1; | 255 | struct entry* e1 = (struct entry*)p1; |
@@ -278,6 +312,7 @@ struct entry* load_and_sort_directory(char *dirname, int *dirfilter, | |||
278 | return NULL; /* not a directory */ | 312 | return NULL; /* not a directory */ |
279 | 313 | ||
280 | name_buffer_length = 0; | 314 | name_buffer_length = 0; |
315 | dirsindir = 0; | ||
281 | *buffer_full = false; | 316 | *buffer_full = false; |
282 | 317 | ||
283 | for ( i=0; i < max_files_in_dir; i++ ) { | 318 | for ( i=0; i < max_files_in_dir; i++ ) { |
@@ -369,6 +404,9 @@ struct entry* load_and_sort_directory(char *dirname, int *dirfilter, | |||
369 | dptr->name = &name_buffer[name_buffer_length]; | 404 | dptr->name = &name_buffer[name_buffer_length]; |
370 | strcpy(dptr->name,entry->d_name); | 405 | strcpy(dptr->name,entry->d_name); |
371 | name_buffer_length += len + 1; | 406 | name_buffer_length += len + 1; |
407 | |||
408 | if (dptr->attr & ATTR_DIRECTORY) /* count the remaining dirs */ | ||
409 | dirsindir++; | ||
372 | } | 410 | } |
373 | *num_files = i; | 411 | *num_files = i; |
374 | closedir(dir); | 412 | closedir(dir); |
@@ -1019,6 +1057,14 @@ static bool dirbrowse(char *root, int *dirfilter) | |||
1019 | snprintf(buf,sizeof(buf),"/%s",file->name); | 1057 | snprintf(buf,sizeof(buf),"/%s",file->name); |
1020 | 1058 | ||
1021 | if (file->attr & ATTR_DIRECTORY) { | 1059 | if (file->attr & ATTR_DIRECTORY) { |
1060 | if (global_settings.talk_dir == 2) /* enter */ | ||
1061 | { | ||
1062 | /* play_dirname */ | ||
1063 | DEBUGF("Playing directory thumbnail: %s", currdir); | ||
1064 | play_dirname(dircursor+dirstart, false); | ||
1065 | /* avoid reading getting cut by next filename */ | ||
1066 | enqueue_next = true; | ||
1067 | } | ||
1022 | memcpy(currdir,buf,sizeof(currdir)); | 1068 | memcpy(currdir,buf,sizeof(currdir)); |
1023 | if ( dirlevel < MAX_DIR_LEVELS ) { | 1069 | if ( dirlevel < MAX_DIR_LEVELS ) { |
1024 | dirpos[dirlevel] = dirstart; | 1070 | dirpos[dirlevel] = dirstart; |
@@ -1425,6 +1471,32 @@ static bool dirbrowse(char *root, int *dirfilter) | |||
1425 | 1471 | ||
1426 | showfileline(dircursor, i, true, dirfilter); /* scroll please */ | 1472 | showfileline(dircursor, i, true, dirfilter); /* scroll please */ |
1427 | need_update = true; | 1473 | need_update = true; |
1474 | |||
1475 | if (dircache[i].attr & ATTR_DIRECTORY) /* directory? */ | ||
1476 | { | ||
1477 | int ret = 0; | ||
1478 | /* play directory thumbnail */ | ||
1479 | if (global_settings.talk_dir == 3) /* hover */ | ||
1480 | { | ||
1481 | DEBUGF("Playing directory thumbnail: %s", currdir); | ||
1482 | ret = play_dirname(dircursor+dirstart, false); | ||
1483 | } | ||
1484 | |||
1485 | if (global_settings.talk_dir == 1 /* dirs as numbers */ | ||
1486 | || ret == -1) /* or no thumbnail found above */ | ||
1487 | { | ||
1488 | talk_id(VOICE_DIR, false); | ||
1489 | talk_number(i+1, true); | ||
1490 | } | ||
1491 | } | ||
1492 | else if (global_settings.talk_file == 1) /* files as numbers */ | ||
1493 | { | ||
1494 | /* enqueue_next is true if still talking the dir name */ | ||
1495 | talk_id(VOICE_FILE, enqueue_next); | ||
1496 | talk_number(i-dirsindir+1, true); | ||
1497 | enqueue_next = false; | ||
1498 | } | ||
1499 | |||
1428 | } | 1500 | } |
1429 | } | 1501 | } |
1430 | 1502 | ||