From fe9b23849552856353cc861e675cd29a6429cfbc Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Thu, 05 Mar 2009 03:56:39 +0000 Subject: Setup CAPS and do not use WAV format --- diff --git a/src/espeak.c b/src/espeak.c index dc8880b..265a243 100644 --- a/src/espeak.c +++ b/src/espeak.c @@ -27,24 +27,19 @@ struct Espeak GOutputStream *buffer; }; -static unsigned char wave_hdr[44] = { - 'R','I','F','F',0x24,0xf0,0xff,0x7f,'W','A','V','E','f','m','t',' ', - 0x10,0,0,0,1,0,1,0, 9,0x3d,0,0,0x12,0x7a,0,0, - 2,0,0x10,0,'d','a','t','a', 0x00,0xf0,0xff,0x7f}; - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static GOutputStream *buffer = NULL; static gint sample_rate = 0; static const espeak_VOICE **voices = NULL; static gint -read_cb(short * wav, int numsamples, espeak_EVENT * events) +read_cb(short * data, int numsamples, espeak_EVENT * events) { - if (wav == NULL) + if (data == NULL) return 0; if (numsamples > 0) - g_output_stream_write(buffer, wav, numsamples*2, NULL, NULL); + g_output_stream_write(buffer, data, numsamples*2, NULL, NULL); return 0; } @@ -79,6 +74,12 @@ espeak_new() return es; } +gint +espeak_sample_rate() +{ + return sample_rate; +} + gchar** espeak_voices() { @@ -101,9 +102,6 @@ espeak_say(struct Espeak *es, const gchar *text, const gchar *voice, guint pitch, guint rate) { g_seekable_seek(G_SEEKABLE(es->buffer), 0, G_SEEK_SET, NULL, NULL); - g_output_stream_write(es->buffer, wave_hdr, 24, NULL, NULL); - g_seekable_seek(G_SEEKABLE(es->buffer), 8, G_SEEK_CUR, NULL, NULL); - g_output_stream_write(es->buffer, wave_hdr+32, 12, NULL, NULL); pthread_mutex_lock(&mutex); buffer = es->buffer; @@ -118,26 +116,6 @@ espeak_say(struct Espeak *es, const gchar *text, const gchar *voice, if (status != EE_OK) return FALSE; - void write4bytes(unsigned char *ptr, int value) - { - int ix; - - for(ix=0; ix<4; ix++) - { - *ptr++ = value & 0xff; - value = value >> 8; - } - } - - GMemoryOutputStream *mb = G_MEMORY_OUTPUT_STREAM(es->buffer); - unsigned char *ptr = g_memory_output_stream_get_data(mb); - guint size = g_memory_output_stream_get_data_size(mb); - - write4bytes(ptr+24, sample_rate); - write4bytes(ptr+28, sample_rate*2); - write4bytes(ptr+4, size-8); - write4bytes(ptr+40, size-44); - return TRUE; } diff --git a/src/espeak.h b/src/espeak.h index 8f7ef61..6258ebd 100644 --- a/src/espeak.h +++ b/src/espeak.h @@ -21,6 +21,7 @@ struct Espeak; struct Espeak* espeak_new(); +gint espeak_sample_rate(); gchar** espeak_voices(); gboolean espeak_say(struct Espeak*, const gchar *text, const gchar *voice, guint pitch, guint rate); diff --git a/src/gstespeak.c b/src/gstespeak.c index 52cfacc..8fd36eb 100644 --- a/src/gstespeak.c +++ b/src/gstespeak.c @@ -23,7 +23,7 @@ * * Example launch line * |[ - * gst-launch-0.10 espeak text="Hello world" pitch=99 rate=300 voice=default ! wavparse ! alsasink + * gst-launch-0.10 espeak text="Hello world" pitch=99 rate=300 voice=default ! alsasink * ]| * */ @@ -48,27 +48,28 @@ enum PROP_PITCH, PROP_RATE, PROP_VOICE, - PROP_VOICES + PROP_VOICES, + PROP_CAPS }; static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ( "src", GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS ("ANY") + GST_STATIC_CAPS_ANY ); -static GstFlowReturn gst_espeak_create (GstBaseSrc*, +static GstFlowReturn gst_espeak_create(GstBaseSrc*, guint64, guint, GstBuffer**); -static gboolean gst_espeak_start (GstBaseSrc*); -static gboolean gst_espeak_stop (GstBaseSrc*); +static gboolean gst_espeak_start(GstBaseSrc*); +static gboolean gst_espeak_stop(GstBaseSrc*); static gboolean gst_espeak_is_seekable (GstBaseSrc*); static void gst_espeak_init_uri(GType); -static void gst_espeak_finalize(GObject * gobject); -static void gst_espeak_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_espeak_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); +static void gst_espeak_finalize(GObject*); +static void gst_espeak_set_property(GObject*, guint, const GValue*, + GParamSpec*); +static void gst_espeak_get_property(GObject*, guint, GValue*, GParamSpec*); +static GstCaps *gst_espeak_getcaps(GstBaseSrc*); GST_BOILERPLATE_FULL(GstEspeak, gst_espeak, GstBaseSrc, GST_TYPE_BASE_SRC, gst_espeak_init_uri); @@ -102,6 +103,7 @@ gst_espeak_class_init (GstEspeakClass * klass) basesrc_class->stop = gst_espeak_stop; basesrc_class->stop = gst_espeak_stop; basesrc_class->is_seekable = gst_espeak_is_seekable; + basesrc_class->get_caps = gst_espeak_getcaps; gobject_class->finalize = gst_espeak_finalize; gobject_class->set_property = gst_espeak_set_property; @@ -127,6 +129,10 @@ gst_espeak_class_init (GstEspeakClass * klass) g_param_spec_boxed("voices", "List of voices", "List of voices", G_TYPE_STRV, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CAPS, + g_param_spec_boxed ("caps", "Caps", + "Caps describing the format of the data.", GST_TYPE_CAPS, + G_PARAM_READABLE)); } /* initialize the new element @@ -145,13 +151,23 @@ gst_espeak_init (GstEspeak * self, self->speak = espeak_new(); self->voice = g_strdup("default"); self->voices = espeak_voices(); + + self->caps = gst_caps_new_simple("audio/x-raw-int", + "rate", G_TYPE_INT, espeak_sample_rate(), + "channels", G_TYPE_INT, 1, + "endianness", G_TYPE_INT, G_BYTE_ORDER, + "width", G_TYPE_INT, 16, + "depth", G_TYPE_INT, 16, + "signed", G_TYPE_BOOLEAN, TRUE, + NULL); } static void gst_espeak_finalize(GObject * self_) { - GstEspeak *self = (GstEspeak*)self_; + GstEspeak *self = GST_ESPEAK(self_); + gst_caps_unref(self->caps); self->caps = NULL; espeak_unref(self->speak); self->speak = NULL; g_free(self->text); self->text = NULL; g_free(self->uri); self->uri = NULL; @@ -243,6 +259,9 @@ gst_espeak_get_property (GObject * object, guint prop_id, case PROP_VOICES: g_value_set_boxed(value, self->voices); break; + case PROP_CAPS: + gst_value_set_caps(value, self->caps); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -293,6 +312,13 @@ gst_espeak_is_seekable (GstBaseSrc * src) return FALSE; } +static GstCaps * +gst_espeak_getcaps(GstBaseSrc *self_) +{ + GstEspeak *self = GST_ESPEAK(self_); + return gst_caps_ref(self->caps); +} + /******************************************************************************/ static GstURIType diff --git a/src/gstespeak.h b/src/gstespeak.h index 7af8b77..a0776aa 100644 --- a/src/gstespeak.h +++ b/src/gstespeak.h @@ -49,6 +49,7 @@ struct _GstEspeak guint rate; gchar *voice; gchar **voices; + GstCaps *caps; }; struct _GstEspeakClass -- cgit v0.9.1