Add:Core:Adding estimate of duration of speech
authortinloaf <tinloaf@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Mon, 5 Jan 2009 20:32:31 +0000 (20:32 +0000)
committertinloaf <tinloaf@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Mon, 5 Jan 2009 20:32:31 +0000 (20:32 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk@1898 ffa7fe5e-494d-0410-b361-a75ebd5db220

navit/navit/attr_def.h
navit/navit/navigation.c
navit/navit/navigation.h
navit/navit/navit.c
navit/navit/navit.h
navit/navit/navit.xml
navit/navit/speech.c
navit/navit/speech.h

index 199be1f..7f47eed 100644 (file)
@@ -88,6 +88,7 @@ ATTR(timeout)
 ATTR(orientation)
 ATTR(keyboard)
 ATTR(position_sats_signal)
+ATTR(cps)
 ATTR2(0x00028000,type_boolean_begin)
 /* boolean */
 ATTR(overwrite)
index 8f868c7..cf00bf3 100644 (file)
@@ -62,6 +62,7 @@ struct navigation {
        struct navigation_command *cmd_last;
        struct callback_list *callback_speech;
        struct callback_list *callback;
+       struct navit *navit;
        int level_last;
        struct item item_last;
        int turn_around;
@@ -100,7 +101,7 @@ angle_delta(int angle1, int angle2)
 }
 
 struct navigation *
-navigation_new(struct attr **attrs)
+navigation_new(struct attr *parent, struct attr **attrs)
 {
        int i,j;
        struct navigation *ret=g_new0(struct navigation, 1);
@@ -111,6 +112,7 @@ navigation_new(struct attr **attrs)
        ret->distance_last=-2;
        ret->distance_turn=50;
        ret->turn_around_limit=3;
+       ret->navit=parent->u.navit;
 
        for (j = 0 ; j <= route_item_last-route_item_first ; j++) {
                for (i = 0 ; i < 3 ; i++) {
@@ -1472,7 +1474,8 @@ show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct n
        struct navigation_command *cur,*prev;
        int distance=itm->dest_length-cmd->itm->dest_length;
        int l0_dist,level,dist,i,time;
-       char *ret,*old,*buf;
+       int speech_time,time2nav;
+       char *ret,*old,*buf,*next;
 
        if (type != attr_navigation_speech) {
                return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only in speech navigation
@@ -1489,6 +1492,7 @@ show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct n
        }
 
        ret = show_maneuver(nav, itm, cmd, type, 0);
+       time2nav = navigation_time(itm,cmd->itm->prev);
        old = NULL;
 
        cur = cmd->next;
@@ -1496,14 +1500,23 @@ show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct n
        i = 0;
        while (cur && cur->itm) {
                // We don't merge more than 3 announcements...
-               if (i > 1) {
+               if (i > 1) { // if you change this, please also change the value below, that is used to terminate the loop
                        break;
                }
+               
+               next = show_maneuver(nav,prev->itm, cur, type, 0);
+               speech_time = navit_speech_estimate(nav->navit,next);
+               g_free(next);
+
+               if (speech_time == -1) { // user didn't set cps
+                       speech_time = 30; // assume 3 seconds
+               }
 
                dist = prev->itm->dest_length - cur->itm->dest_length;
                time = navigation_time(prev->itm,cur->itm->prev);
 
-               if (time > 50) { // For now, we statically use 5 seconds...
+               if (time >= (speech_time + 30)) { // 3 seconds for understanding what has been said
+                       printf("Time: %i, speech_time: %i\n", time, speech_time);
                        break;
                }
 
@@ -1511,10 +1524,16 @@ show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct n
                buf = show_maneuver(nav, prev->itm, cur, type, 1);
                ret = g_strdup_printf("%s, %s", old, buf);
                g_free(buf);
-               g_free(old);
+               if (navit_speech_estimate(nav->navit,ret) > time2nav) {
+                       g_free(ret);
+                       ret = old;
+                       i = 2; // This will terminate the loop
+               } else {
+                       g_free(old);
+               }
 
                // If the two maneuvers are *really* close, we shouldn't tell the second one again, because TTS won't be fast enough
-               if (time <= 30) {
+               if (time <= speech_time) {
                        cur->itm->told = 1;
                }
 
index ef8ebb8..0aea185 100644 (file)
@@ -31,7 +31,7 @@ struct callback;
 struct map;
 struct navigation;
 struct route;
-struct navigation *navigation_new(struct attr **attrs);
+struct navigation *navigation_new(struct attr *parent, struct attr **attrs);
 int navigation_set_announce(struct navigation *this_, enum item_type type, int *level);
 void navigation_update(struct navigation *this_, struct route *route);
 void navigation_flush(struct navigation *this_);
index a66d882..013fb3a 100644 (file)
@@ -977,6 +977,12 @@ navit_textfile_debug_log(struct navit *this_, const char *fmt, ...)
                va_end(ap);
 }
 
+int 
+navit_speech_estimate(struct navit *this_, char *str)
+{
+       return speech_estimate_duration(this_->speech, str);
+}
+
 void
 navit_say(struct navit *this_, char *text)
 {
index 2c0e1be..997a359 100644 (file)
@@ -65,6 +65,7 @@ struct graphics *navit_get_graphics(struct navit *this_);
 void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description);
 void navit_add_bookmark(struct navit *this_, struct pcoord *c, const char *description);
 void navit_say(struct navit *this_, char *text);
+int navit_speech_estimate(struct navit *this_, char *str);
 void navit_speak(struct navit *this_);
 void navit_window_roadbook_destroy(struct navit *this_);
 void navit_window_roadbook_new(struct navit *this_);
index 3ba3d6b..21dc49c 100644 (file)
         </navigation>
 
         <!-- Navit provides speech output in text format.
-             If you have a speech synthesizer like festival lite installed, you can get turn by turn directions out of navit.
+             If you have a speech synthesizer like festival lite installed, you can get turn by turn directions out of navit. Please set the "cps"-value to how many characters your tts engine approximately speaks per second.
              The default is text output to the shell -->
-        <speech type="cmdline" data="echo 'Fix the speech tag in navit.xml to let navit say:' '%s'"/>
+        <speech type="cmdline" data="echo 'Fix the speech tag in navit.xml to let navit say:' '%s'" cps="15"/>
         <!-- <speech type="cmdline" data="flite -t '%s'"/> -->
 
         <!-- If you have the reiseplaner maps installed, set enabled="yes" in the next line and set the path correctly -->
index 817832d..b3df169 100644 (file)
@@ -88,6 +88,32 @@ speech_get_attr(struct speech *this_, enum attr_type type, struct attr *attr, st
 }
 
 /**
+ * @brief Tries to estimate how long it will take to speak a certain string
+ *
+ * This function tries to estimate how long it will take to speak a certain string
+ * passed in str. It relies on the "characters per second"-value passed from the
+ * configuration.
+ *
+ * @param this_ The speech whose speed should be used
+ * @param str The string that should be estimated
+ * @return Time in tenth of seconds or -1 on error
+ */
+int
+speech_estimate_duration(struct speech *this_, char *str)
+{
+       int count;
+       struct attr cps_attr;
+   
+       if (!speech_get_attr(this_,attr_cps,&cps_attr,NULL)) {
+               return -1;
+       }
+
+       count = strlen(str);
+       
+       return (count * 10) / cps_attr.u.num;
+}
+
+/**
  * @brief Sets an attribute from an speech plugin
  *
  * This sets an attribute of a speech plugin, overwriting an attribute of the same type if it
index e736118..ef7c594 100644 (file)
@@ -34,6 +34,7 @@ int speech_sayf(struct speech *this_, const char *format, ...);
 void speech_destroy(struct speech *this_);
 int speech_get_attr(struct speech *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter);
 int speech_set_attr(struct speech *this_, struct attr *attr);
+int speech_estimate_duration(struct speech *this_, char *str);
 /* end of prototypes */
 
 #endif