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
This commit is contained in:
Jörg Hohensohn 2004-10-06 21:37:46 +00:00
parent 6f9a7eb2c7
commit d48442039e
6 changed files with 112 additions and 69 deletions

View file

@ -2390,16 +2390,16 @@ voice: "als Zahl"
new: "als Zahl"
id: LANG_VOICE_DIR_ENTER
desc: "talkbox" mode for directories
eng: "on enter"
voice: "beim Betreten"
new: "beim Betreten"
desc: DEPRECATED
eng: ""
voice: ""
new: ""
id: LANG_VOICE_DIR_HOVER
desc: "talkbox" mode for directories
eng: "while hovering"
voice: "mit Zeiger"
new: "mit Cursor"
desc: "talkbox" mode for directories + files
eng: ".talk mp3 clip"
voice: "Sprachdatei"
new: ".talk mp3 Datei"
id: VOICE_FILE
desc: spoken only, prefix for file number

View file

@ -2404,15 +2404,15 @@ voice: "Numbers"
new:
id: LANG_VOICE_DIR_ENTER
desc: "talkbox" mode for directories
eng: "on enter"
voice: "on enter"
desc: DEPRECATED
eng: ""
voice: ""
new:
id: LANG_VOICE_DIR_HOVER
desc: "talkbox" mode for directories
eng: "while hovering"
voice: "while hovering"
desc: "talkbox" mode for directories + files
eng: ".talk mp3 clip"
voice: "talk mp3 clip"
new:
id: VOICE_FILE

View file

@ -71,7 +71,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
#define CONFIG_BLOCK_VERSION 16
#define CONFIG_BLOCK_VERSION 17
#define CONFIG_BLOCK_SIZE 512
#define RTC_BLOCK_SIZE 44
@ -150,6 +150,7 @@ Rest of config block, only saved to disk:
static const char off_on[] = "off,on";
static const char off_on_ask[] = "off,on,ask";
static const char graphic_numeric[] = "graphic,numeric";
static const char off_number_spell_hover[] = "off,number,spell,hover";
/* the part of the settings which ends up in the RTC RAM, where available
(those we either need early, save frequently, or without spinup) */
@ -319,8 +320,8 @@ static const struct bit_entry hd_bits[] =
{1, S_O(line_in), false, "line in", off_on },
#endif
/* voice */
{3, S_O(talk_dir), 0, "talk dir", "off,number,spell,enter,hover" },
{2, S_O(talk_file), 0, "talk file", "off,number,spell" },
{2, S_O(talk_dir), 0, "talk dir", off_number_spell_hover },
{2, S_O(talk_file), 0, "talk file", off_number_spell_hover },
{1, S_O(talk_menu), true, "talk menu", off_on },
/* If values are just added to the end, no need to bump the version. */

View file

@ -898,28 +898,24 @@ static bool voice_menus(void)
return ret;
}
static bool voice_dirs(void)
{
static const struct opt_items names[] = {
/* this is used 2 times below, so it saves memory to put it in global scope */
static const struct opt_items voice_names[] = {
{ STR(LANG_OFF) },
{ STR(LANG_VOICE_NUMBER) },
{ STR(LANG_VOICE_SPELL) },
{ STR(LANG_VOICE_DIR_ENTER) },
{ STR(LANG_VOICE_DIR_HOVER) }
};
static bool voice_dirs(void)
{
return set_option( str(LANG_VOICE_DIR),
&global_settings.talk_dir, INT, names, 5, NULL);
&global_settings.talk_dir, INT, voice_names, 4, NULL);
}
static bool voice_files(void)
{
static const struct opt_items names[] = {
{ STR(LANG_OFF) },
{ STR(LANG_VOICE_NUMBER) },
{ STR(LANG_VOICE_SPELL) }
};
return set_option( str(LANG_VOICE_FILE),
&global_settings.talk_file, INT, names, 3, NULL);
&global_settings.talk_file, INT, voice_names, 4, NULL);
}
static bool voice_menu(void)

View file

