From 4ca2d910f3be689fd3c78a4f1be0555d6b1a30c1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 29 Jun 2009 23:05:27 -0700 Subject: [PATCH] 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 --- aoview/Makefile.am | 14 ++++++- aoview/aoview.glade | 20 ++++++++++ aoview/aoview.h | 7 ++++ aoview/aoview_flite.c | 39 +++++++++++++++++++ aoview/aoview_main.c | 2 + aoview/aoview_state.c | 51 ++++++++++++++++++++++++ aoview/aoview_voice.c | 91 +++++++++++++++++++++++++++++++++++++++++++ configure.ac | 10 +++++ 8 files changed, 232 insertions(+), 2 deletions(-) create mode 100644 aoview/aoview_flite.c create mode 100644 aoview/aoview_voice.c 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 @@ -221,6 +221,26 @@ + + + True + _Voice + True + + + True + + + True + Enable _Voice + True + True + + + + + + True 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 + * + * 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 +#include + +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 + * + * 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 + +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]) -- 2.30.2