aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile154
-rw-r--r--espeak~-help.pd94
-rw-r--r--espeak~.c204
3 files changed, 452 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..b3528b2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,154 @@
+# Makefile
+# (c) 2006 IOhannes m zmölnig
+
+# path to pd
+## change this according to your setup!
+PDROOT=../../../../pd
+#PDROOT=/home/zmoelnig/src/pd/
+
+# here we find the sources of pd (and evtl. the pd.lib)
+PDSRCDIR=$(PDROOT)/src
+PDLIBDIR=$(PDROOT)/bin
+
+# this is the filename-extension
+# people have to specify it at the cmdline: eg "make pd_linux"
+EXTENSION=$(MAKECMDGOALS)
+
+# if no filename-extension is supplied by the user
+# try to guess one, based on what "uname" tells us
+UNAME := $(shell uname -s)
+ifeq ($(UNAME),Linux)
+ DEFAULTEXTENSION= pd_linux
+else
+ ifeq ($(UNAME),Darwin)
+ DEFAULTEXTENSION= pd_darwin
+ else
+ ifeq (MINGW,$(findstring MINGW,$(UNAME)))
+ DEFAULTEXTENSION= pd_nt
+ else
+ ifeq ($(UNAME),IRIX)
+ UNAMEV := $(shell uname -R)
+ ifeq (6.,$(findstring 6.,$(UNAMEV)))
+ DEFAULTEXTENSION= pd_irix6
+ else
+ DEFAULTEXTENSION= pd_irix5
+ endif
+ else
+ DEFAULTEXTENSION=help
+ endif
+ endif
+ endif
+endif
+
+# if no extension is given, call "make" again with a guessed extension
+auto:
+ make $(DEFAULTEXTENSION)
+
+# just a stupid fallback
+help:
+ @echo "choose one command: make pd_linux (linux), make pd_darwin (osX), make pd_irix5 (IRIX5), make pd_irix6 (IRIX6), make dll (MSVC), make pd_nt (MinWG)"
+
+# delete old build files
+clean:
+ -rm -f *.dll *.pd_* *.o *.obj *~
+
+# we want to compile all C-files we find in the current directory
+SOURCES=$(sort $(filter %.c, $(wildcard *.c)))
+# each C-files maps will become an external with the given filename-extension
+TARGETS=$(SOURCES:.c=.$(EXTENSION))
+
+
+# ----------------------- Linux -----------------------
+
+pd_linux: $(TARGETS)
+
+LINUXCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer -fPIC \
+ -Wall -W -Wshadow -Wstrict-prototypes -Werror \
+ -Wno-unused -Wno-parentheses -Wno-switch
+
+LINUXLDFLAGS = -export-dynamic -shared -lc -lm -lespeak
+
+LINUXINCLUDE = -I$(PDSRCDIR)
+
+%.pd_linux: %.c
+ $(CC) $(LINUXLDFLAGS) $(LINUXCFLAGS) $(LINUXINCLUDE) -o $*.pd_linux $*.c
+ strip --strip-unneeded $*.pd_linux
+
+
+
+# ----------------------- Mac OSX -----------------------
+
+pd_darwin: $(TARGETS)
+
+DARWINCFLAGS = -DPD -O2 -Wall -W -Wshadow -Wstrict-prototypes \
+ -Wno-unused -Wno-parentheses -Wno-switch
+
+DARWININCLUDE = -I$(PDSRCDIR)
+
+DARWINLDFLAGS = -bundle -undefined suppress -flat_namespace
+
+%.pd_darwin: %.c
+ $(CC) $(DARWINCFLAGS) $(DARWININCLUDE) $(DARWINLDFLAGS) -o $*.pd_darwin $*.c
+
+
+# ----------------------- IRIX 5.x -----------------------
+pd_irix5: $(TARGETS)
+
+SGICFLAGS5 = -o32 -DPD -DSGI -O2
+
+SGIINCLUDE = -I$(PDSRCDIR)
+
+SGILDFLAGS = -elf -shared -rdata_shared
+
+%.pd_irix5: %.c
+ $(CC) $(SGICFLAGS5) $(SGIINCLUDE) -o $*.o -c $*.c
+ $(LD) $(SGILDFLAGS) -o $*.pd_irix5 $*.o
+ rm $*.o
+
+
+# ----------------------- IRIX 6.x -----------------------
+pd_irix6: $(TARGETS)
+
+SGICFLAGS6 = -DPD -DSGI -n32 \
+ -OPT:roundoff=3 -OPT:IEEE_arithmetic=3 -OPT:cray_ivdep=true \
+ -Ofast=ip32
+
+%.pd_irix6: %.c
+ $(CC) $(SGICFLAGS6) $(SGIINCLUDE) -o $*.o -c $*.c
+ $(LD) $(SGILDFLAGS) -o $*.pd_irix6 $*.o
+ rm $*.o
+
+
+# ----------------------- NT -----------------------
+dll: $(TARGETS)
+
+PDNTCFLAGS = /W3 /WX /DPD /DNT /D__WIN32__ /DMSW /nologo
+
+VC="C:\Programme\Microsoft Visual Studio\Vc98"
+
+PDNTINCLUDE = /I. /I$(PDROOT)\tcl\include /I$(PDSRCDIR)\src /I$(VC)\include
+
+PDNTLDIR = $(VC)\lib
+
+PDNTLIB = $(PDNTLDIR)\libc.lib \
+ $(PDNTLDIR)\oldnames.lib \
+ $(PDNTLDIR)\kernel32.lib \
+ $(PDLIBDIR)\pd.lib
+
+%.dll: %.c
+ cl $(PDNTCFLAGS) $(PDNTINCLUDE) /c $*.c
+ link /dll /export:$*_setup $*.obj $(PDNTLIB)
+
+
+pd_nt: $(TARGETS)
+
+MINGWCFLAGS = -DPD -O2 -funroll-loops -fomit-frame-pointer \
+ -Wall -W -Wshadow -Wstrict-prototypes -Werror \
+ -Wno-unused -Wno-parentheses -Wno-switch -mms-bitfields
+
+MINGWLDFLAGS = -export_dynamic -shared -lm -lkernel32 -lcoldname -lcrtdll -lpd -L$(PDLIBDIR)
+
+MINGWINCLUDE = -I$(PDSRCDIR)
+
+%.pd_nt: %.c
+ $(CC) $(MINGWLDFLAGS) $(MINGWCFLAGS) $(MINGWINCLUDE) -o $*.dll $*.c
diff --git a/espeak~-help.pd b/espeak~-help.pd
new file mode 100644
index 0000000..d396340
--- /dev/null
+++ b/espeak~-help.pd
@@ -0,0 +1,94 @@
+#N canvas 811 359 866 452 10;
+#X obj 112 142 espeak~;
+#X obj 65 188 env~;
+#X floatatom 65 209 5 0 0 0 - - -;
+#X obj 112 184 dac~;
+#X obj 36 47 metro 5000;
+#X obj 35 19 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1
+;
+#X msg 328 32 \; pd dsp 1;
+#X obj 111 80 list prepend;
+#X obj 111 101 list prepend speak;
+#X obj 111 122 list trim;
+#X obj 113 55 t b a;
+#X msg 202 125 bang;
+#X obj 177 165 print info;
+#X msg 319 102 voice serbian;
+#X msg 241 67 dosvi denje;
+#X msg 305 158 voice \$1;
+#X symbolatom 305 128 0 0 0 0 - - -;
+#X msg 353 218 bang;
+#X msg 211 31 dobro;
+#X msg 114 23 na wie geths;
+#X symbolatom 236 9 0 0 0 0 - - -;
+#X floatatom 71 17 5 0 0 0 - - -;
+#X obj 515 148 espeak~;
+#X obj 468 194 env~;
+#X floatatom 468 215 5 0 0 0 - - -;
+#X obj 515 190 dac~;
+#X obj 439 53 metro 5000;
+#X obj 438 25 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0
+1;
+#X obj 514 86 list prepend;
+#X obj 514 107 list prepend speak;
+#X obj 514 128 list trim;
+#X obj 516 61 t b a;
+#X msg 605 131 bang;
+#X obj 580 171 print info;
+#X msg 722 108 voice serbian;
+#X msg 644 73 dosvi denje;
+#X msg 708 164 voice \$1;
+#X symbolatom 708 134 0 0 0 0 - - -;
+#X msg 756 224 bang;
+#X msg 614 37 dobro;
+#X msg 517 29 na wie geths;
+#X symbolatom 639 15 0 0 0 0 - - -;
+#X floatatom 474 23 5 0 0 0 - - -;
+#X msg 127 364 das ist ein ganz schon langer text ich weiss auch nicht
+mehr was ich jetzt noch schreiben soll;
+#X msg 145 308 das ist ein ganz schon langer text ich weiss auch nicht
+;
+#X connect 0 0 1 0;
+#X connect 0 0 3 0;
+#X connect 0 1 12 0;
+#X connect 1 0 2 0;
+#X connect 4 0 7 0;
+#X connect 5 0 4 0;
+#X connect 7 0 8 0;
+#X connect 8 0 9 0;
+#X connect 9 0 0 0;
+#X connect 10 0 7 0;
+#X connect 10 1 7 1;
+#X connect 11 0 0 0;
+#X connect 13 0 0 0;
+#X connect 14 0 10 0;
+#X connect 15 0 0 0;
+#X connect 16 0 15 0;
+#X connect 17 0 16 0;
+#X connect 18 0 10 0;
+#X connect 19 0 10 0;
+#X connect 20 0 10 0;
+#X connect 21 0 4 1;
+#X connect 22 0 23 0;
+#X connect 22 0 25 0;
+#X connect 22 1 33 0;
+#X connect 23 0 24 0;
+#X connect 26 0 28 0;
+#X connect 27 0 26 0;
+#X connect 28 0 29 0;
+#X connect 29 0 30 0;
+#X connect 30 0 22 0;
+#X connect 31 0 28 0;
+#X connect 31 1 28 1;
+#X connect 32 0 22 0;
+#X connect 34 0 22 0;
+#X connect 35 0 31 0;
+#X connect 36 0 22 0;
+#X connect 37 0 36 0;
+#X connect 38 0 37 0;
+#X connect 39 0 31 0;
+#X connect 40 0 31 0;
+#X connect 41 0 31 0;
+#X connect 42 0 26 1;
+#X connect 43 0 10 0;
+#X connect 44 0 10 0;
diff --git a/espeak~.c b/espeak~.c
new file mode 100644
index 0000000..16a7fbf
--- /dev/null
+++ b/espeak~.c
@@ -0,0 +1,204 @@
+/******************************************************
+ *
+ * espeak - implementation file
+ *
+ * (c) copyright 2011 IOhannes m zmölnig
+ * (c) copyright 2011 Matthias Kronlachner
+ * (c) copyright 2011 Marian Weger
+ *
+ * within the course: Künstlerisches Gestalten mit Klang 2010/2011
+ *
+ * institute of electronic music and acoustics (iem)
+ *
+ ******************************************************
+ *
+ * license: GNU General Public License v.2
+ *
+ ******************************************************/
+
+#include "m_pd.h"
+#include <espeak/speak_lib.h>
+#include <string.h>
+
+/* general */
+
+static int espeak_rate=0;
+#define ESPEAK_BUFFER 50000
+
+
+typedef struct _espeak
+{
+ t_object x_obj;
+
+ short*x_buffer; /* buffer of synth'ed samples */
+ unsigned int x_buflen; /* length of the buffer */
+
+ unsigned int x_position; /* playback position for perform-routine */
+
+ int x_ready; /* flag: if true, start playback */
+
+
+ t_outlet*x_infoout;
+} t_espeak;
+
+/* ------------------------ espeak~ ----------------------------- */
+
+static t_class *espeak_class;
+
+static t_int *espeak_perform(t_int *w){
+ t_espeak *x = (t_espeak *)(w[1]);
+ t_sample *out = (t_sample *)(w[2]);
+ int n = (int)(w[3]);
+
+ if(x->x_ready) {
+ // got data to play back
+ n=n/2;
+
+ short*in=x->x_buffer+x->x_position;
+
+ x->x_position+=n;
+ if(x->x_position>=x->x_buflen)
+ x->x_ready=0;
+
+
+ while(n--) {
+ t_sample f=(*in++)/32768.;
+ *out++ = f;
+ *out++ = f;
+ }
+
+ } else {
+ while(n--) {
+ *out++=0.f;
+ }
+ }
+
+ return (w+4);
+}
+
+static void espeak_dsp(t_espeak *x, t_signal **sp){
+
+ t_signal*sig=sp[0];
+
+
+ dsp_add(espeak_perform, 3,
+ x,
+ sp[0]->s_vec,
+ sp[0]->s_n);
+}
+
+static int espeak_callback(short *wav, int numsamples, espeak_EVENT *events) {
+ int i=0;
+
+ verbose(1, "get %d samples", numsamples);
+
+ if(numsamples) {
+ t_espeak*x = (t_espeak*)events[0].user_data;
+ if(NULL==x)
+ return 1;
+
+ memset(x->x_buffer, 0, x->x_buflen*sizeof(short));
+ memcpy(x->x_buffer, wav, numsamples*sizeof(short));
+ x->x_ready = 1;
+ x->x_position = 0;
+ }
+
+ return 0;
+}
+
+static void espeak_text(t_espeak *x, t_symbol*s, int argc, t_atom*argv) {
+ t_binbuf*bb=binbuf_new();
+ int size=0;
+ char*text=NULL;
+
+ binbuf_add(bb, argc, argv);
+ binbuf_gettext(bb, &text, &size);
+ binbuf_free(bb);
+
+ text[size]=0;
+
+ verbose(1, "speak '%s'", text);
+
+ espeak_Synth(text,
+ strlen(text),
+ 0,
+ POS_CHARACTER,
+ 0,
+ espeakCHARS_AUTO,
+ NULL,
+ x);
+}
+
+
+static void espeak_info(t_espeak*x){
+ const espeak_VOICE**voices=espeak_ListVoices(NULL);
+ int i=0;
+
+ while(voices[i]) {
+
+ t_atom ap[3];
+ SETSYMBOL(ap+0, gensym(voices[i]->name));
+ SETSYMBOL(ap+1, gensym(voices[i]->languages));
+ SETSYMBOL(ap+2, gensym(voices[i]->identifier));
+
+ outlet_anything(x->x_infoout, gensym("voice"), 3, ap);
+
+ i++;
+ }
+}
+
+
+static void espeak_voice(t_espeak*x, t_symbol*s){
+ espeak_ERROR err= espeak_SetVoiceByName(s->s_name);
+}
+
+static void espeak_free(t_espeak*x){
+ freebytes(x->x_buffer, x->x_buflen*sizeof(short));
+ if(x->x_infoout)
+ outlet_free(x->x_infoout);
+
+}
+
+static void *espeak_new(void){
+ t_espeak *x = (t_espeak *)pd_new(espeak_class);
+
+ x->x_buflen = espeak_rate*ESPEAK_BUFFER/1000;
+ x->x_buffer = (short*)getbytes(x->x_buflen*sizeof(short));
+
+ outlet_new(&x->x_obj, gensym("signal"));
+ x->x_infoout=outlet_new(&x->x_obj, NULL);
+
+ return (x);
+}
+
+void espeak_tilde_setup(void){
+
+ int result=espeak_Initialize(AUDIO_OUTPUT_RETRIEVAL,
+ ESPEAK_BUFFER,
+ NULL,
+ 0);
+
+
+ if(result<0) {
+ error("couldn't initialize eSpeak");
+ return;
+ }
+
+ espeak_SetSynthCallback(espeak_callback);
+ espeak_rate=result;
+
+ post("eSpeak running at %d Hz", result);
+
+ espeak_class = class_new(gensym("espeak~"), (t_newmethod)espeak_new, 0, sizeof(t_espeak), 0, 0);
+
+ class_addmethod(espeak_class, (t_method)espeak_dsp, gensym("dsp"), 0);
+
+ class_addmethod(espeak_class, (t_method)espeak_text, gensym("speak"), A_GIMME, 0);
+
+
+ class_addmethod(espeak_class, (t_method)espeak_voice, gensym("voice"), A_SYMBOL, 0);
+
+
+ class_addbang(espeak_class, (t_method)espeak_info);
+
+}