summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-06-29 23:05:27 -0700
committerKeith Packard <keithp@keithp.com>2009-06-29 23:05:27 -0700
commit4ca2d910f3be689fd3c78a4f1be0555d6b1a30c1 (patch)
treebf84ba9d1919c3c5ab4364b0a80fbe6e4dd6699c
parent527d7c803ed9597b210634018cb2eb9d048d9846 (diff)
Use flite to announce flight state
This uses the flite voice synthesis library from festival to announce altitude and speed information during the rocket flight. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--aoview/Makefile.am14
-rw-r--r--aoview/aoview.glade20
-rw-r--r--aoview/aoview.h7
-rw-r--r--aoview/aoview_flite.c39
-rw-r--r--aoview/aoview_main.c2
-rw-r--r--aoview/aoview_state.c51
-rw-r--r--aoview/aoview_voice.c91
-rw-r--r--configure.ac10
8 files changed, 232 insertions, 2 deletions
diff --git a/aoview/Makefile.am b/aoview/Makefile.am
index be3fbacf..86811bfe 100644
--- a/aoview/Makefile.am
+++ b/aoview/Makefile.am
@@ -1,7 +1,11 @@
VERSION=$(shell git describe)
-AM_CFLAGS=$(GNOME_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\"
+AM_CFLAGS=$(GNOME_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\" @FLITE_INCS@
-bin_PROGRAMS=aoview
+if USE_FLITE
+FLITE_PROG=aoview_flite
+endif
+
+bin_PROGRAMS=aoview $(FLITE_PROG)
aoview_LDADD=$(GNOME_LIBS)
@@ -18,8 +22,14 @@ aoview_SOURCES = \
aoview_util.c \
aoview_file.c \
aoview_eeprom.c \
+ aoview_voice.c \
aoview.h
+aoview_flite_SOURCES = \
+ aoview_flite.c
+
+aoview_flite_LDADD=@FLITE_LIBS@
+
BUILT_SOURCES = aoview_glade.h
CLEANFILES = aoview_glade.h
diff --git a/aoview/aoview.glade b/aoview/aoview.glade
index f3989999..153db1e3 100644
--- a/aoview/aoview.glade
+++ b/aoview/aoview.glade
@@ -222,6 +222,26 @@
</widget>
</child>
<child>
+ <widget class="GtkMenuItem" id="menuitem6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Voice</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu6">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckMenuItem" id="voice_enable">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Enable _Voice</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
<widget class="GtkMenuItem" id="menuitem4">
<property name="visible">True</property>
<property name="label" translatable="yes">_Help</property>
diff --git a/aoview/aoview.h b/aoview/aoview.h
index 6fb5e098..1ad9e160 100644
--- a/aoview/aoview.h
+++ b/aoview/aoview.h
@@ -220,4 +220,11 @@ aoview_eeprom_save(const char *device);
void
aoview_eeprom_init(GladeXML *xml);
+/* aoview_voice.c */
+void aoview_voice_open(void);
+
+void aoview_voice_close(void);
+
+void aoview_voice_speak(char *format, ...);
+
#endif /* _AOVIEW_H_ */
diff --git a/aoview/aoview_flite.c b/aoview/aoview_flite.c
new file mode 100644
index 00000000..daa3ed36
--- /dev/null
+++ b/aoview/aoview_flite.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdio.h>
+#include <flite/flite.h>
+
+cst_voice *register_cmu_us_kal();
+
+int
+main(int argc, char **argv)
+{
+ char line[1024];
+ cst_voice *v;
+
+ flite_init();
+ v = register_cmu_us_kal();
+ if (!v) {
+ perror("register voice");
+ exit(1);
+ }
+ while (fgets(line, sizeof (line) - 1, stdin) != NULL) {
+ flite_text_to_speech(line, v, "play");
+ }
+ exit (0);
+}
diff --git a/aoview/aoview_main.c b/aoview/aoview_main.c
index 45907519..6833a84a 100644
--- a/aoview/aoview_main.c
+++ b/aoview/aoview_main.c
@@ -77,6 +77,8 @@ int main(int argc, char **argv)
assert(about_dialog);
gtk_about_dialog_set_version(about_dialog, AOVIEW_VERSION);
+ aoview_voice_init(xml);
+
aoview_dev_dialog_init(xml);
aoview_state_init(xml);
diff --git a/aoview/aoview_state.c b/aoview/aoview_state.c
index 52f581ff..13b0f73b 100644
--- a/aoview/aoview_state.c
+++ b/aoview/aoview_state.c
@@ -73,6 +73,55 @@ aoview_state_add_deg(char *label, double deg, char pos, char neg)
}
+static char *ascent_states[] = {
+ "boost",
+ "fast",
+ "coast",
+ 0,
+};
+
+void
+aoview_state_speak(struct aostate *state)
+{
+ static char last_state[32];
+ int i;
+ gboolean report = FALSE;
+ static time_t last_time;
+ time_t this_time;
+ static int last_altitude;
+ int this_altitude;
+
+ if (strcmp(state->state, last_state)) {
+ aoview_voice_speak("rocket state now %s\n", state->state);
+ if (!strcmp(state->state, "drogue"))
+ aoview_voice_speak("maximum altitude %d meters\n",
+ aoview_pres_to_altitude(min_pres) -
+ aoview_pres_to_altitude(state->ground_pres));
+ report = TRUE;
+ strcpy(last_state, state->state);
+ }
+ this_time = time(NULL);
+ this_altitude = aoview_pres_to_altitude(state->flight_pres) - aoview_pres_to_altitude(state->ground_pres);
+ if (this_time - last_time >= 10)
+ report = TRUE;
+ if (this_altitude / 1000 != last_altitude / 1000)
+ report = TRUE;
+
+ if (report) {
+ aoview_voice_speak("altitude %d meters\n",
+ this_altitude);
+ for (i = 0; ascent_states[i]; i++)
+ if (!strcmp(ascent_states[i], state->state)) {
+ aoview_voice_speak("speed %d meters per second\n",
+ state->flight_vel / 2700);
+ break;
+ }
+ }
+
+ last_time = this_time;
+ last_altitude = this_altitude;
+}
+
void
aoview_state_notify(struct aostate *state)
{
@@ -171,6 +220,7 @@ aoview_state_notify(struct aostate *state)
aoview_table_add_row("Pad GPS alt", "%gm", pad_alt);
}
aoview_table_finish();
+ aoview_state_speak(state);
}
void
@@ -193,4 +243,5 @@ void
aoview_state_init(GladeXML *xml)
{
aoview_state_new();
+ aoview_voice_speak("initializing rocket flight monitoring system\n");
}
diff --git a/aoview/aoview_voice.c b/aoview/aoview_voice.c
new file mode 100644
index 00000000..7f4e576e
--- /dev/null
+++ b/aoview/aoview_voice.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "aoview.h"
+
+#if HAVE_FLITE
+#include <stdarg.h>
+
+FILE *aoview_flite;
+
+void aoview_voice_open(void)
+{
+ if (!aoview_flite)
+ aoview_flite = popen("aoview_flite", "w");
+}
+
+void aoview_voice_close(void)
+{
+ if (aoview_flite) {
+ pclose(aoview_flite);
+ aoview_flite = NULL;
+ }
+}
+
+void aoview_voice_speak(char *format, ...)
+{
+ va_list ap;
+
+ if (aoview_flite) {
+ va_start(ap, format);
+ vfprintf(aoview_flite, format, ap);
+ fflush(aoview_flite);
+ va_end(ap);
+ }
+}
+
+#else
+void aoview_voice_open(void)
+{
+}
+
+void aoview_voice_close(void)
+{
+}
+
+void aoview_voice_speak(char *format, ...)
+{
+}
+#endif
+
+
+static GtkCheckMenuItem *voice_enable;
+
+static void
+aoview_voice_enable(GtkWidget *widget, gpointer data)
+{
+ if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) {
+ aoview_voice_open();
+ aoview_voice_speak("enable voice system\n");
+ } else {
+ aoview_voice_speak("disable voice system\n");
+ aoview_voice_close();
+ }
+}
+
+void
+aoview_voice_init(GladeXML *xml)
+{
+ aoview_voice_open();
+
+ voice_enable = GTK_CHECK_MENU_ITEM(glade_xml_get_widget(xml, "voice_enable"));
+ assert(voice_enable);
+
+ g_signal_connect(G_OBJECT(voice_enable), "toggled",
+ G_CALLBACK(aoview_voice_enable),
+ voice_enable);
+}
diff --git a/configure.ac b/configure.ac
index 178a53f4..b2467c3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,6 +43,16 @@ if test "x$GCC" = "xyes"; then
fi
AC_SUBST(WARN_CFLAGS)
+AC_CHECK_HEADERS(flite/flite.h,HAVE_FLITE_H=yes,HAVE_FLITE_H=no)
+AC_CHECK_LIB(flite, flite_init,HAVE_LIBFLITE=yes,HAVE_LIBFLITE=no,-lm)
+
+if test "x$HAVE_FLITE_H" = "xyes" -a "x$HAVE_LIBFLITE" = "xyes"; then
+ AC_DEFINE(HAVE_FLITE,1,[Define if the flite library is usable])
+ AC_SUBST(FLITE_LIBS,"-lflite_cmu_us_kal -lflite_usenglish -lflite_cmulex -lflite -lm")
+ AC_SUBST(FLITE_INCS,-Iflite)
+fi
+AM_CONDITIONAL(USE_FLITE,test "x$HAVE_FLITE_H" = "xyes" -a "x$HAVE_LIBFLITE" = "xyes")
+
PKG_CHECK_MODULES([GNOME], [gtk+-2.0 libglade-2.0 gconf-2.0])
PKG_CHECK_MODULES([LIBUSB], [libusb-1.0])