Hook aoview directly to alsa
authorKeith Packard <keithp@keithp.com>
Sat, 11 Jul 2009 07:56:13 +0000 (00:56 -0700)
committerKeith Packard <keithp@keithp.com>
Sat, 11 Jul 2009 07:56:13 +0000 (00:56 -0700)
This skips the flite internal audio stuff which opened and closed the audio
device for each phrase. This caused the first part of some phrases to be
missed when using an external audio device.

Signed-off-by: Keith Packard <keithp@keithp.com>
aoview/Makefile.am
aoview/aoview_flite.c
aoview/aoview_voice.c
configure.ac

index c354aa0..00851b6 100644 (file)
@@ -1,9 +1,9 @@
 VERSION=$(shell git describe)
-AM_CFLAGS=$(GNOME_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\" @FLITE_INCS@
+AM_CFLAGS=$(GNOME_CFLAGS) $(ALSA_CFLAGS) -I$(top_srcdir)/src -DAOVIEW_VERSION=\"$(VERSION)\" @FLITE_INCS@
 
 bin_PROGRAMS=aoview
 
-aoview_LDADD=$(GNOME_LIBS) $(FLITE_LIBS)
+aoview_LDADD=$(GNOME_LIBS) $(FLITE_LIBS) $(ALSA_LIBS)
 
 aoview_SOURCES = \
        aoview_main.c \
index bca1904..2673824 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdio.h>
 #include <flite/flite.h>
 #include "aoview.h"
+#include <alsa/asoundlib.h>
 
 cst_voice *register_cmu_us_kal();
 static cst_voice *voice;
@@ -25,14 +26,58 @@ static cst_voice *voice;
 static FILE *pipe_write;
 static GThread *aoview_flite_thread;
 
+static snd_pcm_t       *alsa_handle;
+
 gpointer
 aoview_flite_task(gpointer data)
 {
        FILE            *input = data;
        char            line[1024];
+       cst_wave        *wave;
+       int             rate;
+       int             channels;
+       int             err;
 
-       while (fgets(line, sizeof (line) - 1, input) != NULL)
-               flite_text_to_speech(line, voice, "play");
+       err = snd_pcm_open(&alsa_handle, "default",
+                          SND_PCM_STREAM_PLAYBACK, 0);
+       if (err >= 0)
+       {
+               if (err < 0) {
+                       snd_pcm_close(alsa_handle);
+                       alsa_handle = 0;
+               }
+       }
+       rate = 0;
+       channels = 0;
+       while (fgets(line, sizeof (line) - 1, input) != NULL) {
+               if (!alsa_handle)
+                       continue;
+               wave = flite_text_to_wave(line, voice);
+               if (wave->sample_rate != rate ||
+                   wave->num_channels != channels)
+               {
+                       rate = wave->sample_rate;
+                       channels = wave->num_channels;
+                       snd_pcm_set_params(alsa_handle,
+                                          SND_PCM_FORMAT_S16,
+                                          SND_PCM_ACCESS_RW_INTERLEAVED,
+                                          channels,
+                                          rate,
+                                          1,
+                                          100000);
+               }
+               snd_pcm_prepare(alsa_handle);
+               err = snd_pcm_writei(alsa_handle,
+                                    wave->samples,
+                                    wave->num_samples);
+               if (err < 0)
+                       fprintf(stderr, "alsa write error %s\n",
+                               strerror(-err));
+               snd_pcm_drain(alsa_handle);
+               delete_wave(wave);
+       }
+       snd_pcm_close(alsa_handle);
+       alsa_handle = 0;
        return NULL;
 }
 
index f7c099b..24422df 100644 (file)
@@ -24,6 +24,8 @@ FILE  *aoview_flite;
 
 void aoview_voice_open(void)
 {
+       int     err;
+
        if (!aoview_flite)
                aoview_flite = aoview_flite_start();
 }
index f55c7ec..495e118 100644 (file)
@@ -57,6 +57,8 @@ PKG_CHECK_MODULES([GNOME], [gtk+-2.0 libglade-2.0 gconf-2.0])
 
 PKG_CHECK_MODULES([LIBUSB], [libusb-1.0])
 
+PKG_CHECK_MODULES([ALSA], [alsa])
+
 AC_OUTPUT([
 Makefile
 aoview/Makefile