@ -55,8 +55,8 @@ enum {
#define STR(id) ID2P(id), id
/* publish this string, so it's stored only once (better than #define) */
extern const char* const dir_thumbnail_name;
extern const char* const dir_thumbnail_name; /* "_dirname.talk" */
#define TALK_EXT ".talk" /* extra extension for file voicing */
void talk_init(void);
int talk_buffer_steal(void); /* claim the mp3 buffer e.g. for play/record */

View file

@ -221,6 +221,25 @@ static int build_playlist(int start_index)
return start_index;
}
static int play_filenumber(int pos, int attr)
{
/* try to find a voice ID for the extension, if known */
unsigned int j;
int ext_id = -1; /* default to none */
for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
{
if (attr == filetypes[j].tree_attr)
{
ext_id = filetypes[j].voiceclip;
break;
}
}
talk_id(VOICE_FILE, false);
talk_number(pos, true);
talk_id(ext_id, true);
return 1;
}
static int play_dirname(int start_index)
{
@ -250,6 +269,41 @@ static int play_dirname(int start_index)
return 1;
}
static int play_filename(char *dir, char *file)
{
int fd;
char name_mp3_filename[MAX_PATH+1];
if (mpeg_status() & MPEG_STATUS_PLAY)
return 0;
if (strcasecmp(&file[strlen(file) - strlen(TALK_EXT)], TALK_EXT))
{ /* file has no .talk extension */
snprintf(name_mp3_filename, sizeof(name_mp3_filename),
"%s/%s" TALK_EXT, dir, file);
/* check if a corresponding .talk file exists */
DEBUGF("Checking for Filename Thumb %s\n", name_mp3_filename);
fd = open(name_mp3_filename, O_RDONLY);
if (fd < 0)
{
DEBUGF("Failed to find: %s\n", name_mp3_filename);
return -1;
}
DEBUGF("Found: %s\n", name_mp3_filename);
close(fd);
talk_file(name_mp3_filename, false);
}
else
{ /* it already is a .talk file, play this directly */
snprintf(name_mp3_filename, sizeof(name_mp3_filename),
"%s/%s", dir, file);
talk_id(LANG_VOICE_DIR_HOVER, false); /* prefix it */
talk_file(name_mp3_filename, true);
}
return 1;
}
static int compare(const void* p1, const void* p2)
{
@ -771,7 +825,6 @@ static bool dirbrowse(const char *root, const int *dirfilter)
int lastdircursor=-1;
bool need_update = true;
bool exit_func = false;
bool enqueue_next = false;
long thumbnail_time = -1; /* for delaying a thumbnail */
bool update_all = false; /* set this to true when the whole file list
has been refreshed on screen */
@ -926,14 +979,6 @@ static bool dirbrowse(const char *root, const int *dirfilter)
snprintf(buf,sizeof(buf),"/%s",file->name);
if (file->attr & ATTR_DIRECTORY) {
if (global_settings.talk_dir == 3) /* enter */
{
/* play_dirname */
DEBUGF("Playing directory thumbnail: %s", currdir);
play_dirname(dircursor+dirstart);
/* avoid reading getting cut by next filename */
enqueue_next = true;
}
memcpy(currdir,buf,sizeof(currdir));
if ( dirlevel < MAX_DIR_LEVELS ) {
dirpos[dirlevel] = dirstart;
@ -1306,6 +1351,8 @@ static bool dirbrowse(const char *root, const int *dirfilter)
TIME_AFTER(current_tick, thumbnail_time))
{ /* a delayed hovering thumbnail is due now */
int res;
if (dircache[lasti].attr & ATTR_DIRECTORY)
{
DEBUGF("Playing directory thumbnail: %s", currdir);
res = play_dirname(lasti);
if (res < 0) /* failed, not existing */
@ -1313,6 +1360,18 @@ static bool dirbrowse(const char *root, const int *dirfilter)
talk_id(VOICE_DIR, false);
talk_number(lasti+1, true);
}
}
else
{
DEBUGF("Playing file thumbnail: %s/%s%s\n",
currdir, dircache[lasti].name, TALK_EXT);
res = play_filename(currdir, dircache[lasti].name);
if (res < 0) /* failed, not existing */
{ /* say the number instead, as a fallback */
play_filenumber(lasti-dirsindir+1,
dircache[lasti].attr);
}
}
thumbnail_time = -1; /* job done */
}
status_draw(false);
@ -1417,7 +1476,7 @@ static bool dirbrowse(const char *root, const int *dirfilter)
if (dircache[i].attr & ATTR_DIRECTORY) /* directory? */
{
/* play directory thumbnail */
if (global_settings.talk_dir == 4) /* hover */
if (global_settings.talk_dir == 3) /* hover */
{ /* "schedule" a thumbnail, to have a little dalay */
thumbnail_time = current_tick + HOVER_DELAY;
}
@ -1433,29 +1492,16 @@ static bool dirbrowse(const char *root, const int *dirfilter)
}
else if (global_settings.talk_file == 1) /* files as numbers */
{
/* try to find a voice ID for the extension, if known */
unsigned int j;
int ext_id = -1; /* default to none */
for (j=0; j<sizeof(filetypes)/sizeof(*filetypes); j++)
{
if ((dircache[i].attr & TREE_ATTR_MASK) == filetypes[j].tree_attr)
{
ext_id = filetypes[j].voiceclip;
break;
}
}
/* enqueue_next is true if still talking the dir name */
talk_id(VOICE_FILE, enqueue_next);
talk_number(i-dirsindir+1, true);
talk_id(ext_id, true);
enqueue_next = false;
play_filenumber(i-dirsindir+1,
dircache[i].attr & TREE_ATTR_MASK);
}
else if (global_settings.talk_file == 2) /* files spelled */
{
/* enqueue_next is true if still talking the dir name */
talk_spell(dircache[i].name, enqueue_next);
enqueue_next = false;
talk_spell(dircache[i].name, false);
}
else if (global_settings.talk_file == 3) /* hover */
{ /* "schedule" a thumbnail, to have a little dalay */
thumbnail_time = current_tick + HOVER_DELAY;
}
}