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;
}
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);
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++) {
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
}
ret = show_maneuver(nav, itm, cmd, type, 0);
+ time2nav = navigation_time(itm,cmd->itm->prev);
old = NULL;
cur = cmd->next;
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;
}
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;
}
</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 -->
}
/**
+ * @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