Files
extra/festival/speech_tools-sndio.patch
2025-06-22 20:39:04 -05:00

528 lines
16 KiB
Diff

diff --git speech_tools.orig/audio/Makefile speech_tools/audio/Makefile
index 6103654..1535faf 100644
--- speech_tools.orig/audio/Makefile
+++ speech_tools/audio/Makefile
@@ -44,7 +44,7 @@ LOCAL_DEFAULT_LIBRARY = estbase
H = audioP.h
CPPSRCS = gen_audio.cc nas.cc esd.cc sun16audio.cc \
mplayer.cc win32audio.cc irixaudio.cc os2audio.cc \
- macosxaudio.cc linux_sound.cc
+ macosxaudio.cc linux_sound.cc sndio.cc
SRCS = $(CPPSRCS)
OBJS = $(SRCS:.cc=.o)
diff --git speech_tools.orig/audio/audioP.h speech_tools/audio/audioP.h
index 6d49690..6c86ab1 100644
--- speech_tools.orig/audio/audioP.h
+++ speech_tools/audio/audioP.h
@@ -43,6 +43,7 @@ int play_nas_wave(EST_Wave &inwave, EST_Option &al);
int play_esd_wave(EST_Wave &inwave, EST_Option &al);
int play_sun16_wave(EST_Wave &inwave, EST_Option &al);
int play_linux_wave(EST_Wave &inwave, EST_Option &al);
+int play_sndio_wave(EST_Wave &inwave, EST_Option &al);
int play_mplayer_wave(EST_Wave &inwave, EST_Option &al);
int play_win32audio_wave(EST_Wave &inwave, EST_Option &al);
int play_irix_wave(EST_Wave &inwave, EST_Option &al);
@@ -52,5 +53,6 @@ int record_nas_wave(EST_Wave &inwave, EST_Option &al);
int record_esd_wave(EST_Wave &inwave, EST_Option &al);
int record_sun16_wave(EST_Wave &inwave, EST_Option &al);
int record_linux_wave(EST_Wave &inwave, EST_Option &al);
+int record_sndio_wave(EST_Wave &inwave, EST_Option &al);
#endif /* __AUDIOP_H__ */
diff --git speech_tools.orig/audio/gen_audio.cc speech_tools/audio/gen_audio.cc
index 985324a..ec286a4 100644
--- speech_tools.orig/audio/gen_audio.cc
+++ speech_tools/audio/gen_audio.cc
@@ -97,6 +97,8 @@ int play_wave(EST_Wave &inwave, EST_Option &al)
protocol = "win32audio";
else if (mplayer_supported)
protocol = "mplayeraudio";
+ else if (sndio_supported)
+ protocol = "sndioaudio";
else
protocol = "sunaudio";
}
@@ -121,6 +123,8 @@ int play_wave(EST_Wave &inwave, EST_Option &al)
else if ((upcase(protocol) == "FREEBSD16AUDIO") ||
(upcase(protocol) == "LINUX16AUDIO"))
return play_linux_wave(*toplay,al);
+ else if (upcase(protocol) == "SNDIOAUDIO")
+ return play_sndio_wave(*toplay,al);
else if (upcase(protocol) == "IRIXAUDIO")
return play_irix_wave(*toplay,al);
else if (upcase(protocol) == "MACOSXAUDIO")
@@ -263,6 +267,8 @@ EST_String options_supported_audio(void)
audios += " win32audio";
if (os2audio_supported)
audios += " os2audio";
+ if (sndio_supported)
+ audios += " sndioaudio";
return audios;
}
@@ -301,6 +307,8 @@ int record_wave(EST_Wave &wave, EST_Option &al)
protocol = "win32audio";
else if (mplayer_supported)
protocol = "mplayeraudio";
+ else if (sndio_supported)
+ protocol = "sndioaudio";
else
protocol = "sunaudio";
}
@@ -314,6 +322,8 @@ int record_wave(EST_Wave &wave, EST_Option &al)
else if ((upcase(protocol) == "FREEBSD16AUDIO") ||
(upcase(protocol) == "LINUX16AUDIO"))
return record_linux_wave(wave,al);
+ else if (upcase(protocol) == "SNDIOAUDIO")
+ return record_sndio_wave(wave,al);
else if (upcase(protocol) == "SUNAUDIO")
return record_sunau_wave(wave,al);
else
diff --git speech_tools/audio/sndio.cc speech_tools/audio/sndio.cc
new file mode 100644
index 0000000..866f43c
--- /dev/null
+++ speech_tools/audio/sndio.cc
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2010 Jacob Meuser <jakemsr@sdf.lonestar.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Based on voxware.cc which came with the following copyright notice. */
+
+/*************************************************************************/
+/* */
+/* Centre for Speech Technology Research */
+/* University of Edinburgh, UK */
+/* Copyright (c) 1997,1998 */
+/* All Rights Reserved. */
+/* */
+/* Permission is hereby granted, free of charge, to use and distribute */
+/* this software and its documentation without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of this work, and to */
+/* permit persons to whom this work is furnished to do so, subject to */
+/* the following conditions: */
+/* 1. The code must retain the above copyright notice, this list of */
+/* conditions and the following disclaimer. */
+/* 2. Any modifications must be clearly marked as such. */
+/* 3. Original authors' names are not deleted. */
+/* 4. The authors' names are not used to endorse or promote products */
+/* derived from this software without specific prior written */
+/* permission. */
+/* */
+/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
+/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
+/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
+/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
+/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
+/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
+/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
+/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
+/* THIS SOFTWARE. */
+/* */
+/*************************************************************************/
+/* Author : Alan W Black */
+/* Date : July 1997 */
+/*-----------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include "EST_cutils.h"
+#include "EST_walloc.h"
+#include "EST_Wave.h"
+#include "EST_wave_aux.h"
+#include "EST_Option.h"
+#include "audioP.h"
+#include "EST_io_aux.h"
+#include "EST_error.h"
+
+#ifdef SUPPORT_SNDIO
+#include <sndio.h>
+int sndio_supported = TRUE;
+static char *aud_sys_name = "sndio";
+static int stereo_only = 0;
+
+
+// Code to block signals while sound is playing.
+// Needed inside Java on (at least some) linux systems
+// as scheduling interrupts seem to break the writes.
+
+#ifdef THREAD_SAFETY
+#include <signal.h>
+#include <pthread.h>
+
+#define THREAD_DECS() \
+ sigset_t oldmask \
+
+#define THREAD_PROTECT() do { \
+ sigset_t newmask; \
+ \
+ sigfillset(&newmask); \
+ \
+ pthread_sigmask(SIG_BLOCK, &newmask, &oldmask); \
+ } while(0)
+
+#define THREAD_UNPROTECT() do { \
+ pthread_sigmask(SIG_SETMASK, &oldmask, NULL); \
+ } while (0)
+
+#else
+#define THREAD_DECS() //empty
+#define THREAD_PROTECT() //empty
+#define THREAD_UNPROTECT() //empty
+#endif
+
+
+#define AUDIOBUFFSIZE 256
+// #define AUDIOBUFFSIZE 20480
+
+int
+play_sndio_wave(EST_Wave &inwave, EST_Option &al)
+{
+ struct sio_hdl *hdl;
+ struct sio_par par;
+ int sample_rate;
+ short *waveform;
+ short *waveform2 = NULL;
+ int num_samples;
+ int i, r, n;
+ char *audiodevice = NULL;
+
+ if (al.present("-audiodevice"))
+ audiodevice = al.val("-audiodevice");
+
+ if ((hdl = sio_open(audiodevice, SIO_PLAY, 0)) == NULL) {
+ cerr << aud_sys_name << ": error opening device" << endl;
+ return -1;
+ }
+
+ waveform = inwave.values().memory();
+ num_samples = inwave.num_samples();
+ sample_rate = inwave.sample_rate();
+
+ sio_initpar(&par);
+
+ par.rate = sample_rate;
+ par.pchan = 1;
+ par.bits = 16;
+ par.sig = 1;
+ par.le = SIO_LE_NATIVE;
+
+ if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
+ cerr << aud_sys_name << ": error configuring parameters" << endl;
+ return -1;
+ }
+
+ if ((par.pchan != 1 && par.pchan != 2) ||
+ !((par.bits == 16 && par.sig == 1) ||
+ (par.bits == 8 && par.sig == 0)) ||
+ par.rate != sample_rate) {
+ cerr << aud_sys_name << ": could not set appropriate parameters" << endl;
+ return -1;
+ }
+
+ if (!sio_start(hdl)) {
+ cerr << aud_sys_name << ": could not start sudio" << endl;
+ return -1;
+ }
+
+ if (par.pchan == 2)
+ stereo_only = 1;
+
+ if (stereo_only) {
+ waveform2 = walloc(short, num_samples * 2);
+ for (i = 0; i < num_samples; i++) {
+ waveform2[i * 2] = inwave.a(i);
+ waveform2[(i * 2) + 1] = inwave.a(i);
+ }
+ waveform = waveform2;
+ num_samples *= 2;
+ }
+
+ THREAD_DECS();
+ THREAD_PROTECT();
+
+ if (par.bits == 8) {
+ // Its actually 8bit unsigned so convert the buffer;
+ unsigned char *uchars = walloc(unsigned char,num_samples);
+ for (i=0; i < num_samples; i++)
+ uchars[i] = waveform[i] / 256 + 128;
+ for (i=0; i < num_samples; i += r) {
+ if (num_samples > i + AUDIOBUFFSIZE)
+ n = AUDIOBUFFSIZE;
+ else
+ n = num_samples - i;
+ r = sio_write(hdl, &uchars[i], n);
+ if (r == 0 && sio_eof(hdl)) {
+ THREAD_UNPROTECT();
+ cerr << aud_sys_name << ": failed to write to buffer" <<
+ sample_rate << endl;
+ sio_close(hdl);
+ return -1;
+ }
+ }
+ wfree(uchars);
+ } else {
+ // 16-bit
+ int nbuf, c;
+ short *buf;
+
+ nbuf = par.round * par.bps * par.pchan;
+
+ buf = new short[nbuf];
+
+ for (i = 0; i < num_samples; i += r / 2) {
+ if (num_samples > i+nbuf)
+ n = nbuf;
+ else
+ n = num_samples-i;
+
+ for (c = 0; c < n; c++)
+ buf[c] = waveform[c + i];
+
+ for(; c < nbuf; c++)
+ buf[c] = waveform[n - 1];
+
+ r = sio_write(hdl, buf, nbuf * 2);
+ if (r == 0 && sio_eof(hdl)) {
+ THREAD_UNPROTECT();
+ EST_warning("%s: failed to write to buffer (sr=%d)",
+ aud_sys_name, sample_rate );
+ sio_close(hdl);
+ return -1;
+ }
+
+ }
+ delete [] buf;
+ }
+
+ sio_close(hdl);
+ if (waveform2)
+ wfree(waveform2);
+
+ THREAD_UNPROTECT();
+ return 1;
+}
+
+int
+record_sndio_wave(EST_Wave &inwave, EST_Option &al)
+{
+ struct sio_hdl *hdl;
+ struct sio_par par;
+ int sample_rate = 16000; // egcs needs the initialized for some reason
+ short *waveform;
+ short *waveform2 = NULL;
+ int num_samples;
+ int i,r,n;
+ char *audiodevice = NULL;
+
+ if (al.present("-audiodevice"))
+ audiodevice = al.val("-audiodevice");
+
+ sample_rate = al.ival("-sample_rate");
+
+ if ((hdl = sio_open(audiodevice, SIO_REC, 0)) == NULL) {
+ cerr << aud_sys_name << ": error opening device" << endl;
+ return -1;
+ }
+
+ sio_initpar(&par);
+
+ par.rate = sample_rate;
+ par.rchan = 1;
+ par.bits = 16;
+ par.sig = 1;
+ par.le = SIO_LE_NATIVE;
+
+ if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
+ cerr << aud_sys_name << ": error configuring parameters" << endl;
+ return -1;
+ }
+
+ if ((par.rchan != 1 && par.rchan != 2) ||
+ !((par.bits == 16 && par.sig == 1) ||
+ (par.bits == 8 && par.sig == 0)) ||
+ par.rate != sample_rate) {
+ cerr << aud_sys_name << ": could not set appropriate parameters" << endl;
+ return -1;
+ }
+
+ if (!sio_start(hdl)) {
+ cerr << aud_sys_name << ": could not start sudio" << endl;
+ return -1;
+ }
+
+ if (par.rchan == 2)
+ stereo_only = 1;
+
+ inwave.resize((int)(sample_rate * al.fval("-time")));
+ inwave.set_sample_rate(sample_rate);
+ num_samples = inwave.num_samples();
+ waveform = inwave.values().memory();
+
+ if (par.bits == 16) {
+ // We assume that the device returns audio in native byte order
+ // by default
+
+ if (stereo_only) {
+ waveform2 = walloc(short, num_samples * 2);
+ num_samples *= 2;
+ } else
+ waveform2 = waveform;
+
+ for (i = 0; i < num_samples; i+= r) {
+ if (num_samples > i+AUDIOBUFFSIZE)
+ n = AUDIOBUFFSIZE;
+ else
+ n = num_samples-i;
+ r = sio_read(hdl, &waveform2[i], n * 2);
+ r /= 2;
+ if (r == 0 && sio_eof(hdl)) {
+ cerr << aud_sys_name << ": failed to read from audio device"
+ << endl;
+ sio_close(hdl);
+ return -1;
+ }
+ }
+ } else {
+ unsigned char *u8wave = walloc(unsigned char, num_samples);
+
+ for (i = 0; i < num_samples; i += r) {
+ if (num_samples > i+AUDIOBUFFSIZE)
+ n = AUDIOBUFFSIZE;
+ else
+ n = num_samples - i;
+ r = sio_read(hdl, &u8wave[i], n);
+ if (r == 0 && sio_eof(hdl)) {
+ cerr << aud_sys_name << ": failed to read from audio device"
+ << endl;
+ sio_close(hdl);
+ wfree(u8wave);
+ return -1;
+ }
+
+ }
+ uchar_to_short(u8wave, waveform, num_samples);
+ wfree(u8wave);
+ }
+
+ if (stereo_only) {
+ for (i = 0; i < num_samples; i += 2)
+ waveform[i / 2] = waveform2[i];
+ wfree(waveform2);
+ }
+
+ sio_close(hdl);
+ return 0;
+}
+
+#else
+
+int sndio_supported = FALSE;
+
+int
+play_sndio_wave(EST_Wave &inwave, EST_Option &al)
+{
+ (void)inwave;
+ (void)al;
+ cerr << "Audio: sndio not compiled in this version" << endl;
+ return -1;
+}
+
+int
+record_sndio_wave(EST_Wave &inwave, EST_Option &al)
+{
+ (void)inwave;
+ (void)al;
+ cerr << "Audio: sndio not compiled in this version" << endl;
+ return -1;
+}
+
+#endif
diff --git speech_tools.orig/config/modules/Makefile speech_tools/config/modules/Makefile
index c937c64..6bfb6d3 100644
--- speech_tools.orig/config/modules/Makefile
+++ speech_tools/config/modules/Makefile
@@ -42,7 +42,7 @@ RULESETS = efence.mak dmalloc.mak debugging.mak \
freebsd16_audio.mak irix_audio.mak linux16_audio.mak \
sun16_audio.mak win32_audio.mak macosx_audio.mak \
mplayer_audio.mak nas_audio.mak esd_audio.mak \
- siod_python.mak
+ siod_python.mak sndio_audio.mak
FILES = Makefile descriptions $(RULESETS)
diff --git speech_tools/config/modules/sndio_audio.mak speech_tools/config/modules/sndio_audio.mak
new file mode 100644
index 0000000..1f5d7d2
--- /dev/null
+++ speech_tools/config/modules/sndio_audio.mak
@@ -0,0 +1,8 @@
+
+INCLUDE_SNDIO_AUDIO=1
+
+MOD_DESC_SNDIO_AUDIO=(from EST) Audio module for sndio audio support
+
+AUDIO_DEFINES += -DSUPPORT_SNDIO
+
+MODULE_LIBS += -lsndio
diff --git speech_tools.orig/config/systems/Linux.mak speech_tools/config/systems/Linux.mak
index 1fbba94..62a3d7b 100644
--- speech_tools.orig/config/systems/Linux.mak
+++ speech_tools/config/systems/Linux.mak
@@ -44,7 +44,7 @@ TCL_LIBRARY = -ltcl
OS_LIBS = -ldl -lncurses
## the native audio module for this type of system
-NATIVE_AUDIO_MODULE = LINUX16
+NATIVE_AUDIO_MODULE = SNDIO
## echo -n doesn't work
ECHO_N = /usr/bin/printf "%s"
diff --git speech_tools.orig/include/EST_audio.h speech_tools/include/EST_audio.h
index 2b1df88..29891b8 100644
--- speech_tools.orig/include/EST_audio.h
+++ speech_tools/include/EST_audio.h
@@ -46,6 +46,7 @@ extern int nas_supported;
extern int esd_supported;
extern int sun16_supported;
extern int freebsd16_supported;
+extern int sndio_supported;
extern int linux16_supported;
extern int mplayer_supported;
extern int win32audio_supported;
diff --git speech_tools.orig/lib/siod/init.scm speech_tools/lib/siod/init.scm
index a149f96..37acb24 100644
--- speech_tools.orig/lib/siod/init.scm
+++ speech_tools/lib/siod/init.scm
@@ -78,8 +78,10 @@
(Parameter.def 'Audio_Method 'os2audio))
((member 'mplayeraudio *modules*)
(Parameter.def 'Audio_Method 'mplayeraudio))
- (t ;; can't find direct support so guess that /dev/audio for 8k ulaw exists
- (Parameter.def 'Audio_Method 'sunaudio)))
+ ((member 'sndioaudio *modules*)
+ (Parameter.def 'Audio_Method 'sndioaudio))
+ (t ;; stupid crappy software. default to only supported "protocol"
+ (Parameter.def 'Audio_Method 'sndioaudio)))
;;; If you have an external program to play audio add its definition
;;; in siteinit.scm