[the-board/sound-thing: 1/4] initial sketch for sound recorder and player
- From: Lucas Rocha <lucasr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [the-board/sound-thing: 1/4] initial sketch for sound recorder and player
- Date: Wed, 5 Jan 2011 10:30:20 +0000 (UTC)
commit 52c2764bd4644a5823b6d470bc9adc7f6a674413
Author: Lucas Rocha <lucasr gnome org>
Date: Sun Dec 26 00:19:00 2010 +0000
initial sketch for sound recorder and player
src/Makefile-tb.am | 8 +-
src/tb/tb-sound-player.c | 425 ++++++++++++++++++++++++++++++++++++++++++++
src/tb/tb-sound-player.h | 44 +++++
src/tb/tb-sound-recorder.c | 389 ++++++++++++++++++++++++++++++++++++++++
src/tb/tb-sound-recorder.h | 47 +++++
5 files changed, 911 insertions(+), 2 deletions(-)
---
diff --git a/src/Makefile-tb.am b/src/Makefile-tb.am
index 69d7811..55d6213 100644
--- a/src/Makefile-tb.am
+++ b/src/Makefile-tb.am
@@ -23,7 +23,9 @@ tb_source_h = \
tb/tb-gio-util.h \
tb/tb-gdk-util.h \
tb/tb-gobject-util.h \
- tb/tb-mx-util.h
+ tb/tb-mx-util.h \
+ tb/tb-sound-player.h \
+ tb/tb-sound-recorder.h
if HAVE_LIBSOUP
tb_source_h += tb/tb-soup-util.h
@@ -34,7 +36,9 @@ tb_source_c = \
tb/tb-gio-util.c \
tb/tb-gdk-util.c \
tb/tb-gobject-util.c \
- tb/tb-mx-util.c
+ tb/tb-mx-util.c \
+ tb/tb-sound-player.c \
+ tb/tb-sound-recorder.c
if HAVE_LIBSOUP
tb_source_c += tb/tb-soup-util.c
diff --git a/src/tb/tb-sound-player.c b/src/tb/tb-sound-player.c
new file mode 100644
index 0000000..5cb998d
--- /dev/null
+++ b/src/tb/tb-sound-player.c
@@ -0,0 +1,425 @@
+#include <glib.h>
+#include <glib-object.h>
+#include <gst/gst.h>
+
+#include "tb-enum-types.h"
+#include "tb/tb-sound-player.h"
+
+G_DEFINE_TYPE (TbSoundPlayer, tb_sound_player, G_TYPE_OBJECT);
+
+#define TB_SOUND_PLAYER_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TB_TYPE_SOUND_PLAYER, TbSoundPlayerPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_PLAYING,
+ PROP_STATE,
+ PROP_FILENAME
+};
+
+struct _TbSoundPlayerPrivate
+{
+ GstElement *pipeline;
+ GstBus *bus;
+ TbSoundPlayerState state;
+ char *filename;
+ gboolean playing;
+};
+
+static void tb_sound_player_destroy_pipeline (TbSoundPlayer *player);
+
+static void
+tb_sound_player_set_state (TbSoundPlayer *player,
+ TbSoundPlayerState state)
+{
+ TbSoundPlayerPrivate *priv;
+
+ g_return_if_fail (TB_IS_SOUND_PLAYER (player));
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ if (priv->state == state)
+ return;
+
+ priv->state = state;
+
+ g_object_notify (G_OBJECT (player), "state");
+}
+
+static void
+tb_sound_player_set_filename (TbSoundPlayer *player,
+ const char *filename)
+{
+ TbSoundPlayerPrivate *priv;
+
+ g_return_if_fail (TB_IS_SOUND_PLAYER (player));
+ g_return_if_fail (filename != NULL);
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ if (priv->filename &&
+ !strcmp (priv->filename, filename))
+ return;
+
+ g_free (priv->filename);
+ priv->filename = g_strdup (filename);
+
+ if (priv->pipeline)
+ tb_sound_player_destroy_pipeline (player);
+
+ g_object_notify (G_OBJECT (player), "filename");
+}
+
+static void
+tb_sound_player_reset_pipeline (TbSoundPlayer *player)
+{
+ TbSoundPlayerPrivate *priv;
+ GstState state, pending;
+ GstMessage *msg;
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ if (!priv->pipeline)
+ return;
+
+ gst_element_get_state (priv->pipeline, &state, &pending, 0);
+
+ if (state == GST_STATE_NULL && pending == GST_STATE_VOID_PENDING)
+ {
+ return;
+ }
+ else if (state == GST_STATE_NULL && pending != GST_STATE_VOID_PENDING)
+ {
+ gst_element_set_state (priv->pipeline, GST_STATE_NULL);
+ return;
+ }
+
+ gst_element_set_state (priv->pipeline, GST_STATE_READY);
+ gst_element_get_state (priv->pipeline, NULL, NULL, -1);
+
+ while ((msg = gst_bus_pop (priv->bus)))
+ gst_bus_async_signal_func (priv->bus, msg, NULL);
+
+ gst_element_set_state (priv->pipeline, GST_STATE_NULL);
+}
+
+static void
+tb_sound_player_destroy_pipeline (TbSoundPlayer *player)
+{
+ TbSoundPlayerPrivate *priv;
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ if (priv->bus)
+ {
+ gst_bus_set_flushing (priv->bus, TRUE);
+ gst_bus_remove_signal_watch (priv->bus);
+
+ gst_object_unref (priv->bus);
+ priv->bus = NULL;
+ }
+
+ if (priv->pipeline)
+ {
+ gst_element_set_state (priv->pipeline, GST_STATE_NULL);
+
+ gst_object_unref (priv->pipeline);
+ priv->pipeline = NULL;
+ }
+}
+
+static void
+tb_sound_player_on_state_changed (GstBus *bus,
+ GstMessage *msg,
+ TbSoundPlayer *player)
+{
+ TbSoundPlayerPrivate *priv;
+ GstState state;
+
+ g_return_if_fail (TB_IS_SOUND_PLAYER (player));
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ if (msg->src != GST_OBJECT (priv->pipeline))
+ return;
+
+ gst_message_parse_state_changed (msg, NULL, &state, NULL);
+
+ switch (state)
+ {
+ case GST_STATE_PLAYING:
+ tb_sound_player_set_state (player, TB_SOUND_PLAYER_STATE_PLAYING);
+ break;
+
+ case GST_STATE_READY:
+ case GST_STATE_PAUSED:
+ tb_sound_player_set_state (player, TB_SOUND_PLAYER_STATE_IDLE);
+ break;
+
+ default:
+ /* Do nothing */
+ break;
+ }
+}
+
+static void
+tb_sound_player_on_error (GstBus *bus,
+ GstMessage *msg,
+ TbSoundPlayer *player)
+{
+ tb_sound_player_reset_pipeline (player);
+ tb_sound_player_set_state (player, TB_SOUND_PLAYER_STATE_ERROR);
+}
+
+static void
+tb_sound_player_on_eos (GstBus *bus,
+ GstMessage *msg,
+ TbSoundPlayer *player)
+{
+ tb_sound_player_set_state (player, TB_SOUND_PLAYER_STATE_DONE);
+ tb_sound_player_reset_pipeline (player);
+}
+
+static gboolean
+tb_sound_player_ensure_pipeline (TbSoundPlayer *player)
+{
+ TbSoundPlayerPrivate *priv;
+ GError *error;
+ gchar *pipeline_desc;
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ if (priv->pipeline)
+ return TRUE;
+
+ if (priv->filename == NULL)
+ {
+ tb_sound_player_set_state (player, TB_SOUND_PLAYER_STATE_ERROR);
+ return FALSE;
+ }
+
+ error = NULL;
+
+ pipeline_desc = g_strdup_printf("playbin uri=file://%s",
+ priv->filename);
+
+ priv->pipeline = gst_parse_launch (pipeline_desc, &error);
+
+ g_free (pipeline_desc);
+
+ if (error)
+ {
+ g_error_free (error);
+ priv->pipeline = NULL;
+
+ tb_sound_player_set_state (player, TB_SOUND_PLAYER_STATE_ERROR);
+ return FALSE;
+ }
+
+ if (!gst_element_set_state (priv->pipeline, GST_STATE_READY))
+ {
+ g_object_unref (priv->pipeline);
+ priv->pipeline = NULL;
+
+ tb_sound_player_set_state (player, TB_SOUND_PLAYER_STATE_ERROR);
+ return FALSE;
+ }
+
+ priv->bus = gst_element_get_bus (priv->pipeline);
+
+ gst_bus_add_signal_watch (priv->bus);
+
+ g_signal_connect (priv->bus,
+ "message::state-changed",
+ G_CALLBACK (tb_sound_player_on_state_changed),
+ player);
+
+ g_signal_connect (priv->bus,
+ "message::error",
+ G_CALLBACK (tb_sound_player_on_error),
+ player);
+
+ g_signal_connect (priv->bus,
+ "message::eos",
+ G_CALLBACK (tb_sound_player_on_eos),
+ player);
+
+ return TRUE;
+}
+
+void
+tb_sound_player_set_playing (TbSoundPlayer *player,
+ gboolean playing)
+{
+ TbSoundPlayerPrivate *priv;
+ GstState state;
+
+ g_return_if_fail (TB_IS_SOUND_PLAYER (player));
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ if (playing)
+ state = GST_STATE_PLAYING;
+ else
+ state = GST_STATE_PAUSED;
+
+ if (tb_sound_player_ensure_pipeline (player))
+ gst_element_set_state (priv->pipeline, state);
+
+ g_object_notify (G_OBJECT (player), "playing");
+}
+
+static gboolean
+tb_sound_player_get_playing (TbSoundPlayer *player)
+{
+ TbSoundPlayerPrivate *priv;
+ GstState state, pending;
+ gboolean playing;
+
+ g_return_if_fail (TB_IS_SOUND_PLAYER (player));
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ if (!priv->pipeline)
+ return FALSE;
+
+ gst_element_get_state (priv->pipeline, &state, &pending, 0);
+
+ if (pending)
+ playing = (pending == GST_STATE_PLAYING);
+ else
+ playing = (state == GST_STATE_PLAYING);
+
+ return playing;
+}
+
+static void
+tb_sound_player_finalize (GObject *gobject)
+{
+ G_OBJECT_CLASS (tb_sound_player_parent_class)->finalize (gobject);
+}
+
+static void
+tb_sound_player_dispose (GObject *gobject)
+{
+ tb_sound_player_destroy_pipeline (TB_SOUND_PLAYER (gobject));
+
+ G_OBJECT_CLASS (tb_sound_player_parent_class)->dispose (gobject);
+}
+
+static void
+tb_sound_player_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TbSoundPlayerPrivate *priv;
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (gobject);
+
+ switch (prop_id)
+ {
+ case PROP_PLAYING:
+ g_value_set_boolean (value,
+ tb_sound_player_get_playing (TB_SOUND_PLAYER (gobject)));
+ break;
+
+ case PROP_STATE:
+ g_value_set_enum (value, priv->state);
+ break;
+
+ case PROP_FILENAME:
+ g_value_set_string (value, priv->filename);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tb_sound_player_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TbSoundPlayerPrivate *priv;
+
+ priv = TB_SOUND_PLAYER_GET_PRIVATE (gobject);
+
+ switch (prop_id)
+ {
+ case PROP_PLAYING:
+ tb_sound_player_set_playing (TB_SOUND_PLAYER (gobject),
+ g_value_get_boolean (value));
+ break;
+
+ case PROP_FILENAME:
+ tb_sound_player_set_filename (TB_SOUND_PLAYER (gobject),
+ g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tb_sound_player_class_init (TbSoundPlayerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (TbSoundPlayerPrivate));
+
+ gobject_class->get_property = tb_sound_player_get_property;
+ gobject_class->set_property = tb_sound_player_set_property;
+ gobject_class->dispose = tb_sound_player_dispose;
+ gobject_class->finalize = tb_sound_player_finalize;
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_PLAYING,
+ g_param_spec_boolean ("playing",
+ "Playing",
+ "Whether player is playing or not",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_STATE,
+ g_param_spec_enum ("state",
+ "State",
+ "State of the sound player",
+ TB_TYPE_SOUND_PLAYER_STATE,
+ TB_SOUND_PLAYER_STATE_UNKNOWN,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_FILENAME,
+ g_param_spec_string ("filename",
+ "Filename",
+ "Filename to save sound to",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+}
+
+static void
+tb_sound_player_init (TbSoundPlayer *player)
+{
+ TbSoundPlayerPrivate *priv;
+
+ player->priv = TB_SOUND_PLAYER_GET_PRIVATE (player);
+
+ player->priv->state = TB_SOUND_PLAYER_STATE_UNKNOWN;
+ player->priv->playing = FALSE;
+ player->priv->filename = NULL;
+ player->priv->pipeline = NULL;
+ player->priv->bus = NULL;
+}
diff --git a/src/tb/tb-sound-player.h b/src/tb/tb-sound-player.h
new file mode 100644
index 0000000..5dd7459
--- /dev/null
+++ b/src/tb/tb-sound-player.h
@@ -0,0 +1,44 @@
+#ifndef __TB_SOUND_PLAYER_H__
+#define __TB_SOUND_PLAYER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define TB_TYPE_SOUND_PLAYER (tb_sound_player_get_type ())
+#define TB_SOUND_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TB_TYPE_SOUND_PLAYER, TbSoundPlayer))
+#define TB_IS_SOUND_PLAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TB_TYPE_SOUND_PLAYER))
+#define TB_SOUND_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TB_TYPE_SOUND_PLAYER, TbSoundPlayerClass))
+#define TB_IS_SOUND_PLAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TB_TYPE_SOUND_PLAYER))
+#define TB_SOUND_PLAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TB_TYPE_SOUND_PLAYER, TbSoundPlayerClass))
+
+typedef struct _TbSoundPlayer TbSoundPlayer;
+typedef struct _TbSoundPlayerPrivate TbSoundPlayerPrivate;
+typedef struct _TbSoundPlayerClass TbSoundPlayerClass;
+
+typedef enum
+{
+ TB_SOUND_PLAYER_STATE_UNKNOWN = 0,
+ TB_SOUND_PLAYER_STATE_IDLE = 1,
+ TB_SOUND_PLAYER_STATE_PLAYING = 2,
+ TB_SOUND_PLAYER_STATE_DONE = 3,
+ TB_SOUND_PLAYER_STATE_ERROR = 4
+} TbSoundPlayerState;
+
+struct _TbSoundPlayer
+{
+ GObject parent_instance;
+
+ TbSoundPlayerPrivate *priv;
+};
+
+struct _TbSoundPlayerClass
+{
+ GObjectClass parent_class;
+};
+
+GType tb_sound_player_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __TB_SOUND_PLAYER_H__ */
diff --git a/src/tb/tb-sound-recorder.c b/src/tb/tb-sound-recorder.c
new file mode 100644
index 0000000..ec87aea
--- /dev/null
+++ b/src/tb/tb-sound-recorder.c
@@ -0,0 +1,389 @@
+#include <glib.h>
+#include <glib-object.h>
+#include <gst/gst.h>
+
+#include "tb-enum-types.h"
+#include "tb/tb-sound-recorder.h"
+
+G_DEFINE_TYPE (TbSoundRecorder, tb_sound_recorder, G_TYPE_OBJECT);
+
+#define TB_SOUND_RECORDER_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TB_TYPE_SOUND_RECORDER, TbSoundRecorderPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_STATE,
+ PROP_FILENAME
+};
+
+struct _TbSoundRecorderPrivate
+{
+ GstElement *pipeline;
+ GstBus *bus;
+ TbSoundRecorderState state;
+ char *filename;
+};
+
+static void tb_sound_recorder_destroy_pipeline (TbSoundRecorder *recorder);
+
+static void
+tb_sound_recorder_set_state (TbSoundRecorder *recorder,
+ TbSoundRecorderState state)
+{
+ TbSoundRecorderPrivate *priv;
+
+ g_return_if_fail (TB_IS_SOUND_RECORDER (recorder));
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ if (priv->state == state)
+ return;
+
+ priv->state = state;
+
+ g_object_notify (G_OBJECT (recorder), "state");
+}
+
+static void
+tb_sound_recorder_set_filename (TbSoundRecorder *recorder,
+ const char *filename)
+{
+ TbSoundRecorderPrivate *priv;
+
+ g_return_if_fail (TB_IS_SOUND_RECORDER (recorder));
+ g_return_if_fail (filename != NULL);
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ if (priv->filename &&
+ !strcmp (priv->filename, filename))
+ return;
+
+ g_free (priv->filename);
+ priv->filename = g_strdup (filename);
+
+ if (priv->pipeline)
+ tb_sound_recorder_destroy_pipeline (recorder);
+
+ g_object_notify (G_OBJECT (recorder), "filename");
+}
+
+static void
+tb_sound_recorder_reset_pipeline (TbSoundRecorder *recorder)
+{
+ TbSoundRecorderPrivate *priv;
+ GstState state, pending;
+ GstMessage *msg;
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ if (!priv->pipeline)
+ return;
+
+ gst_element_get_state (priv->pipeline, &state, &pending, 0);
+
+ if (state == GST_STATE_NULL && pending == GST_STATE_VOID_PENDING)
+ {
+ return;
+ }
+ else if (state == GST_STATE_NULL && pending != GST_STATE_VOID_PENDING)
+ {
+ gst_element_set_state (priv->pipeline, GST_STATE_NULL);
+ return;
+ }
+
+ gst_element_set_state (priv->pipeline, GST_STATE_READY);
+ gst_element_get_state (priv->pipeline, NULL, NULL, -1);
+
+ while ((msg = gst_bus_pop (priv->bus)))
+ gst_bus_async_signal_func (priv->bus, msg, NULL);
+
+ gst_element_set_state (priv->pipeline, GST_STATE_NULL);
+}
+
+static void
+tb_sound_recorder_destroy_pipeline (TbSoundRecorder *recorder)
+{
+ TbSoundRecorderPrivate *priv;
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ if (priv->bus)
+ {
+ gst_bus_set_flushing (priv->bus, TRUE);
+ gst_bus_remove_signal_watch (priv->bus);
+
+ gst_object_unref (priv->bus);
+ priv->bus = NULL;
+ }
+
+ if (priv->pipeline)
+ {
+ gst_element_set_state (priv->pipeline, GST_STATE_NULL);
+
+ gst_object_unref (priv->pipeline);
+ priv->pipeline = NULL;
+ }
+}
+
+static void
+tb_sound_recorder_on_state_changed (GstBus *bus,
+ GstMessage *msg,
+ TbSoundRecorder *recorder)
+{
+ TbSoundRecorderPrivate *priv;
+ GstState state;
+
+ g_return_if_fail (TB_IS_SOUND_RECORDER (recorder));
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ if (msg->src != GST_OBJECT (priv->pipeline))
+ return;
+
+ gst_message_parse_state_changed (msg, NULL, &state, NULL);
+
+ switch (state)
+ {
+ case GST_STATE_PLAYING:
+ tb_sound_recorder_set_state (recorder, TB_SOUND_RECORDER_STATE_RECORDING);
+ break;
+
+ case GST_STATE_READY:
+ case GST_STATE_PAUSED:
+ tb_sound_recorder_set_state (recorder, TB_SOUND_RECORDER_STATE_IDLE);
+ break;
+
+ default:
+ /* Do nothing */
+ break;
+ }
+}
+
+static void
+tb_sound_recorder_on_error (GstBus *bus,
+ GstMessage *msg,
+ TbSoundRecorder *recorder)
+{
+ tb_sound_recorder_reset_pipeline (recorder);
+ tb_sound_recorder_set_state (recorder, TB_SOUND_RECORDER_STATE_ERROR);
+}
+
+static void
+tb_sound_recorder_on_eos (GstBus *bus,
+ GstMessage *msg,
+ TbSoundRecorder *recorder)
+{
+ tb_sound_recorder_set_state (recorder, TB_SOUND_RECORDER_STATE_DONE);
+ tb_sound_recorder_reset_pipeline (recorder);
+}
+
+static gboolean
+tb_sound_recorder_ensure_pipeline (TbSoundRecorder *recorder)
+{
+ TbSoundRecorderPrivate *priv;
+ GError *error;
+ gchar *pipeline_desc;
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ if (priv->pipeline)
+ return TRUE;
+
+ if (priv->filename == NULL)
+ {
+ tb_sound_recorder_set_state (recorder, TB_SOUND_RECORDER_STATE_ERROR);
+ return FALSE;
+ }
+
+ error = NULL;
+
+ pipeline_desc = g_strdup_printf("autoaudiosrc name=source ! "
+ "audioconvert ! "
+ "wavenc ! "
+ "filesink location=%s",
+ priv->filename);
+
+ priv->pipeline = gst_parse_launch (pipeline_desc, &error);
+
+ g_free (pipeline_desc);
+
+ if (error)
+ {
+ g_error_free (error);
+ priv->pipeline = NULL;
+
+ tb_sound_recorder_set_state (recorder, TB_SOUND_RECORDER_STATE_ERROR);
+ return FALSE;
+ }
+
+ if (!gst_element_set_state (priv->pipeline, GST_STATE_READY))
+ {
+ g_object_unref (priv->pipeline);
+ priv->pipeline = NULL;
+
+ tb_sound_recorder_set_state (recorder, TB_SOUND_RECORDER_STATE_ERROR);
+ return FALSE;
+ }
+
+ priv->bus = gst_element_get_bus (priv->pipeline);
+
+ gst_bus_add_signal_watch (priv->bus);
+
+ g_signal_connect (priv->bus,
+ "message::state-changed",
+ G_CALLBACK (tb_sound_recorder_on_state_changed),
+ recorder);
+
+ g_signal_connect (priv->bus,
+ "message::error",
+ G_CALLBACK (tb_sound_recorder_on_error),
+ recorder);
+
+ g_signal_connect (priv->bus,
+ "message::eos",
+ G_CALLBACK (tb_sound_recorder_on_eos),
+ recorder);
+
+ return TRUE;
+}
+
+static void
+tb_sound_recorder_finalize (GObject *gobject)
+{
+ G_OBJECT_CLASS (tb_sound_recorder_parent_class)->finalize (gobject);
+}
+
+static void
+tb_sound_recorder_dispose (GObject *gobject)
+{
+ tb_sound_recorder_destroy_pipeline (TB_SOUND_RECORDER (gobject));
+
+ G_OBJECT_CLASS (tb_sound_recorder_parent_class)->dispose (gobject);
+}
+
+static void
+tb_sound_recorder_get_property (GObject *gobject,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TbSoundRecorderPrivate *priv;
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (gobject);
+
+ switch (prop_id)
+ {
+ case PROP_STATE:
+ g_value_set_enum (value, priv->state);
+ break;
+
+ case PROP_FILENAME:
+ g_value_set_string (value, priv->filename);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tb_sound_recorder_set_property (GObject *gobject,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TbSoundRecorderPrivate *priv;
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (gobject);
+
+ switch (prop_id)
+ {
+ case PROP_FILENAME:
+ tb_sound_recorder_set_filename (TB_SOUND_RECORDER (gobject),
+ g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tb_sound_recorder_class_init (TbSoundRecorderClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (TbSoundRecorderPrivate));
+
+ gobject_class->get_property = tb_sound_recorder_get_property;
+ gobject_class->set_property = tb_sound_recorder_set_property;
+ gobject_class->dispose = tb_sound_recorder_dispose;
+ gobject_class->finalize = tb_sound_recorder_finalize;
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_STATE,
+ g_param_spec_enum ("state",
+ "State",
+ "State of the sound recorder",
+ TB_TYPE_SOUND_RECORDER_STATE,
+ TB_SOUND_RECORDER_STATE_UNKNOWN,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property
+ (gobject_class,
+ PROP_FILENAME,
+ g_param_spec_string ("filename",
+ "Filename",
+ "Filename to save sound to",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+}
+
+static void
+tb_sound_recorder_init (TbSoundRecorder *recorder)
+{
+ TbSoundRecorderPrivate *priv;
+
+ recorder->priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ recorder->priv->state = TB_SOUND_RECORDER_STATE_UNKNOWN;
+ recorder->priv->filename = NULL;
+ recorder->priv->pipeline = NULL;
+ recorder->priv->bus = NULL;
+}
+
+void
+tb_sound_recorder_start (TbSoundRecorder *recorder)
+{
+ TbSoundRecorderPrivate *priv;
+
+ g_return_if_fail (TB_IS_SOUND_RECORDER (recorder));
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ if (tb_sound_recorder_ensure_pipeline (recorder))
+ gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
+}
+
+void
+tb_sound_recorder_stop (TbSoundRecorder *recorder)
+{
+ TbSoundRecorderPrivate *priv;
+ GstElement *source;
+
+ g_return_if_fail (TB_IS_SOUND_RECORDER (recorder));
+
+ priv = TB_SOUND_RECORDER_GET_PRIVATE (recorder);
+
+ if (priv->pipeline == NULL)
+ return;
+
+ gst_element_send_event (priv->pipeline, gst_event_new_eos());
+}
diff --git a/src/tb/tb-sound-recorder.h b/src/tb/tb-sound-recorder.h
new file mode 100644
index 0000000..31199ca
--- /dev/null
+++ b/src/tb/tb-sound-recorder.h
@@ -0,0 +1,47 @@
+#ifndef __TB_SOUND_RECORDER_H__
+#define __TB_SOUND_RECORDER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define TB_TYPE_SOUND_RECORDER (tb_sound_recorder_get_type ())
+#define TB_SOUND_RECORDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TB_TYPE_SOUND_RECORDER, TbSoundRecorder))
+#define TB_IS_SOUND_RECORDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TB_TYPE_SOUND_RECORDER))
+#define TB_SOUND_RECORDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TB_TYPE_SOUND_RECORDER, TbSoundRecorderClass))
+#define TB_IS_SOUND_RECORDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TB_TYPE_SOUND_RECORDER))
+#define TB_SOUND_RECORDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TB_TYPE_SOUND_RECORDER, TbSoundRecorderClass))
+
+typedef struct _TbSoundRecorder TbSoundRecorder;
+typedef struct _TbSoundRecorderPrivate TbSoundRecorderPrivate;
+typedef struct _TbSoundRecorderClass TbSoundRecorderClass;
+
+typedef enum
+{
+ TB_SOUND_RECORDER_STATE_UNKNOWN = 0,
+ TB_SOUND_RECORDER_STATE_IDLE = 1,
+ TB_SOUND_RECORDER_STATE_RECORDING = 2,
+ TB_SOUND_RECORDER_STATE_DONE = 3,
+ TB_SOUND_RECORDER_STATE_ERROR = 4
+} TbSoundRecorderState;
+
+struct _TbSoundRecorder
+{
+ GObject parent_instance;
+
+ TbSoundRecorderPrivate *priv;
+};
+
+struct _TbSoundRecorderClass
+{
+ GObjectClass parent_class;
+};
+
+GType tb_sound_recorder_get_type (void) G_GNUC_CONST;
+
+void tb_sound_recorder_start (TbSoundRecorder *recorder);
+void tb_sound_recorder_stop (TbSoundRecorder *recorder);
+
+G_END_DECLS
+
+#endif /* __TB_SOUND_RECORDER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]