flite: Add the rms, slt, awb and kal voices

And allow switching between them.
diff --git a/configure.ac b/configure.ac
index 0b687d9..ce54f94 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,10 +243,9 @@
 	[with_flite=check])
 AS_IF([test $with_flite != "no"],
 	[AC_CHECK_LIB([flite], [flite_init],
-		[flite_basic="-lflite"],
+		[flite_basic="-lflite -lm"],
 		[AS_IF([test $with_flite = "yes"],
-			[AC_MSG_FAILURE([libflite is not available])])],
-		[-lm])
+			[AC_MSG_FAILURE([libflite is not available])])])
 	AC_CHECK_LIB([flite_usenglish], [usenglish_init],
 		[flite_basic="-lflite_usenglish ${flite_basic}"],
 		[AS_IF([test $with_flite = "yes"],
@@ -257,25 +256,36 @@
 		[AS_IF([test $with_flite = "yes"],
 			[AC_MSG_FAILURE([libflite_cmulex is not available])])],
 		[-lflite -lm])
+
 	AC_CHECK_LIB([flite_cmu_us_kal16], [register_cmu_us_kal16],
-		[with_flite=yes;
-		flite_kal="-lflite_cmu_us_kal16";
-		AC_DEFINE([HAVE_REGISTER_CMU_US_KAL16], [1],
-			[Use cmu_register_us_kal16 to register the 16-bit voice.])],
-		[AC_CHECK_LIB([flite_cmu_us_kal16], [register_cmu_us_kal],
-			[with_flite=yes;
-			flite_kal="-lflite_cmu_us_kal16"],
-			[AC_CHECK_LIB([flite_cmu_us_kal], [register_cmu_us_kal],
-				[with_flite=yes;
-				flite_kal="-lflite_cmu_us_kal"],
-				[AS_IF([test $with_flite = "yes"],
-					[AC_MSG_FAILURE([no flite voices found])])],
-				[$flite_basic -lm])],
-			[$flite_basic -lm])],
-		[$flite_basic -lm])])
+		[with_flite=yes; flite_voices="$flite_voices -lflite_cmu_us_kal16"
+		 AC_DEFINE([HAVE_REGISTER_CMU_US_KAL16], [1],
+                       [Use cmu_register_us_kal16 to register the kal 16-bit voice.])],
+		[], [$flite_basic])
+	AC_CHECK_LIB([flite_cmu_us_kal], [register_cmu_us_kal],
+		[with_flite=yes; flite_voices="$flite_voices -lflite_cmu_us_kal"
+		 AC_DEFINE([HAVE_REGISTER_CMU_US_KAL], [1],
+                       [Use cmu_register_us_kal to register the kal 8-bit voice.])],
+		[], [$flite_basic])
+	AC_CHECK_LIB([flite_cmu_us_awb], [register_cmu_us_awb],
+		[with_flite=yes; flite_voices="$flite_voices -lflite_cmu_us_awb"
+		 AC_DEFINE([HAVE_REGISTER_CMU_US_AWB], [1],
+                       [Use cmu_register_us_kal to register the awb voice.])],
+		[], [$flite_basic])
+	AC_CHECK_LIB([flite_cmu_us_rms], [register_cmu_us_rms],
+		[with_flite=yes; flite_voices="$flite_voices -lflite_cmu_us_rms"
+		 AC_DEFINE([HAVE_REGISTER_CMU_US_RMS], [1],
+                       [Use cmu_register_us_kal to register the rms voice.])],
+		[], [$flite_basic])
+	AC_CHECK_LIB([flite_cmu_us_slt], [register_cmu_us_slt],
+		[with_flite=yes; flite_voices="$flite_voices -lflite_cmu_us_slt"
+		 AC_DEFINE([HAVE_REGISTER_CMU_US_SLT], [1],
+                       [Use cmu_register_us_kal to register the slt voice.])],
+		[], [$flite_basic])
+])
 AM_CONDITIONAL([flite_support], [test $with_flite = "yes"])
 AC_SUBST([flite_basic])
-AC_SUBST([flite_kal])
+AC_SUBST([flite_voices])
 AS_IF([test $with_flite = "yes"], [output_modules="${output_modules} flite"])
 
 AC_CHECK_PROGS([FLITE], [flite])
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
index 259d3ee..33dc78d 100644
--- a/src/modules/Makefile.am
+++ b/src/modules/Makefile.am
@@ -121,7 +121,7 @@
 modulebin_PROGRAMS += sd_flite
 sd_flite_SOURCES = flite.c $(common_SOURCES)
 sd_flite_LDADD = $(top_builddir)/src/common/libcommon.la \
-	$(flite_kal) $(flite_basic) \
+	$(flite_voices) $(flite_basic) \
 	$(common_LDADD)
 endif
 
diff --git a/src/modules/flite.c b/src/modules/flite.c
index 46cdfce..be6560e 100644
--- a/src/modules/flite.c
+++ b/src/modules/flite.c
@@ -36,6 +36,13 @@
 #define DEBUG_MODULE 1
 DECLARE_DEBUG();
 
+/* These aren't declared in any header */
+extern cst_voice *register_cmu_us_kal16(void);
+extern cst_voice *register_cmu_us_kal(void);
+extern cst_voice *register_cmu_us_awb(void);
+extern cst_voice *register_cmu_us_rms(void);
+extern cst_voice *register_cmu_us_slt(void);
+
 /* Thread and process control */
 static int flite_speaking = 0;
 
@@ -44,11 +51,41 @@
 static signed int flite_volume = 0;
 
 /* Internal functions prototypes */
+static void flite_set_voice(const char *name);
 static void flite_set_rate(signed int rate);
 static void flite_set_pitch(signed int pitch);
 static void flite_set_volume(signed int pitch);
 
