+ further mucking about with the playondemand filter

Original commit message from CVS:
+ further mucking about with the playondemand filter
This commit is contained in:
Leif Johnson 2003-11-16 21:48:55 +00:00
parent 70ac550707
commit 531a3a6936
4 changed files with 57 additions and 64 deletions

View file

@ -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

View file

@ -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);

View file

@ -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) {

View file

@ -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__ */