diff options
-rw-r--r-- | gst/playondemand/demo-mp3.c | 36 | ||||
-rw-r--r-- | gst/playondemand/filter.func | 52 | ||||
-rw-r--r-- | gst/playondemand/gstplayondemand.c | 16 | ||||
-rw-r--r-- | gst/playondemand/gstplayondemand.h | 17 |
4 files changed, 57 insertions, 64 deletions
diff --git a/gst/playondemand/demo-mp3.c b/gst/playondemand/demo-mp3.c index 7161aae40..6e404a15c 100644 --- a/gst/playondemand/demo-mp3.c +++ b/gst/playondemand/demo-mp3.c @@ -4,13 +4,14 @@ #include <gst/gst.h> #define NUM_BEATS 12 +#define TICK_RATE(x) (x * 1e-6) GtkWidget *window, *vbox, *beat_box, *button_box; GtkWidget *play_button, *clear_button, *reset_button, *quit_button; GtkWidget **beat_button; GtkWidget *speed_scale; GtkObject *speed_adj; -GstElement *src, *mad, *conv, *pod, *sink, *pipeline; +GstElement *src, *dec, *pod, *sink, *pipeline; GstClock *element_clock; guint32 *beats; @@ -63,36 +64,33 @@ beat (GtkToggleButton *button, gpointer data) void speed (GtkAdjustment *adjustment, gpointer data) { - g_signal_stop_emission_by_name(G_OBJECT(pod), "deep-notify"); - g_object_set(G_OBJECT(pod), "tick-rate", adjustment->value, NULL); + /*g_signal_stop_emission_by_name(G_OBJECT(pod), "deep-notify");*/ + g_object_set(G_OBJECT(pod), "tick-rate", TICK_RATE(adjustment->value), NULL); /*gst_clock_set_speed(element_clock, adjustment->value);*/ } void setup_pipeline (gchar *filename) { - src = gst_element_factory_make("filesrc", "filesrc"); - mad = gst_element_factory_make("mad", "mad"); - conv = gst_element_factory_make("audioconvert", "audioconvert"); - pod = gst_element_factory_make("playondemand", "playondemand"); - sink = gst_element_factory_make("alsasink", "alsasink"); + src = gst_element_factory_make("filesrc", "source"); + dec = gst_element_factory_make("vorbisfile", "decoder"); + pod = gst_element_factory_make("playondemand", "sequencer"); + sink = gst_element_factory_make("alsasink", "sink"); - g_object_set(G_OBJECT(src), "location", filename, NULL); - g_object_set(G_OBJECT(sink), "period-count", 64, - "period-size", 512, NULL); - g_object_set(G_OBJECT(pod), "total-ticks", NUM_BEATS, - "tick-rate", 1.0, - "max-plays", NUM_BEATS * 2, NULL); + g_object_set(G_OBJECT (src), "location", filename, NULL); + g_object_set(G_OBJECT (sink), "period-count", 64, "period-size", 512, NULL); + g_object_set(G_OBJECT (pod), "total-ticks", NUM_BEATS, + "tick-rate", 1.0e-6, "max-plays", NUM_BEATS * 2, NULL); - g_object_get(G_OBJECT(pod), "ticks", &beats, NULL); + g_object_get(G_OBJECT (pod), "ticks", &beats, NULL); pipeline = gst_pipeline_new("app"); - gst_bin_add_many(GST_BIN(pipeline), src, mad, conv, pod, sink, NULL); - gst_element_link_many(src, mad, conv, pod, sink, NULL); + gst_bin_add_many(GST_BIN (pipeline), src, dec, pod, sink, NULL); + gst_element_link_many(src, dec, pod, sink, NULL); - element_clock = gst_bin_get_clock(GST_BIN(pipeline)); - gst_element_set_clock(GST_ELEMENT(pod), element_clock); + element_clock = gst_element_get_clock(GST_ELEMENT (sink)); + gst_element_set_clock(GST_ELEMENT (pod), element_clock); } void diff --git a/gst/playondemand/filter.func b/gst/playondemand/filter.func index a07edf4e1..3f2755a0b 100644 --- a/gst/playondemand/filter.func +++ b/gst/playondemand/filter.func @@ -6,37 +6,36 @@ filter_data = (_TYPE_ *) filter->buffer; num_filter = filter->buffer_bytes / sizeof(_TYPE_); do { - if (in == NULL && ! filter->eos) in = GST_BUFFER (gst_pad_pull(filter->sinkpad)); - - /****************************************************************************/ /* see if we've got any events coming through ... */ - while (! filter->eos && GST_IS_EVENT(in)) { - if (GST_EVENT_TYPE(in) == GST_EVENT_EOS) { - gst_event_unref(in); - gst_buffer_free(in); + while (! filter->eos && in != NULL && GST_IS_EVENT (in)) { + GstEvent *event = GST_EVENT (in); + if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { + gst_event_unref (event); + gst_data_free (in); + in = NULL; filter->eos = TRUE; - } else if ((GST_EVENT_TYPE(in) == GST_EVENT_SEEK) || - (GST_EVENT_TYPE(in) == GST_EVENT_FLUSH)) { - gst_event_unref(in); - gst_buffer_free(in); + } else if ((GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS) || + (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH)) { + gst_event_unref (event); + gst_data_free (in); + in = NULL; filter->eos = FALSE; filter->write = 0; } else { - gst_pad_push(filter->srcpad, GST_DATA (in)); + gst_pad_push(filter->srcpad, in); } - in = GST_BUFFER (gst_pad_pull(filter->sinkpad)); + in = (in == NULL && ! filter->eos) ? gst_pad_pull(filter->sinkpad) : NULL; } - /****************************************************************************/ /* handle data from the input buffer. */ if (! filter->eos) { register guint j, w = filter->write; - data_in = (_TYPE_ *) GST_BUFFER_DATA(in); - num_in = GST_BUFFER_SIZE(in) / sizeof(_TYPE_); + data_in = (_TYPE_ *) GST_BUFFER_DATA (GST_BUFFER (in)); + num_in = GST_BUFFER_SIZE (in) / sizeof(_TYPE_); for (j = 0; (j < num_in) && (w+j < num_filter); j++) filter_data[w+j] = data_in[j]; @@ -45,14 +44,13 @@ do { if (filter->write >= num_filter) filter->eos = TRUE; - out = in; + out = GST_BUFFER (in); } else { out = gst_buffer_new_from_pool(filter->bufpool, 0, 0); } in = NULL; - /****************************************************************************/ /* check to see if we have to add new play pointers. */ if (filter->clock) { @@ -60,12 +58,8 @@ do { guint total_ticks = filter->total_ticks; guint current_tick = \ - ((guint) (gst_clock_get_time(filter->clock) * filter->tick_rate / - GST_SECOND)) % total_ticks; - - /* for some reason modulo arithmetic isn't working for me here, i suspect - some unsigned/signed voodoo. but it's probably safe to do this with an if - statement since it doesn't happen all that often ... */ + ((guint) (gst_clock_get_time(filter->clock) * \ + filter->tick_rate / GST_SECOND)) % total_ticks; tick_offset = current_tick - last_tick; if (tick_offset < 0) tick_offset += total_ticks; @@ -84,14 +78,13 @@ do { last_tick = current_tick; } - /****************************************************************************/ /* handle output data. */ { register guint k, p; - data_out = (_TYPE_ *) GST_BUFFER_DATA(out); - num_out = GST_BUFFER_SIZE(out) / sizeof(_TYPE_); + data_out = (_TYPE_ *) GST_BUFFER_DATA (out); + num_out = GST_BUFFER_SIZE (out) / sizeof(_TYPE_); for (k = 0; k < num_out; k++) data_out[k] = zero; @@ -111,11 +104,12 @@ do { } } - /****************************************************************************/ - /* push out the buffer. */ + /* push out the buffer and get a new buffer if we're allowed to loop. */ gst_pad_push(filter->srcpad, GST_DATA (out)); if (gst_element_interrupt (GST_ELEMENT (filter))) break; + in = (in == NULL && ! filter->eos) ? gst_pad_pull(filter->sinkpad) : NULL; + } while (TRUE); diff --git a/gst/playondemand/gstplayondemand.c b/gst/playondemand/gstplayondemand.c index afac7bddf..0c06bbd2f 100644 --- a/gst/playondemand/gstplayondemand.c +++ b/gst/playondemand/gstplayondemand.c @@ -44,9 +44,9 @@ /* element factory information */ static GstElementDetails play_on_demand_details = { "Play On Demand", - "Filter/Audio/Effect", - "Plays a stream at specific times, or when it receives a signal", - "Leif Morgan Johnson <leif@ambient.2y.net>" + "Filter/Editor/Audio", + "Schedule a stream to play at specific times, or when a signal is received", + "Leif Morgan Johnson <leif@ambient.2y.net>", }; @@ -218,18 +218,23 @@ play_on_demand_class_init (GstPlayOnDemandClass *klass) g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_MUTE, g_param_spec_boolean("mute", "Silence output", "Do not output any sound", FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_BUFFER_TIME, g_param_spec_float("buffer-time", "Buffer length in seconds", "Number of seconds of audio the buffer holds", 0.0, G_MAXFLOAT, GST_POD_BUFFER_TIME, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_MAX_PLAYS, g_param_spec_uint("max-plays", "Maximum simultaneous playbacks", "Maximum allowed number of simultaneous plays from the buffer", 1, G_MAXUINT, GST_POD_MAX_PLAYS, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TICK_RATE, g_param_spec_float("tick-rate", "Tick rate (ticks/second)", "The rate of musical ticks, the smallest time unit in a song", 0, G_MAXFLOAT, GST_POD_TICK_RATE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TOTAL_TICKS, g_param_spec_uint("total-ticks", "Total number of ticks", "Total number of ticks in the tick array", 1, G_MAXUINT, 1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TICKS, g_param_spec_pointer("ticks", "Ticks to play sample on", "An array of ticks (musical times) at which to play the sample", G_PARAM_READWRITE)); @@ -430,7 +435,8 @@ play_on_demand_loop (GstElement *elem) { GstPlayOnDemand *filter = GST_PLAYONDEMAND(elem); guint num_in, num_out, num_filter; - GstBuffer *in, *out; + GstData *in = NULL; + GstBuffer *out = NULL; static guint last_tick = 0; g_return_if_fail(filter != NULL); @@ -442,7 +448,7 @@ play_on_demand_loop (GstElement *elem) filter->bufpool = gst_buffer_pool_get_default(GST_POD_BUFPOOL_SIZE, GST_POD_BUFPOOL_NUM); - in = GST_BUFFER (gst_pad_pull(filter->sinkpad)); + in = (in == NULL && ! filter->eos) ? gst_pad_pull(filter->sinkpad) : NULL; if (filter->format == GST_PLAYONDEMAND_FORMAT_INT) { if (filter->width == 16) { diff --git a/gst/playondemand/gstplayondemand.h b/gst/playondemand/gstplayondemand.h index b73b5c2ad..8c7fa2123 100644 --- a/gst/playondemand/gstplayondemand.h +++ b/gst/playondemand/gstplayondemand.h @@ -22,21 +22,20 @@ #ifndef __GST_PLAYONDEMAND_H__ #define __GST_PLAYONDEMAND_H__ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif #include <gst/gst.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - +G_BEGIN_DECLS #define GST_TYPE_PLAYONDEMAND \ (gst_play_on_demand_get_type()) #define GST_PLAYONDEMAND(obj) \ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PLAYONDEMAND,GstPlayOnDemand)) #define GST_PLAYONDEMAND_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstPlayOnDemand)) + (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PLAYONDEMAND,GstPlayOnDemand)) #define GST_IS_PLAYONDEMAND(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAYONDEMAND)) #define GST_IS_PLAYONDEMAND_CLASS(obj) \ @@ -94,10 +93,6 @@ struct _GstPlayOnDemandClass { GType gst_play_on_demand_get_type(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS #endif /* __GST_PLAYONDEMAND_H__ */ |