mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 15:51:11 +00:00
+ further mucking about with the playondemand filter
Original commit message from CVS: + further mucking about with the playondemand filter
This commit is contained in:
parent
70ac550707
commit
531a3a6936
4 changed files with 57 additions and 64 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue