[ANNOUNCE] libao support for speechdispatcher (with working pulseaudio :-) )
- From: Halim Sahin <halim sahin freenet de>
- To: gnome-accessibility-list gnome org
- Subject: [ANNOUNCE] libao support for speechdispatcher (with working pulseaudio :-) )
- Date: Thu, 17 Dec 2009 10:57:49 +0100
Hi,
Please use attached diff for (speechd from Luke's git repo) to add libao
support.
Libao is a cross platform audio library for playing sound.
Marco Skambraks has written a libao driver for speechd which works out
of box with pulse.
Use libao as audiooutputmethod in spechd.conf.
libao uses pulse if
default_driver=pulse
is set in /etc/libao.conf
It supports also oss alsa sun irix ...
FEDBACK TO:
marco openblinux de
halim openblinux de
I have tested libao with it's pulseaudio plugin and it works great.
A crash of pulseaudio doesn't affect speechd.
After a resume of pa speech comes back.
Have a lot of fun.
Halim
--
----------------------
Halim Sahin
The OpenBlinux Project
diff -ruN speechd/configure.in myspeechd/configure.in
--- speechd/configure.in 2009-12-16 11:47:43.000000000 +0100
+++ myspeechd/configure.in 2009-12-16 11:49:25.000000000 +0100
@@ -203,6 +203,25 @@
AM_CONDITIONAL(nas_support, test $nas_aud = "true")
+AC_CHECK_LIB(ao,
+ ao_play,
+ libao_aud="true";echo "Compiling with libao support.";,
+ libao_aud="false";echo "*** libao library missing. Compiling without libao support! See INSTALL.";)
+
+AC_ARG_WITH(libao, AS_HELP_STRING(--with-libao, Compile with libao support),
+ if test $withval = "no"; then
+ echo "Forced compilation without libao support.";
+ libao_aud="false";
+ else
+ if test $libao_aud = "false"; then
+ echo "libao support is not available. Sorry."; exit 1;
+ fi
+ fi
+ echo "")
+
+AM_CONDITIONAL(libao_support, test $libao_aud = "true")
+
+
AC_CHECK_LIB(asound,
snd_pcm_open,
alsa_aud="true";echo "Compiling with ALSA support.";,
diff -ruN speechd/src/audio/Makefile.am myspeechd/src/audio/Makefile.am
--- speechd/src/audio/Makefile.am 2009-12-16 11:47:43.000000000 +0100
+++ myspeechd/src/audio/Makefile.am 2009-12-16 11:49:25.000000000 +0100
@@ -18,12 +18,16 @@
ALSA_FLAGS = -DWITH_ALSA
ALSA_LIBS = -lasound
endif
+if libao_support
+LIBAO_FLAGS = -DWITH_LIBAO
+LIBAO_LIBS = -lao
+endif
-EXTRA_DIST = alsa.c oss.c nas.c pulse.c
+EXTRA_DIST = alsa.c libao.c oss.c nas.c pulse.c
-AM_CFLAGS = $(am_cflags) $(NAS_FLAGS) $(PULSE_FLAGS) $(ALSA_FLAGS)
-libsdaudio_la_LDFLAGS = -version-info @LIB_SDAUDIO_CURRENT@:@LIB_SDAUDIO_REVISION@:@LIB_SDAUDIO_AGE@ -lpthread $(NAS_LIBS) $(PULSE_LIBS) $(ALSA_LIBS)
+AM_CFLAGS = $(am_cflags) $(NAS_FLAGS) $(PULSE_FLAGS) $(ALSA_FLAGS) $(LIBAO_FLAGS)
+libsdaudio_la_LDFLAGS = -version-info @LIB_SDAUDIO_CURRENT@:@LIB_SDAUDIO_REVISION@:@LIB_SDAUDIO_AGE@ -lpthread $(NAS_LIBS) $(PULSE_LIBS) $(ALSA_LIBS) $(LIBAO_LIBS)
spdlib_LTLIBRARIES = libsdaudio.la
diff -ruN speechd/src/audio/libao.c myspeechd/src/audio/libao.c
--- speechd/src/audio/libao.c 1970-01-01 01:00:00.000000000 +0100
+++ myspeechd/src/audio/libao.c 2009-12-16 11:50:50.000000000 +0100
@@ -0,0 +1,191 @@
+/*
+ * libao.c -- The libao backend for the spd_audio library.
+ *
+ * Author: Marco Skambraks <marco openblinux de>
+ * Date: 2009-12-15
+ *
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Leser General Public License as published by the Free
+ * Software Foundation; either version 2.1, or (at your option) any later
+ * version.
+ *
+ * This software 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 Lesser General Public License
+ * along with this package; see the file COPYING. If not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <sys/time.h>
+#include <time.h>
+#include <string.h>
+#include <ao/ao.h>
+
+/* send a packet of XXX bytes to the sound device */
+#define AO_SEND_BYTES 256
+/* Put a message into the logfile (stderr) */
+#define MSG(level, arg...) \
+ if(level <= log_level){ \
+ time_t t; \
+ struct timeval tv; \
+ char *tstr; \
+ t = time(NULL); \
+ tstr = strdup(ctime(&t)); \
+ tstr[strlen(tstr)-1] = 0; \
+ gettimeofday(&tv,NULL); \
+ fprintf(stderr," %s [%d]",tstr, (int) tv.tv_usec); \
+ fprintf(stderr," libao:: "); \
+ fprintf(stderr,arg); \
+ fprintf(stderr,"\n"); \
+ fflush(stderr); \
+ xfree(tstr); \
+ }
+
+#define ERR(arg...) \
+ { \
+ time_t t; \
+ struct timeval tv; \
+ char *tstr; \
+ t = time(NULL); \
+ tstr = strdup(ctime(&t)); \
+ tstr[strlen(tstr)-1] = 0; \
+ gettimeofday(&tv,NULL); \
+ fprintf(stderr," %s [%d]",tstr, (int) tv.tv_usec); \
+ fprintf(stderr," libao ERROR: "); \
+ fprintf(stderr,arg); \
+ fprintf(stderr,"\n"); \
+ fflush(stderr); \
+ xfree(tstr); \
+ }
+
+int libao_stop (AudioID * id);
+
+int libao_open (AudioID * id, void **pars);
+
+int libao_close (AudioID * id);
+
+int libao_play (AudioID * id, AudioTrack track);
+
+int libao_set_volume (AudioID * id, int volume);
+
+static volatile int ao_stop_playback = 0;
+
+static int default_driver;
+
+ao_device *device = NULL;
+
+int libao_open (AudioID * id, void **pars)
+{
+
+ ao_initialize ();
+ default_driver = ao_default_driver_id ();
+ return 0;
+}
+
+int libao_play (AudioID * id, AudioTrack track)
+{
+ int bytes_per_sample;
+
+ int num_bytes;
+
+ int outcnt = 0;
+
+ signed short *output_samples;
+
+ int i;
+
+ ao_sample_format format;
+
+ if (id == NULL)
+ return -1;
+ if (track.samples == NULL || track.num_samples <= 0)
+ return 0;
+
+ /* Choose the correct format */
+ format.bits = track.bits;
+ if (track.bits == 16)
+ bytes_per_sample = 2;
+ else if (track.bits == 8)
+ bytes_per_sample = 1;
+ else
+ {
+ ERR ("Audio: Unrecognized sound data format.\n");
+ return -10;
+ }
+ format.channels = track.num_channels;
+ format.rate = track.sample_rate;
+ format.byte_format = AO_FMT_LITTLE;
+ MSG (3, "Starting playback");
+ output_samples = track.samples;
+ num_bytes = track.num_samples * bytes_per_sample;
+ if (device == NULL)
+ device = ao_open_live (default_driver, &format, NULL);
+ if (device == NULL)
+ {
+ ERR ("error opening libao dev");
+ return -2;
+ }
+ MSG (3, "bytes to play: %d, (%f secs)", num_bytes,
+ (((float) (num_bytes) / 2) / (float) track.sample_rate));
+
+ ao_stop_playback = 0;
+ outcnt = 0;
+ i = 0;
+
+ while ((outcnt < num_bytes) && !ao_stop_playback)
+ {
+ if ((num_bytes - outcnt) > AO_SEND_BYTES)
+ i = AO_SEND_BYTES;
+ else
+ i = (num_bytes - outcnt);
+
+ if (!ao_play (device, (char *) output_samples + outcnt, i))
+ {
+ ao_close (device);
+ device = NULL;
+ ERR ("Audio: ao_play() - closing device - re-open it in next run\n");
+ }
+ outcnt += i;
+ }
+
+ return 0;
+
+}
+
+/* stop the libao_play() loop */
+int libao_stop (AudioID * id)
+{
+
+ ao_stop_playback = 1;
+ return 0;
+}
+
+int libao_close (AudioID * id)
+{
+
+ if (device != NULL)
+ ao_close (device);
+ device = NULL;
+
+ ao_shutdown ();
+ id = NULL;
+
+ return 0;
+}
+
+int libao_set_volume (AudioID * id, int volume)
+{
+ return 0;
+}
+
+/* Provide the libao backend. */
+AudioFunctions libao_functions =
+ { libao_open, libao_play, libao_stop, libao_close, libao_set_volume };
+
+#undef MSG
+#undef ERR
diff -ruN speechd/src/audio/spd_audio.c myspeechd/src/audio/spd_audio.c
--- speechd/src/audio/spd_audio.c 2009-12-16 11:47:43.000000000 +0100
+++ myspeechd/src/audio/spd_audio.c 2009-12-16 11:49:25.000000000 +0100
@@ -27,7 +27,7 @@
* playing 8 or 16 bit data, immediate stop and synchronization. This library
* currently provides OSS, NAS, ALSA and PulseAudio backend. The available backends are
* specified at compile-time using the directives WITH_OSS, WITH_NAS, WITH_ALSA,
- * WITH_PULSE, but the user program is allowed to switch between them at run-time.
+ * WITH_PULSE, WITH_LIBAO but the user program is allowed to switch between them at run-time.
*/
#include "spd_audio.h"
@@ -47,6 +47,9 @@
#ifdef WITH_OSS
#include "oss.c"
#endif
+#ifdef WITH_LIBAO
+#include "libao.c"
+#endif
/* The NAS backend */
#ifdef WITH_NAS
@@ -116,6 +119,7 @@
*error = strdup("The sound library wasn't compiled with OSS support.");
return NULL;
#endif
+
}
else if (type == AUDIO_ALSA){
#ifdef WITH_ALSA
@@ -180,6 +184,27 @@
return NULL;
#endif
}
+ else if (type == AUDIO_LIBAO){
+#ifdef WITH_LIBAO
+ id->function = (Funct*) &libao_functions;
+
+ if (id->function->open != NULL){
+ ret = id->function->open(id, pars);
+ if (ret != 0){
+ *error = (char*) strdup("Couldn't open libao");
+ return NULL;
+ }
+ }
+ else{
+ *error = (char*) strdup("Couldn't open libao module.");
+ return NULL;
+ }
+ id->type = AUDIO_LIBAO;
+#else
+ *error = strdup("The sound library wasn't compiled with libao support.");
+ return NULL;
+#endif
+ }
else{
*error = (char*) strdup("Unknown device");
return NULL;
diff -ruN speechd/src/audio/spd_audio.h myspeechd/src/audio/spd_audio.h
--- speechd/src/audio/spd_audio.h 2009-12-16 11:47:43.000000000 +0100
+++ myspeechd/src/audio/spd_audio.h 2009-12-16 11:49:25.000000000 +0100
@@ -54,7 +54,7 @@
#define AUDIO_BUF_SIZE 4096
-typedef enum{AUDIO_OSS = 0, AUDIO_NAS = 1, AUDIO_ALSA=2, AUDIO_PULSE=3} AudioOutputType;
+typedef enum{AUDIO_OSS = 0, AUDIO_NAS = 1, AUDIO_ALSA=2, AUDIO_PULSE=3, AUDIO_LIBAO=4} AudioOutputType;
typedef enum{SPD_AUDIO_LE, SPD_AUDIO_BE} AudioFormat;
AudioFormat spd_audio_endian;
diff -ruN speechd/src/modules/module_utils.c myspeechd/src/modules/module_utils.c
--- speechd/src/modules/module_utils.c 2009-12-16 11:47:43.000000000 +0100
+++ myspeechd/src/modules/module_utils.c 2009-12-16 11:49:25.000000000 +0100
@@ -1150,6 +1150,15 @@
module_audio_output_method = AUDIO_OSS;
audio_output_set = 1;
}
+ } else if (len == 5 && strncmp("libao", outputs, len) == 0){
+ DBG("Using libao audio output method");
+ module_audio_pars[0] = NULL;
+ module_audio_pars[1] = NULL;
+ module_audio_id = spd_audio_open(AUDIO_LIBAO, (void**) module_audio_pars, &error);
+ if (module_audio_id){
+ module_audio_output_method = AUDIO_LIBAO;
+ audio_output_set = 1;
+ }
} else if (len == 4 && strncmp("alsa", outputs, len) == 0){
DBG("Using Alsa audio output method");
module_audio_pars[0] = audio_settings.audio_alsa_device;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]