From 78283bda64ee09502029cd2eee459fef1bd31385 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Fri, 26 Jul 2024 23:35:00 -0400 Subject: talk: Voice the volume name when browsing and when voicing full paths Change-Id: I56660e168edd135a09cd5c021504a58ec9d40093 --- apps/talk.c | 31 ++++++++++++++++++++++++++++--- apps/talk.h | 4 ++++ apps/tree.c | 6 ++++++ firmware/common/pathfuncs.c | 30 +++++++++++++++++++++++++++++- firmware/export/pathfuncs.h | 1 + 5 files changed, 68 insertions(+), 4 deletions(-) diff --git a/apps/talk.c b/apps/talk.c index 2e73001c46..ab4a97397c 100644 --- a/apps/talk.c +++ b/apps/talk.c @@ -44,6 +44,7 @@ #include "debug.h" #include "panic.h" #include "misc.h" /* time_split_units() */ +#include "mv.h" /***************** Constants *****************/ @@ -1167,6 +1168,21 @@ int talk_file_or_spell(const char *dirname, const char *filename, return 0; } +#ifdef HAVE_MULTIVOLUME +int talk_volume_id(int volume) +{ + if (volume == -1) + return 0; + + int drive = volume_drive(volume); + // XXX voice "VOLUME" or something like that? + + talk_id(drive? LANG_DISK_NAME_MMC : LANG_DISK_NAME_INTERNAL, true); + talk_value(volume, UNIT_INT, true); + return 1; +} +#endif + /* Play a directory's .talk thumbnail, fallback to spelling the filename, or go straight to spelling depending on settings. */ int talk_dir_or_spell(const char* dirname, @@ -1174,13 +1190,14 @@ int talk_dir_or_spell(const char* dirname, { if (global_settings.talk_dir_clip) { /* .talk clips enabled */ - if(talk_file(dirname, NULL, dir_thumbnail_name, NULL, + if (talk_file(dirname, NULL, dir_thumbnail_name, NULL, prefix_ids, enqueue) >0) return 0; } - if (global_settings.talk_dir == TALK_SPEAK_SPELL) + if (global_settings.talk_dir == TALK_SPEAK_SPELL) { /* Either .talk clips disabled or as a fallback */ return talk_spell_basename(dirname, prefix_ids, enqueue); + } return 0; } @@ -1201,12 +1218,20 @@ int talk_fullpath(const char* path, bool enqueue) while(ptr) { /* There are more slashes ahead */ /* temporarily poke a NULL at end of component to truncate string */ *ptr = '\0'; - talk_dir_or_spell(buf, NULL, true); +#ifdef HAVE_MULTIVOLUME + if (start == buf+1) { + int vol = path_get_volume_id(buf+1); + if (!talk_volume_id(vol)) + talk_dir_or_spell(buf, NULL, true); + } else +#endif + talk_dir_or_spell(buf, NULL, true); *ptr = '/'; /* restore string */ talk_id(VOICE_CHAR_SLASH, true); start = ptr+1; /* setup for next component */ ptr = strchr(start, '/'); } + /* no more slashes, final component is a filename */ return talk_file_or_spell(NULL, buf, NULL, true); } diff --git a/apps/talk.h b/apps/talk.h index 6139b9ec46..507d5cbed1 100644 --- a/apps/talk.h +++ b/apps/talk.h @@ -145,6 +145,10 @@ void talk_fractional(char *tbuf, int value, int unit); void talk_time(const struct tm *tm, bool enqueue); void talk_date(const struct tm *tm, bool enqueue); +#ifdef HAVE_MULTIVOLUME +int talk_volume_id(int volume); +#endif + /* speaks hr, min, sec, ms; unit_idx is lowest or base unit of the time value */ int talk_time_intervals(long time, int unit_idx, bool enqueue); diff --git a/apps/tree.c b/apps/tree.c index 8c41abbdcf..71a7ee3f62 100644 --- a/apps/tree.c +++ b/apps/tree.c @@ -1252,6 +1252,12 @@ static void say_filetype(int attr) static int ft_play_dirname(char* name) { +#ifdef HAVE_MULTIVOLUME + int vol = path_get_volume_id(name); + if (talk_volume_id(vol)) + return 1; +#endif + return talk_file(tc.currdir, name, dir_thumbnail_name, NULL, global_settings.talk_filetype ? TALK_IDARRAY(VOICE_DIR) : NULL, diff --git a/firmware/common/pathfuncs.c b/firmware/common/pathfuncs.c index db1935db8b..b5e5ecb0cf 100644 --- a/firmware/common/pathfuncs.c +++ b/firmware/common/pathfuncs.c @@ -127,7 +127,35 @@ void init_volume_names(void) VOL_START_TOK, voldec, volume, VOL_END_TOK); DEBUGF("vol<%d> = %s ", volume, buffer); } - DEBUGF("\n"); + DEBUGF("\n"); +} + +#include + +int path_get_volume_id(const char *name) +{ + int v = -1; + + if (!name || *name != VOL_START_TOK) + goto bail; + + do { + switch (*name) + { + case '0' ... '9': /* digit; parse volume number */ + v = (v * 10 + *name - '0') % VOL_NUM_MAX; + break; + case '\0': + case PATH_SEPCH: /* no closing bracket; no volume */ + v = -1; + goto bail; + default: /* something else; reset volume */ + v = 0; + } + } while (*++name != VOL_END_TOK); /* found end token? */ + +bail: + return v; } /* Returns on which volume this is and sets *nameptr to the portion of the diff --git a/firmware/export/pathfuncs.h b/firmware/export/pathfuncs.h index 73f20f9a52..fce8e5851c 100644 --- a/firmware/export/pathfuncs.h +++ b/firmware/export/pathfuncs.h @@ -83,6 +83,7 @@ int path_strip_last_volume(const char *name, const char **nameptr, bool greedy); int get_volume_name(int volume, char *name); int make_volume_root(int volume, char *dst); void init_volume_names(void); +int path_get_volume_id(const char *name); #endif int path_strip_drive(const char *name, const char **nameptr, bool greedy); -- cgit v1.2.3