-/* Voice */
+/* Loaded voices */
+static cst_voice *kal16_cst_voice;
+static cst_voice *kal_cst_voice;
+static cst_voice *awb_cst_voice;
+static cst_voice *rms_cst_voice;
+static cst_voice *slt_cst_voice;
+
+static SPDVoice rms_voice = {
+		.name = "rms",
+		.language = "en",
+};
+static SPDVoice slt_voice = {
+		.name = "slt",
+		.language = "en",
+};
+static SPDVoice awb_voice = {
+		.name = "awb",
+		.language = "en",
+};
+static SPDVoice kal16_voice = {
+		.name = "kal16",
+		.language = "en",
+};
+static SPDVoice kal_voice = {
+		.name = "kal",
+		.language = "en",
+};
+static SPDVoice *voices[6]; /* One is left NULL */
+
+/* Current voice */
 static cst_voice *flite_voice;
 
 static int flite_stop = 0;
@@ -72,28 +109,72 @@
 
 int module_init(char **status_info)
 {
+	SPDVoice **v;
 	DBG("Module init");
 
 	module_audio_set_server();
 
 	*status_info = NULL;
 
-	/* Init flite and register a new voice */
+	/* Init flite and register voices */
 	flite_init();
 
+	v = voices;
+
+#ifdef HAVE_REGISTER_CMU_US_RMS
+	rms_cst_voice = register_cmu_us_rms();
+	if (rms_cst_voice)
+	{
+		*v++ = &rms_voice;
+		if (flite_voice == NULL)
+			flite_voice = rms_cst_voice;
+	}
+#endif
+
+#ifdef HAVE_REGISTER_CMU_US_SLT
+	slt_cst_voice = register_cmu_us_slt();
+	if (slt_cst_voice)
+	{
+		*v++ = &slt_voice;
+		if (flite_voice == NULL)
+			flite_voice = slt_cst_voice;
+	}
+#endif
+
+#ifdef HAVE_REGISTER_CMU_US_AWB
+	awb_cst_voice = register_cmu_us_awb();
+	if (awb_cst_voice)
+	{
+		*v++ = &awb_voice;
+		if (flite_voice == NULL)
+			flite_voice = awb_cst_voice;
+	}
+#endif
+
 #ifdef HAVE_REGISTER_CMU_US_KAL16
-	cst_voice *register_cmu_us_kal16();	/* This isn't declared in any headers. */
-	flite_voice = register_cmu_us_kal16();
-#else
-	cst_voice *register_cmu_us_kal();
-	flite_voice = register_cmu_us_kal();
-#endif /* HAVE_REGISTER_CMU_US_KAL16 */
+	kal16_cst_voice = register_cmu_us_kal16();
+	if (kal16_cst_voice)
+	{
+		*v++ = &kal16_voice;
+		if (flite_voice == NULL)
+			flite_voice = kal16_cst_voice;
+	}
+#endif
+
+#ifdef HAVE_REGISTER_CMU_US_KAL
+	kal_cst_voice = register_cmu_us_kal();
+	if (kal_cst_voice)
+	{
+		*v++ = &kal_voice;
+		if (flite_voice == NULL)
+			flite_voice = kal_cst_voice;
+	}
+#endif
 
 	if (flite_voice == NULL) {
-		DBG("Couldn't register the basic kal voice.\n");
-		*status_info = g_strdup("Can't register the basic kal voice. "
-					"Currently only kal is supported. Seems your FLite "
-					"installation is incomplete.");
+		DBG("Couldn't register a voice.\n");
+		*status_info = g_strdup("Can't register a voice. "
+					"Seems your FLite installation is incomplete.");
 		return -1;
 	}
 
@@ -111,15 +192,6 @@
 
 SPDVoice **module_list_voices(void)
 {
-	static SPDVoice voice = {
-#ifdef HAVE_REGISTER_CMU_US_KAL16
-			.name = "kal16",
-#else
-			.name = "kal",
-#endif
-			.language = "en",
-	};
-	static SPDVoice *voices[] = { &voice, NULL };
 	return voices;
 }
 
@@ -152,6 +224,7 @@
 	module_speak_ok();
 
 	/* Setting voice */
+	UPDATE_STRING_PARAMETER(voice.name, flite_set_voice);
 	UPDATE_PARAMETER(rate, flite_set_rate);
 	UPDATE_PARAMETER(volume, flite_set_volume);
 	UPDATE_PARAMETER(pitch, flite_set_pitch);
@@ -259,8 +332,16 @@
 		module_stop();
 	}
 
-	g_free(flite_voice);
-	flite_voice = NULL;
+	g_free(kal16_cst_voice);
+	kal16_cst_voice = NULL;
+	g_free(kal_cst_voice);
+	kal_cst_voice = NULL;
+	g_free(awb_cst_voice);
+	awb_cst_voice = NULL;
+	g_free(rms_cst_voice);
+	rms_cst_voice = NULL;
+	g_free(slt_cst_voice);
+	slt_cst_voice = NULL;
 	g_free(buf);
 	buf = NULL;
 
@@ -269,6 +350,21 @@
 
 /* Internal functions */
 
+static void flite_set_voice(const char *name)
+{
+	if (!strcmp(name, "kal16"))
+		flite_voice = kal16_cst_voice;
+	else if (!strcmp(name, "kal"))
+		flite_voice = kal_cst_voice;
+	else if (!strcmp(name, "awb"))
+		flite_voice = awb_cst_voice;
+	else if (!strcmp(name, "rms"))
+		flite_voice = rms_cst_voice;
+	else if (!strcmp(name, "slt"))
+		flite_voice = slt_cst_voice;
+	DBG("Unknown voice %s", name);
+}
+
 static void flite_set_rate(signed int rate)
 {
 	float stretch = 1;