Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@member.fsf.org>2009-03-05 03:56:39 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-03-05 03:56:39 (GMT)
commitfe9b23849552856353cc861e675cd29a6429cfbc (patch)
tree442e9d23d36e9e5ea58be33f4218a9e3e85160c6
parent314963cb771bd61b01c9aa57a4c3601302fdf62b (diff)
Setup CAPS and do not use WAV format
-rw-r--r--src/espeak.c40
-rw-r--r--src/espeak.h1
-rw-r--r--src/gstespeak.c50
-rw-r--r--src/gstespeak.h1
4 files changed, 49 insertions, 43 deletions
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 @@
* <refsect2>
* <title>Example launch line</title>
* |[
- * 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
* ]|
* </refsect2>
*/
@@ -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