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-02-05 08:16:49 (GMT)
committer Aleksey Lim <alsroot@member.fsf.org>2009-02-05 08:16:49 (GMT)
commitc1cf739f24db8b87efcff613a253cc19cc5918d3 (patch)
tree20525aec832a2c34f92d82a1cc0f6e73630ba359
parente493948ac25d425719ad70d45bb02aefc3e32e06 (diff)
Add espeak:// uri type and "text" property
-rw-r--r--src/gstespeak.c290
-rw-r--r--src/gstespeak.h10
2 files changed, 209 insertions, 91 deletions
diff --git a/src/gstespeak.c b/src/gstespeak.c
index ea69f1d..cd357a1 100644
--- a/src/gstespeak.c
+++ b/src/gstespeak.c
@@ -61,6 +61,7 @@
#endif
#include <gst/gst.h>
+#include <string.h>
#include "gstespeak.h"
#include "espeak.h"
@@ -71,6 +72,7 @@ GST_DEBUG_CATEGORY_STATIC (gst_espeak_debug);
enum
{
PROP_0,
+ PROP_TEXT,
PROP_SILENT
};
@@ -81,26 +83,27 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE (
GST_STATIC_CAPS ("ANY")
);
-GST_BOILERPLATE (GstEspeak, gst_espeak, GstBaseSrc, GST_TYPE_BASE_SRC);
-
-static GstFlowReturn gst_espeak_src_create (GstBaseSrc*,
+static GstFlowReturn gst_espeak_create (GstBaseSrc*,
guint64, guint, GstBuffer**);
-static gboolean gst_espeak_src_start (GstBaseSrc*);
-static gboolean gst_espeak_src_stop (GstBaseSrc*);
-static gboolean gst_espeak_src_is_seekable (GstBaseSrc*);
-static gboolean gst_espeak_src_unlock (GstBaseSrc*);
-static gboolean gst_espeak_src_unlock_stop (GstBaseSrc*);
-static gboolean gst_espeak_src_do_seek (GstBaseSrc*, GstSegment*);
-static gboolean gst_espeak_src_check_get_range (GstBaseSrc*);
-static gboolean gst_espeak_src_do_get_size (GstBaseSrc*, guint64*);
-
-static void gst_espeak_src_dispose (GObject * gobject);
+static gboolean gst_espeak_start (GstBaseSrc*);
+static gboolean gst_espeak_stop (GstBaseSrc*);
+static gboolean gst_espeak_is_seekable (GstBaseSrc*);
+static gboolean gst_espeak_unlock (GstBaseSrc*);
+static gboolean gst_espeak_unlock_stop (GstBaseSrc*);
+static gboolean gst_espeak_do_seek (GstBaseSrc*, GstSegment*);
+static gboolean gst_espeak_check_get_range (GstBaseSrc*);
+static gboolean gst_espeak_do_get_size (GstBaseSrc*, guint64*);
+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);
-/* GObject vmethod implementations */
+GST_BOILERPLATE_FULL(GstEspeak, gst_espeak, GstBaseSrc, GST_TYPE_BASE_SRC,
+ gst_espeak_init_uri);
+
+/******************************************************************************/
static void
gst_espeak_base_init (gpointer gclass)
@@ -124,24 +127,29 @@ gst_espeak_class_init (GstEspeakClass * klass)
GObjectClass *gobject_class = (GObjectClass *) klass;
GstBaseSrcClass *basesrc_class = (GstBaseSrcClass *) klass;
- basesrc_class->create = gst_espeak_src_create;
- basesrc_class->start = gst_espeak_src_start;
- basesrc_class->stop = gst_espeak_src_stop;
- basesrc_class->stop = gst_espeak_src_stop;
- basesrc_class->is_seekable = gst_espeak_src_is_seekable;
- basesrc_class->unlock = gst_espeak_src_unlock;
- basesrc_class->unlock_stop = gst_espeak_src_unlock_stop;
- basesrc_class->do_seek = gst_espeak_src_do_seek;
- basesrc_class->check_get_range = gst_espeak_src_check_get_range;
- basesrc_class->get_size = gst_espeak_src_do_get_size;
-
- gobject_class->dispose = gst_espeak_src_dispose;
+ basesrc_class->create = gst_espeak_create;
+ basesrc_class->start = gst_espeak_start;
+ basesrc_class->stop = gst_espeak_stop;
+ basesrc_class->stop = gst_espeak_stop;
+ basesrc_class->is_seekable = gst_espeak_is_seekable;
+ basesrc_class->unlock = gst_espeak_unlock;
+ basesrc_class->unlock_stop = gst_espeak_unlock_stop;
+ basesrc_class->do_seek = gst_espeak_do_seek;
+ basesrc_class->check_get_range = gst_espeak_check_get_range;
+ basesrc_class->get_size = gst_espeak_do_get_size;
+
+ gobject_class->finalize = gst_espeak_finalize;
gobject_class->set_property = gst_espeak_set_property;
gobject_class->get_property = gst_espeak_get_property;
+ g_object_class_install_property(gobject_class, PROP_TEXT,
+ g_param_spec_string("text", "Text",
+ "Text to pronounce", NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_SILENT,
- g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
- FALSE, G_PARAM_READWRITE));
+ g_param_spec_boolean("silent", "Silent",
+ "Produce verbose output ?",
+ FALSE, G_PARAM_READWRITE));
}
/* initialize the new element
@@ -153,75 +161,100 @@ static void
gst_espeak_init (GstEspeak * self,
GstEspeakClass * gclass)
{
+ self->text = NULL;
+ self->uri = NULL;
self->speak = espeak_new();
}
static void
-gst_espeak_src_dispose(GObject * self_)
+gst_espeak_finalize(GObject * self_)
{
GstEspeak *self = (GstEspeak*)self_;
- espeak_unref(self->speak);
- self->speak = NULL;
+
+ espeak_unref(self->speak); self->speak = NULL;
+ g_free(self->text); self->text = NULL;
+ g_free(self->uri); self->uri = NULL;
G_OBJECT_CLASS(parent_class)->dispose(self_);
}
+/******************************************************************************/
+
+static gboolean
+gst_espeak_set_text(GstEspeak *self, const gchar *text)
+{
+ GstState state;
+
+ /* the element must be stopped in order to do this */
+ GST_OBJECT_LOCK(self);
+ state = GST_STATE(self);
+ GST_OBJECT_UNLOCK (self);
+
+ if (state != GST_STATE_READY && state != GST_STATE_NULL)
+ {
+ GST_DEBUG_OBJECT(self, "setting text in wrong state");
+ return FALSE;
+ }
+
+ g_free(self->text);
+ g_free(self->uri);
+
+ if (text == NULL) {
+ self->text = NULL;
+ self->uri = NULL;
+ } else {
+ self->text = g_strdup(text);
+ self->uri = gst_uri_construct ("espeak", self->text);
+ }
+
+ g_object_notify(G_OBJECT (self), "text");
+ gst_uri_handler_new_uri(GST_URI_HANDLER(self), self->uri);
+
+ return TRUE;
+}
+
static void
-gst_espeak_set_property (GObject * object, guint prop_id,
+gst_espeak_set_property (GObject *object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
- GstEspeak *filter = GST_ESPEAK (object);
-
- switch (prop_id) {
- case PROP_SILENT:
- filter->silent = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ GstEspeak *self = GST_ESPEAK(object);
+
+ switch (prop_id) {
+ case PROP_TEXT:
+ gst_espeak_set_text(self, g_value_get_string(value));
+ break;
+ case PROP_SILENT:
+ self->silent = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
static void
gst_espeak_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
- GstEspeak *filter = GST_ESPEAK (object);
-
- switch (prop_id) {
- case PROP_SILENT:
- g_value_set_boolean (value, filter->silent);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/* GstElement vmethod implementations */
-
-/* entry point to initialize the plug-in
- * initialize the plug-in itself
- * register the element factories and other features
- */
-static gboolean
-espeak_init (GstPlugin * espeak)
-{
- /* debug category for fltering log messages
- *
- * exchange the string 'Template espeak' with your description
- */
- GST_DEBUG_CATEGORY_INIT (gst_espeak_debug, "espeak",
- 0, "Template espeak");
-
- return gst_element_register (espeak, "espeak", GST_RANK_NONE,
- GST_TYPE_ESPEAK);
+ GstEspeak *self = GST_ESPEAK(object);
+
+ switch (prop_id) {
+ case PROP_TEXT:
+ g_value_set_string(value, self->text);
+ break;
+ case PROP_SILENT:
+ g_value_set_boolean (value, self->silent);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
/******************************************************************************/
static GstFlowReturn
-gst_espeak_src_create (GstBaseSrc * self_, guint64 offset, guint size,
+gst_espeak_create (GstBaseSrc * self_, guint64 offset, guint size,
GstBuffer ** buf)
{
GstEspeak *self = (GstEspeak*)self_;
@@ -232,51 +265,49 @@ gst_espeak_src_create (GstBaseSrc * self_, guint64 offset, guint size,
}
static gboolean
-gst_espeak_src_start (GstBaseSrc * self_)
+gst_espeak_start (GstBaseSrc * self_)
{
- GstEspeak *self = (GstEspeak*)self_;
- GstState status;
- gst_element_get_state((GstElement*)self, NULL, &status, 0);
+ GstEspeak *self = GST_ESPEAK(self_);
- if (status == GST_STATE_PAUSED)
- return espeak_say(self->speak, "Aa");
+ if (self->text == NULL || self->text[0] == 0)
+ return FALSE;
- return TRUE;
+ return espeak_say(self->speak, self->text);
}
static gboolean
-gst_espeak_src_stop (GstBaseSrc * self)
+gst_espeak_stop (GstBaseSrc * self)
{
return TRUE;
}
static gboolean
-gst_espeak_src_is_seekable (GstBaseSrc * src)
+gst_espeak_is_seekable (GstBaseSrc * src)
{
return FALSE;
}
-static gboolean gst_espeak_src_unlock (GstBaseSrc * bsrc)
+static gboolean gst_espeak_unlock (GstBaseSrc * bsrc)
{
return TRUE;
}
-static gboolean gst_espeak_src_unlock_stop (GstBaseSrc * bsrc)
+static gboolean gst_espeak_unlock_stop (GstBaseSrc * bsrc)
{
return TRUE;
}
-static gboolean gst_espeak_src_do_seek (GstBaseSrc * src, GstSegment * segment)
+static gboolean gst_espeak_do_seek (GstBaseSrc * src, GstSegment * segment)
{
return TRUE;
}
-static gboolean gst_espeak_src_check_get_range (GstBaseSrc * src)
+static gboolean gst_espeak_check_get_range (GstBaseSrc * src)
{
return FALSE;
}
-static gboolean gst_espeak_src_do_get_size (GstBaseSrc * src, guint64 * size)
+static gboolean gst_espeak_do_get_size (GstBaseSrc * src, guint64 * size)
{
*size = -1;
return TRUE;
@@ -284,6 +315,91 @@ static gboolean gst_espeak_src_do_get_size (GstBaseSrc * src, guint64 * size)
/******************************************************************************/
+static GstURIType
+gst_espeak_uri_get_type(void)
+{
+ return GST_URI_SRC;
+}
+
+static gchar**
+gst_espeak_uri_get_protocols(void)
+{
+ static gchar *protocols[] = { "espeak", NULL };
+ return protocols;
+}
+
+static const gchar *
+gst_espeak_uri_get_uri(GstURIHandler *handler)
+{
+ GstEspeak *self = GST_ESPEAK(handler);
+ return self->uri;
+}
+
+static gboolean
+gst_espeak_uri_set_uri(GstURIHandler *handler, const gchar *uri)
+{
+ gchar *protocol, *text;
+ gboolean ret;
+
+ protocol = gst_uri_get_protocol(uri);
+ ret = strcmp(protocol, "espeak") == 0;
+ g_free(protocol);
+ if (!ret) return FALSE;
+
+ text = gst_uri_get_location(uri);
+
+ if (!text)
+ return FALSE;
+
+ ret = gst_espeak_set_text(GST_ESPEAK(handler), text);
+ g_free (text);
+
+ return ret;
+}
+
+static void
+gst_espeak_uri_handler_init(gpointer g_iface, gpointer iface_data)
+{
+ GstURIHandlerInterface *iface = (GstURIHandlerInterface*) g_iface;
+
+ iface->get_type = gst_espeak_uri_get_type;
+ iface->get_protocols = gst_espeak_uri_get_protocols;
+ iface->get_uri = gst_espeak_uri_get_uri;
+ iface->set_uri = gst_espeak_uri_set_uri;
+}
+
+static void
+gst_espeak_init_uri(GType filesrc_type)
+{
+ static const GInterfaceInfo urihandler_info = {
+ gst_espeak_uri_handler_init,
+ NULL,
+ NULL
+ };
+ g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER,
+ &urihandler_info);
+}
+
+/******************************************************************************/
+
+/* entry point to initialize the plug-in
+ * initialize the plug-in itself
+ * register the element factories and other features
+ */
+static gboolean
+espeak_init (GstPlugin * espeak)
+{
+ /* debug category for fltering log messages
+ *
+ * exchange the string 'Template espeak' with your description
+ */
+ GST_DEBUG_CATEGORY_INIT (gst_espeak_debug, "espeak",
+ 0, "Template espeak");
+
+ return gst_element_register (espeak, "espeak", GST_RANK_NONE,
+ GST_TYPE_ESPEAK);
+}
+
/* gstreamer looks for this structure to register espeaks
*
* exchange the string 'Template espeak' with your espeak description
diff --git a/src/gstespeak.h b/src/gstespeak.h
index 90d3044..f7f2884 100644
--- a/src/gstespeak.h
+++ b/src/gstespeak.h
@@ -69,14 +69,16 @@ struct Espeak;
struct _GstEspeak
{
- GstAudioSrc parent;
- struct Espeak *speak;
- gboolean silent;
+ GstAudioSrc parent;
+ struct Espeak *speak;
+ gchar *text;
+ gchar *uri;
+ gboolean silent;
};
struct _GstEspeakClass
{
- GstAudioSrcClass parent_class;
+ GstAudioSrcClass parent_class;
};
GType gst_espeak_get_type (void);