diff options
author | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-10-06 21:37:46 +0000 |
---|---|---|
committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-10-06 21:37:46 +0000 |
commit | d48442039ed399c0ba5ae51bc42d56b5b23f1bc4 (patch) | |
tree | aaed266e96ce32e43490c8fca364e931e1667288 /apps | |
parent | 6f9a7eb2c7d6f81e54b47c917be79f5126ba8982 (diff) | |
download | rockbox-d48442039ed399c0ba5ae51bc42d56b5b23f1bc4.tar.gz rockbox-d48442039ed399c0ba5ae51bc42d56b5b23f1bc4.zip |
patch #978765 by Carsten Tschach, new option for voice filenames: every file may have an optional .talk companion, with a filename clip. While at it, I removed the "on enter" directory talking, nobody used it.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5194 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/lang/deutsch.lang | 16 | ||||
-rw-r--r-- | apps/lang/english.lang | 12 | ||||
-rw-r--r-- | apps/settings.c | 7 | ||||
-rw-r--r-- | apps/settings_menu.c | 24 | ||||
-rw-r--r-- | apps/talk.h | 4 | ||||
-rw-r--r-- | apps/tree.c | 118 |
6 files changed, 112 insertions, 69 deletions
diff --git a/apps/lang/deutsch.lang b/apps/lang/deutsch.lang index db4ccc053e..f4cfa864af 100644 --- a/apps/lang/deutsch.lang +++ b/apps/lang/deutsch.lang | |||
@@ -2390,16 +2390,16 @@ voice: "als Zahl" | |||
2390 | new: "als Zahl" | 2390 | new: "als Zahl" |
2391 | 2391 | ||
2392 | id: LANG_VOICE_DIR_ENTER | 2392 | id: LANG_VOICE_DIR_ENTER |
2393 | desc: "talkbox" mode for directories | 2393 | desc: DEPRECATED |
2394 | eng: "on enter" | 2394 | eng: "" |
2395 | voice: "beim Betreten" | 2395 | voice: "" |
2396 | new: "beim Betreten" | 2396 | new: "" |
2397 | 2397 | ||
2398 | id: LANG_VOICE_DIR_HOVER | 2398 | id: LANG_VOICE_DIR_HOVER |
2399 | desc: "talkbox" mode for directories | 2399 | desc: "talkbox" mode for directories + files |
2400 | eng: "while hovering" | 2400 | eng: ".talk mp3 clip" |
2401 | voice: "mit Zeiger" | 2401 | voice: "Sprachdatei" |
2402 | new: "mit Cursor" | 2402 | new: ".talk mp3 Datei" |
2403 | 2403 | ||
2404 | id: VOICE_FILE | 2404 | id: VOICE_FILE |
2405 | desc: spoken only, prefix for file number | 2405 | desc: spoken only, prefix for file number |
diff --git a/apps/lang/english.lang b/apps/lang/english.lang index d93920dab8..facbe7eaf9 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang | |||
@@ -2404,15 +2404,15 @@ voice: "Numbers" | |||
2404 | new: | 2404 | new: |
2405 | 2405 | ||
2406 | id: LANG_VOICE_DIR_ENTER | 2406 | id: LANG_VOICE_DIR_ENTER |
2407 | desc: "talkbox" mode for directories | 2407 | desc: DEPRECATED |
2408 | eng: "on enter" | 2408 | eng: "" |
2409 | voice: "on enter" | 2409 | voice: "" |
2410 | new: | 2410 | new: |
2411 | 2411 | ||
2412 | id: LANG_VOICE_DIR_HOVER | 2412 | id: LANG_VOICE_DIR_HOVER |
2413 | desc: "talkbox" mode for directories | 2413 | desc: "talkbox" mode for directories + files |
2414 | eng: "while hovering" | 2414 | eng: ".talk mp3 clip" |
2415 | voice: "while hovering" | 2415 | voice: "talk mp3 clip" |
2416 | new: | 2416 | new: |
2417 | 2417 | ||
2418 | id: VOICE_FILE | 2418 | id: VOICE_FILE |
diff --git a/apps/settings.c b/apps/settings.c index 45ea7de072..10333b15c1 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -71,7 +71,7 @@ const char rec_base_directory[] = REC_BASE_DIR; | |||
71 | 71 | ||
72 | 72 | ||
73 | 73 | ||
74 | #define CONFIG_BLOCK_VERSION 16 | 74 | #define CONFIG_BLOCK_VERSION 17 |
75 | #define CONFIG_BLOCK_SIZE 512 | 75 | #define CONFIG_BLOCK_SIZE 512 |
76 | #define RTC_BLOCK_SIZE 44 | 76 | #define RTC_BLOCK_SIZE 44 |
77 | 77 | ||
@@ -150,6 +150,7 @@ Rest of config block, only saved to disk: | |||
150 | static const char off_on[] = "off,on"; | 150 | static const char off_on[] = "off,on"; |
151 | static const char off_on_ask[] = "off,on,ask"; | 151 | static const char off_on_ask[] = "off,on,ask"; |
152 | static const char graphic_numeric[] = "graphic,numeric"; | 152 | static const char graphic_numeric[] = "graphic,numeric"; |
153 | static const char off_number_spell_hover[] = "off,number,spell,hover"; | ||
153 | 154 | ||
154 | /* the part of the settings which ends up in the RTC RAM, where available | 155 | /* the part of the settings which ends up in the RTC RAM, where available |
155 | (those we either need early, save frequently, or without spinup) */ | 156 | (those we either need early, save frequently, or without spinup) */ |
@@ -319,8 +320,8 @@ static const struct bit_entry hd_bits[] = | |||
319 | {1, S_O(line_in), false, "line in", off_on }, | 320 | {1, S_O(line_in), false, "line in", off_on }, |
320 | #endif | 321 | #endif |
321 | /* voice */ | 322 | /* voice */ |
322 | {3, S_O(talk_dir), 0, "talk dir", "off,number,spell,enter,hover" }, | 323 | {2, S_O(talk_dir), 0, "talk dir", off_number_spell_hover }, |
323 | {2, S_O(talk_file), 0, "talk file", "off,number,spell" }, | 324 | {2, S_O(talk_file), 0, "talk file", off_number_spell_hover }, |
324 | {1, S_O(talk_menu), true, "talk menu", off_on }, | 325 | {1, S_O(talk_menu), true, "talk menu", off_on }, |
325 | 326 | ||
326 | /* If values are just added to the end, no need to bump the version. */ | 327 | /* If values are just added to the end, no need to bump the version. */ |
diff --git a/apps/settings_menu.c b/apps/settings_menu.c index 624274520f..4e9ec25d79 100644 --- a/apps/settings_menu.c +++ b/apps/settings_menu.c | |||
@@ -898,28 +898,24 @@ static bool voice_menus(void) | |||
898 | return ret; | 898 | return ret; |
899 | } | 899 | } |
900 | 900 | ||
901 | /* this is used 2 times below, so it saves memory to put it in global scope */ | ||
902 | static const struct opt_items voice_names[] = { | ||
903 | { STR(LANG_OFF) }, | ||
904 | { STR(LANG_VOICE_NUMBER) }, | ||
905 | { STR(LANG_VOICE_SPELL) }, | ||
906 | { STR(LANG_VOICE_DIR_HOVER) } | ||
907 | }; | ||
908 | |||
901 | static bool voice_dirs(void) | 909 | static bool voice_dirs(void) |
902 | { | 910 | { |
903 | static const struct opt_items names[] = { | ||
904 | { STR(LANG_OFF) }, | ||
905 | { STR(LANG_VOICE_NUMBER) }, | ||
906 | { STR(LANG_VOICE_SPELL) }, | ||
907 | { STR(LANG_VOICE_DIR_ENTER) }, | ||
908 | { STR(LANG_VOICE_DIR_HOVER) } | ||
909 | }; | ||
910 | return set_option( str(LANG_VOICE_DIR), | 911 | return set_option( str(LANG_VOICE_DIR), |
911 | &global_settings.talk_dir, INT, names, 5, NULL); | 912 | &global_settings.talk_dir, INT, voice_names, 4, NULL); |
912 | } | 913 | } |
913 | 914 | ||
914 | static bool voice_files(void) | 915 | static bool voice_files(void) |
915 | { | 916 | { |
916 | static const struct opt_items names[] = { | ||
917 | { STR(LANG_OFF) }, | ||
918 | { STR(LANG_VOICE_NUMBER) }, | ||
919 | { STR(LANG_VOICE_SPELL) } | ||
920 | }; | ||
921 | return set_option( str(LANG_VOICE_FILE), | 917 | return set_option( str(LANG_VOICE_FILE), |
922 | &global_settings.talk_file, INT, names, 3, NULL); | 918 | &global_settings.talk_file, INT, voice_names, 4, NULL); |
923 | } | 919 | } |
924 | 920 | ||
925 | static bool voice_menu(void) | 921 | static bool voice_menu(void) |
diff --git a/apps/talk.h b/apps/talk.h index c4c8bc7285..09d71866b0 100644 --- a/apps/talk.h +++ b/apps/talk.h | |||
@@ -55,8 +55,8 @@ enum { | |||
55 | #define STR(id) ID2P(id), id | 55 | #define STR(id) ID2P(id), id |
56 | 56 | ||
57 | /* publish this string, so it's stored only once (better than #define) */ | 57 | /* publish this string, so it's stored only once (better than #define) */ |
58 | extern const char* const dir_thumbnail_name; | 58 | extern const char* const dir_thumbnail_name; /* "_dirname.talk" */ |
59 | 59 | #define TALK_EXT ".talk" /* extra extension for file voicing */ | |
60 | 60 | ||
61 | void talk_init(void); | 61 | void talk_init(void); |
62 | 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 90ae159418..effb093b41 100644 --- a/apps/tree.c +++ b/apps/tree.c | |||
@@ -221,6 +221,25 @@ static int build_playlist(int start_index) | |||
221 | return start_index; | 221 | return start_index; |
222 | } | 222 | } |
223 | 223 | ||
224 | static int play_filenumber(int pos, int attr) | ||
225 | { | ||
226 | /* try to find a voice ID for the extension, if known */ | ||
227 | unsigned int j; | ||
228 | int ext_id = -1; /* default to none */ | ||
229 | for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++) | ||
230 | { | ||
231 | if (attr == filetypes[j].tree_attr) | ||
232 | { | ||
233 | ext_id = filetypes[j].voiceclip; | ||
234 | break; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | talk_id(VOICE_FILE, false); | ||
239 | talk_number(pos, true); | ||
240 | talk_id(ext_id, true); | ||
241 | return 1; | ||
242 | } | ||
224 | 243 | ||
225 | static int play_dirname(int start_index) | 244 | static int play_dirname(int start_index) |
226 | { | 245 | { |
@@ -250,6 +269,41 @@ static int play_dirname(int start_index) | |||
250 | return 1; | 269 | return 1; |
251 | } | 270 | } |
252 | 271 | ||
272 | static int play_filename(char *dir, char *file) | ||
273 | { | ||
274 | int fd; | ||
275 | char name_mp3_filename[MAX_PATH+1]; | ||
276 | |||
277 | if (mpeg_status() & MPEG_STATUS_PLAY) | ||
278 | return 0; | ||
279 | |||
280 | if (strcasecmp(&file[strlen(file) - strlen(TALK_EXT)], TALK_EXT)) | ||
281 | { /* file has no .talk extension */ | ||
282 | snprintf(name_mp3_filename, sizeof(name_mp3_filename), | ||
283 | "%s/%s" TALK_EXT, dir, file); | ||
284 | |||
285 | /* check if a corresponding .talk file exists */ | ||
286 | DEBUGF("Checking for Filename Thumb %s\n", name_mp3_filename); | ||
287 | fd = open(name_mp3_filename, O_RDONLY); | ||
288 | if (fd < 0) | ||
289 | { | ||
290 | DEBUGF("Failed to find: %s\n", name_mp3_filename); | ||
291 | return -1; | ||
292 | } | ||
293 | DEBUGF("Found: %s\n", name_mp3_filename); | ||
294 | close(fd); | ||
295 | talk_file(name_mp3_filename, false); | ||
296 | } | ||
297 | else | ||
298 | { /* it already is a .talk file, play this directly */ | ||
299 | snprintf(name_mp3_filename, sizeof(name_mp3_filename), | ||
300 | "%s/%s", dir, file); | ||
301 | talk_id(LANG_VOICE_DIR_HOVER, false); /* prefix it */ | ||
302 | talk_file(name_mp3_filename, true); | ||
303 | } | ||
304 | |||
305 | return 1; | ||
306 | } | ||
253 | 307 | ||
254 | static int compare(const void* p1, const void* p2) | 308 | static int compare(const void* p1, const void* p2) |
255 | { | 309 | { |
@@ -771,7 +825,6 @@ static bool dirbrowse(const char *root, const int *dirfilter) | |||
771 | int lastdircursor=-1; | 825 | int lastdircursor=-1; |
772 | bool need_update = true; | 826 | bool need_update = true; |
773 | bool exit_func = false; | 827 | bool exit_func = false; |
774 | bool enqueue_next = false; | ||
775 | long thumbnail_time = -1; /* for delaying a thumbnail */ | 828 | long thumbnail_time = -1; /* for delaying a thumbnail */ |
776 | bool update_all = false; /* set this to true when the whole file list | 829 | bool update_all = false; /* set this to true when the whole file list |
777 | has been refreshed on screen */ | 830 | has been refreshed on screen */ |
@@ -926,14 +979,6 @@ static bool dirbrowse(const char *root, const int *dirfilter) | |||
926 | snprintf(buf,sizeof(buf),"/%s",file->name); | 979 | snprintf(buf,sizeof(buf),"/%s",file->name); |
927 | 980 | ||
928 | if (file->attr & ATTR_DIRECTORY) { | 981 | if (file->attr & ATTR_DIRECTORY) { |
929 | if (global_settings.talk_dir == 3) /* enter */ | ||
930 | { | ||
931 | /* play_dirname */ | ||
932 | DEBUGF("Playing directory thumbnail: %s", currdir); | ||
933 | play_dirname(dircursor+dirstart); | ||
934 | /* avoid reading getting cut by next filename */ | ||
935 | enqueue_next = true; | ||
936 | } | ||
937 | memcpy(currdir,buf,sizeof(currdir)); | 982 | memcpy(currdir,buf,sizeof(currdir)); |
938 | if ( dirlevel < MAX_DIR_LEVELS ) { | 983 | if ( dirlevel < MAX_DIR_LEVELS ) { |
939 | dirpos[dirlevel] = dirstart; | 984 | dirpos[dirlevel] = dirstart; |
@@ -1306,12 +1351,26 @@ static bool dirbrowse(const char *root, const int *dirfilter) | |||
1306 | TIME_AFTER(current_tick, thumbnail_time)) | 1351 | TIME_AFTER(current_tick, thumbnail_time)) |
1307 | { /* a delayed hovering thumbnail is due now */ | 1352 | { /* a delayed hovering thumbnail is due now */ |
1308 | int res; | 1353 | int res; |
1309 | DEBUGF("Playing directory thumbnail: %s", currdir); | 1354 | if (dircache[lasti].attr & ATTR_DIRECTORY) |
1310 | res = play_dirname(lasti); | 1355 | { |
1311 | if (res < 0) /* failed, not existing */ | 1356 | DEBUGF("Playing directory thumbnail: %s", currdir); |
1312 | { /* say the number instead, as a fallback */ | 1357 | res = play_dirname(lasti); |
1313 | talk_id(VOICE_DIR, false); | 1358 | if (res < 0) /* failed, not existing */ |
1314 | talk_number(lasti+1, true); | 1359 | { /* say the number instead, as a fallback */ |
1360 | talk_id(VOICE_DIR, false); | ||
1361 | talk_number(lasti+1, true); | ||
1362 | } | ||
1363 | } | ||
1364 | else | ||
1365 | { | ||
1366 | DEBUGF("Playing file thumbnail: %s/%s%s\n", | ||
1367 | currdir, dircache[lasti].name, TALK_EXT); | ||
1368 | res = play_filename(currdir, dircache[lasti].name); | ||
1369 | if (res < 0) /* failed, not existing */ | ||
1370 | { /* say the number instead, as a fallback */ | ||
1371 | play_filenumber(lasti-dirsindir+1, | ||
1372 | dircache[lasti].attr); | ||
1373 | } | ||
1315 | } | 1374 | } |
1316 | thumbnail_time = -1; /* job done */ | 1375 | thumbnail_time = -1; /* job done */ |
1317 | } | 1376 | } |
@@ -1417,7 +1476,7 @@ static bool dirbrowse(const char *root, const int *dirfilter) | |||
1417 | if (dircache[i].attr & ATTR_DIRECTORY) /* directory? */ | 1476 | if (dircache[i].attr & ATTR_DIRECTORY) /* directory? */ |
1418 | { | 1477 | { |
1419 | /* play directory thumbnail */ | 1478 | /* play directory thumbnail */ |
1420 | if (global_settings.talk_dir == 4) /* hover */ | 1479 | if (global_settings.talk_dir == 3) /* hover */ |
1421 | { /* "schedule" a thumbnail, to have a little dalay */ | 1480 | { /* "schedule" a thumbnail, to have a little dalay */ |
1422 | thumbnail_time = current_tick + HOVER_DELAY; | 1481 | thumbnail_time = current_tick + HOVER_DELAY; |
1423 | } | 1482 | } |
@@ -1433,29 +1492,16 @@ static bool dirbrowse(const char *root, const int *dirfilter) | |||
1433 | } | 1492 | } |
1434 | else if (global_settings.talk_file == 1) /* files as numbers */ | 1493 | else if (global_settings.talk_file == 1) /* files as numbers */ |
1435 | { | 1494 | { |
1436 | /* try to find a voice ID for the extension, if known */ | 1495 | play_filenumber(i-dirsindir+1, |
1437 | unsigned int j; | 1496 | dircache[i].attr & TREE_ATTR_MASK); |
1438 | int ext_id = -1; /* default to none */ | ||
1439 | for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++) | ||
1440 | { | ||
1441 | if ((dircache[i].attr & TREE_ATTR_MASK) == filetypes[j].tree_attr) | ||
1442 | { | ||
1443 | ext_id = filetypes[j].voiceclip; | ||
1444 | break; | ||
1445 | } | ||
1446 | } | ||
1447 | |||
1448 | /* enqueue_next is true if still talking the dir name */ | ||
1449 | talk_id(VOICE_FILE, enqueue_next); | ||
1450 | talk_number(i-dirsindir+1, true); | ||
1451 | talk_id(ext_id, true); | ||
1452 | enqueue_next = false; | ||
1453 | } | 1497 | } |
1454 | else if (global_settings.talk_file == 2) /* files spelled */ | 1498 | else if (global_settings.talk_file == 2) /* files spelled */ |
1455 | { | 1499 | { |
1456 | /* enqueue_next is true if still talking the dir name */ | 1500 | talk_spell(dircache[i].name, false); |
1457 | talk_spell(dircache[i].name, enqueue_next); | 1501 | } |
1458 | enqueue_next = false; | 1502 | else if (global_settings.talk_file == 3) /* hover */ |
1503 | { /* "schedule" a thumbnail, to have a little dalay */ | ||
1504 | thumbnail_time = current_tick + HOVER_DELAY; | ||
1459 | } | 1505 | } |
1460 | 1506 | ||
1461 | } | 1507 | } |