playondemand: remove unported plugin from 0.8

These days one would do the effect e.g. using gnonlin.
This commit is contained in:
Stefan Sauer 2011-11-22 09:11:35 +01:00
parent bae725ed1f
commit aa4b5b3bf5
6 changed files with 0 additions and 985 deletions

View file

@ -1 +0,0 @@
demo_mp3

View file

@ -1,19 +0,0 @@
plugin_LTLIBRARIES = libgstplayondemand.la
libgstplayondemand_la_SOURCES = gstplayondemand.c
libgstplayondemand_la_CFLAGS = $(GST_CFLAGS)
libgstplayondemand_la_LIBADD =
libgstplayondemand_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstplayondemand_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = gstplayondemand.h filter.func
if HAVE_GTK
noinst_PROGRAMS = demo_mp3
endif
demo_mp3_SOURCES = demo-mp3.c gstplayondemand.h
## putting GTK_CFLAGS first fixes a weird compilation error with GTK and XML
demo_mp3_CFLAGS = $(GTK_CFLAGS) $(GST_CFLAGS)
demo_mp3_LDFLAGS = $(GST_LIBS) $(GTK_LIBS)

View file

@ -1,187 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <glib.h>
#include <gtk/gtk.h>
#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, *dec, *pod, *sink, *pipeline;
GstClock *element_clock;
guint32 *beats;
void
played (GstElement * pod, gpointer data)
{
gint i;
g_print ("Played beat at %02u, beats are ",
(guint) (gst_clock_get_time (element_clock) / GST_SECOND *
(GTK_ADJUSTMENT (speed_adj))->value) % NUM_BEATS);
for (i = 0; i <= NUM_BEATS / 32; i++)
g_print ("%08x ", beats[i]);
g_print ("\n");
}
void
play (GtkButton * button, gpointer data)
{
g_signal_emit_by_name (G_OBJECT (pod), "play", NULL, NULL);
}
void
clear (GtkButton * button, gpointer data)
{
g_signal_emit_by_name (G_OBJECT (pod), "clear", NULL, NULL);
}
void
reset (GtkButton * button, gpointer data)
{
guint i;
g_signal_emit_by_name (G_OBJECT (pod), "reset", NULL, NULL);
for (i = 0; i < NUM_BEATS; i++)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (beat_button[i]), 0);
}
void
beat (GtkToggleButton * button, gpointer data)
{
guint b = GPOINTER_TO_UINT (data);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
beats[b / 32] |= 1 << (b % 32);
else
beats[b / 32] &= ~(1 << (b % 32));
}
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", TICK_RATE (adjustment->value),
NULL);
/*gst_clock_set_speed(element_clock, adjustment->value); */
}
void
setup_pipeline (gchar * filename)
{
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 (DEFAULT_AUDIOSINK, "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.0e-6, "max-plays", NUM_BEATS * 2, NULL);
g_object_get (G_OBJECT (pod), "ticks", &beats, NULL);
pipeline = gst_pipeline_new ("app");
gst_bin_add_many (GST_BIN (pipeline), src, dec, pod, sink, NULL);
gst_element_link_many (src, dec, pod, sink, NULL);
element_clock = gst_element_get_clock (GST_ELEMENT (sink));
gst_element_set_clock (GST_ELEMENT (pod), element_clock);
}
void
setup_gui (void)
{
guint i;
beat_button = g_new (GtkWidget *, NUM_BEATS);
/* initialize gui elements ... */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (window), 12);
vbox = gtk_vbox_new (TRUE, 0);
gtk_box_set_spacing (GTK_BOX (vbox), 12);
beat_box = gtk_hbox_new (TRUE, 0);
button_box = gtk_hbox_new (TRUE, 0);
play_button = gtk_button_new_with_label ("Play");
clear_button = gtk_button_new_with_label ("Reset Sound");
reset_button = gtk_button_new_with_label ("Reset All");
quit_button = gtk_button_new_with_label ("Quit");
for (i = 0; i < NUM_BEATS; i++)
beat_button[i] =
gtk_toggle_button_new_with_label (g_strdup_printf ("%2d", i + 1));
speed_adj = gtk_adjustment_new (1, 0.0, 10.0, 0.1, 1.0, 0.0);
speed_scale = gtk_hscale_new (GTK_ADJUSTMENT (speed_adj));
gtk_scale_set_digits (GTK_SCALE (speed_scale), 4);
gtk_range_set_update_policy (GTK_RANGE (speed_scale),
GTK_UPDATE_DISCONTINUOUS);
/* do the packing stuff ... */
gtk_window_set_default_size (GTK_WINDOW (window), 96, 96);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_box_pack_start (GTK_BOX (button_box), play_button, TRUE, TRUE, 2);
gtk_box_pack_start (GTK_BOX (button_box), clear_button, TRUE, TRUE, 2);
gtk_box_pack_start (GTK_BOX (button_box), reset_button, TRUE, TRUE, 2);
gtk_box_pack_start (GTK_BOX (button_box), quit_button, TRUE, TRUE, 2);
for (i = 0; i < NUM_BEATS; i++)
gtk_box_pack_start (GTK_BOX (beat_box), beat_button[i], TRUE, TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), button_box, TRUE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (vbox), beat_box, TRUE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (vbox), speed_scale, TRUE, FALSE, 2);
/* connect things ... */
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play), NULL);
g_signal_connect (G_OBJECT (clear_button), "clicked", G_CALLBACK (clear),
NULL);
g_signal_connect (G_OBJECT (reset_button), "clicked", G_CALLBACK (reset),
NULL);
g_signal_connect (G_OBJECT (quit_button), "clicked", gtk_main_quit, NULL);
g_signal_connect (G_OBJECT (pod), "played", G_CALLBACK (played), NULL);
g_signal_connect (G_OBJECT (speed_adj), "value_changed", G_CALLBACK (speed),
NULL);
for (i = 0; i < NUM_BEATS; i++)
g_signal_connect (G_OBJECT (beat_button[i]), "toggled", G_CALLBACK (beat),
GUINT_TO_POINTER (i));
/* show the gui. */
gtk_widget_show_all (window);
gtk_idle_add ((GtkFunction) gst_bin_iterate, pipeline);
}
int
main (int argc, char **argv)
{
gst_init (&argc, &argv);
gtk_init (&argc, &argv);
if (argc != 2) {
g_print ("usage: %s <mp3-filename>\n", argv[0]);
exit (-1);
}
setup_pipeline (argv[1]);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
setup_gui ();
gtk_main ();
g_free (beat_button);
return 0;
}

View file

@ -1,113 +0,0 @@
/* -*- C -*- */
_TYPE_ *data_in, *data_out, *filter_data;
filter_data = (_TYPE_ *) filter->buffer;
num_filter = filter->buffer_bytes / sizeof(_TYPE_);
do {
/* see if we've got any events coming through ... */
while (! filter->eos && in != NULL && GST_IS_EVENT (in)) {
GstEvent *event = GST_EVENT (in);
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
gst_data_unref (in);
in = NULL;
filter->eos = TRUE;
} else if ((GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS) ||
(GST_EVENT_TYPE (event) == GST_EVENT_FLUSH)) {
gst_data_unref (in);
in = NULL;
filter->eos = FALSE;
filter->write = 0;
} else {
gst_pad_push(filter->srcpad, in);
}
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 (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];
filter->write += j;
if (filter->write >= num_filter) filter->eos = TRUE;
out = GST_BUFFER (in);
} else {
out = gst_buffer_new_and_alloc (GST_POD_BUFPOOL_SIZE);
}
in = NULL;
/* check to see if we have to add new play pointers. */
if (filter->clock) {
register gint t, tick_offset;
guint total_ticks = filter->total_ticks;
guint current_tick = \
((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;
for (tick_offset -= 1, t = current_tick - tick_offset;
tick_offset >= 0;
tick_offset--, t--) {
if (t < 0) t += total_ticks;
if (filter->ticks[t / 32] & (1 << t % 32))
play_on_demand_add_play_pointer(
filter, filter->rate * tick_offset / filter->tick_rate);
}
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_);
for (k = 0; k < num_out; k++) data_out[k] = zero;
for (p = 0; p < filter->max_plays; p++) {
guint offset = filter->plays[p];
if (offset != G_MAXUINT) {
/* only copy audio data if the element's not muted. */
if (! filter->mute)
for (k = 0; (k < num_out) && (offset+k < num_filter); k++)
data_out[k] = CLAMP(data_out[k] + filter_data[offset+k], min, max);
/* update the play pointer. k > 0 even if the filter is muted. */
filter->plays[p] = (offset+k >= num_filter) ? G_MAXUINT : offset + k;
}
}
}
/* 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

@ -1,568 +0,0 @@
/* GStreamer
* Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <gst/gst.h>
#include <gst/audio/audio.h>
#include "gstplayondemand.h"
/* in these files, a 'tick' is a discrete unit of time, usually around the 1ms
* range. a tick is not divisible into smaller units of time. 1ms is probably
* way beyond what a real computer can actually keep track of, but hey ... */
/* some default values */
#define GST_POD_MAX_PLAYS 100 /* maximum simultaneous plays */
#define GST_POD_BUFFER_TIME 5.0 /* buffer length in seconds */
#define GST_POD_TICK_RATE 1e-6 /* ticks per second */
/* buffer pool fallback values ... use if no buffer pool is available */
#define GST_POD_BUFPOOL_SIZE 4096
#define GST_POD_BUFPOOL_NUM 6
static GstStaticPadTemplate play_on_demand_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS)
);
static GstStaticPadTemplate play_on_demand_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_AUDIO_INT_PAD_TEMPLATE_CAPS "; "
GST_AUDIO_FLOAT_STANDARD_PAD_TEMPLATE_CAPS)
);
/* GObject functionality */
static void play_on_demand_class_init (GstPlayOnDemandClass * klass);
static void play_on_demand_base_init (GstPlayOnDemandClass * klass);
static void play_on_demand_init (GstPlayOnDemand * filter);
static void play_on_demand_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void play_on_demand_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static void play_on_demand_finalize (GObject * object);
/* GStreamer functionality */
static GstPadLinkReturn play_on_demand_pad_link (GstPad * pad,
const GstCaps * caps);
static void play_on_demand_loop (GstElement * elem);
static void play_on_demand_set_clock (GstElement * elem, GstClock * clock);
/* signal handlers */
static void play_on_demand_play_handler (GstElement * elem);
static void play_on_demand_clear_handler (GstElement * elem);
static void play_on_demand_reset_handler (GstElement * elem);
/* utility functions */
static void play_on_demand_add_play_pointer (GstPlayOnDemand * filter,
guint pos);
static void play_on_demand_resize_buffer (GstPlayOnDemand * filter);
GType
gst_play_on_demand_get_type (void)
{
static GType play_on_demand_type = 0;
if (!play_on_demand_type) {
static const GTypeInfo play_on_demand_info = {
sizeof (GstPlayOnDemandClass),
(GBaseInitFunc) play_on_demand_base_init,
NULL,
(GClassInitFunc) play_on_demand_class_init,
NULL,
NULL,
sizeof (GstPlayOnDemand),
0,
(GInstanceInitFunc) play_on_demand_init,
};
play_on_demand_type = g_type_register_static (GST_TYPE_ELEMENT,
"GstPlayOnDemand", &play_on_demand_info, 0);
}
return play_on_demand_type;
}
/* signals and properties */
enum
{
/* add signals here */
PLAYED_SIGNAL,
STOPPED_SIGNAL,
PLAY_SIGNAL,
CLEAR_SIGNAL,
RESET_SIGNAL,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_MUTE,
PROP_BUFFER_TIME,
PROP_MAX_PLAYS,
PROP_TICK_RATE,
PROP_TOTAL_TICKS,
PROP_TICKS
};
static guint gst_pod_filter_signals[LAST_SIGNAL] = { 0 };
static GstElementClass *parent_class = NULL;
static void
play_on_demand_base_init (GstPlayOnDemandClass * klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&play_on_demand_src_template));
gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&play_on_demand_sink_template));
gst_element_class_set_details_simple (element_class, "Play On Demand",
"Filter/Editor/Audio",
"Schedule a stream to play at specific times, or when a signal is received",
"Leif Morgan Johnson <leif@ambient.2y.net>");
}
static void
play_on_demand_class_init (GstPlayOnDemandClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
gst_pod_filter_signals[PLAYED_SIGNAL] =
g_signal_new ("played", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPlayOnDemandClass, played),
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gst_pod_filter_signals[STOPPED_SIGNAL] =
g_signal_new ("stopped", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPlayOnDemandClass, stopped),
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gst_pod_filter_signals[PLAY_SIGNAL] =
g_signal_new ("play", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPlayOnDemandClass, play),
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gst_pod_filter_signals[CLEAR_SIGNAL] =
g_signal_new ("clear", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPlayOnDemandClass, clear),
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
gst_pod_filter_signals[RESET_SIGNAL] =
g_signal_new ("reset", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstPlayOnDemandClass, reset),
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
klass->play = play_on_demand_play_handler;
klass->clear = play_on_demand_clear_handler;
klass->reset = play_on_demand_reset_handler;
parent_class = g_type_class_peek_parent (klass);
gobject_class->set_property = play_on_demand_set_property;
gobject_class->get_property = play_on_demand_get_property;
gobject_class->finalize = play_on_demand_finalize;
gstelement_class->set_clock = play_on_demand_set_clock;
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_PARAM_STATIC_STRINGS));
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_PARAM_STATIC_STRINGS));
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_PARAM_STATIC_STRINGS));
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_PARAM_STATIC_STRINGS));
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_PARAM_STATIC_STRINGS));
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 | G_PARAM_STATIC_STRINGS));
}
static void
play_on_demand_init (GstPlayOnDemand * filter)
{
filter->srcpad =
gst_pad_new_from_static_template (&play_on_demand_src_template, "src");
filter->sinkpad =
gst_pad_new_from_static_template (&play_on_demand_sink_template, "sink");
gst_pad_set_link_function (filter->sinkpad, play_on_demand_pad_link);
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
gst_element_set_loop_function (GST_ELEMENT (filter), play_on_demand_loop);
filter->clock = NULL;
filter->rate = 0;
filter->ticks = g_new (guint32, filter->total_ticks / 32 + 1);
filter->plays = g_new (guint, filter->max_plays);
play_on_demand_resize_buffer (filter);
play_on_demand_reset_handler (GST_ELEMENT (filter));
}
static void
play_on_demand_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstPlayOnDemand *filter;
register guint i;
guint new_size, min_size, *new_plays;
guint *new_ticks;
g_return_if_fail (GST_IS_PLAYONDEMAND (object));
filter = GST_PLAYONDEMAND (object);
switch (prop_id) {
case PROP_MUTE:
filter->mute = g_value_get_boolean (value);
break;
case PROP_BUFFER_TIME:
filter->buffer_time = g_value_get_float (value);
play_on_demand_resize_buffer (filter);
/* clear out now-invalid play pointers */
for (i = 0; i < filter->max_plays; i++)
filter->plays[i] = G_MAXUINT;
break;
case PROP_MAX_PLAYS:
new_size = g_value_get_uint (value);
min_size = (new_size < filter->max_plays) ? new_size : filter->max_plays;
new_plays = g_new (guint, new_size);
for (i = 0; i < min_size; i++)
new_plays[i] = filter->plays[i];
for (i = min_size; i < new_size; i++)
new_plays[i] = G_MAXUINT;
g_free (filter->plays);
filter->plays = new_plays;
filter->max_plays = new_size;
break;
case PROP_TICK_RATE:
filter->tick_rate = g_value_get_float (value);
break;
case PROP_TOTAL_TICKS:
new_size = g_value_get_uint (value);
min_size =
(new_size < filter->total_ticks) ? new_size : filter->total_ticks;
new_ticks = g_new (guint32, new_size / 32 + 1);
for (i = 0; i <= min_size / 32; i++)
new_ticks[i] = filter->ticks[i];
for (i = min_size / 32 + 1; i <= new_size / 32; i++)
new_ticks[i] = 0;
g_free (filter->ticks);
filter->ticks = new_ticks;
filter->total_ticks = new_size;
break;
case PROP_TICKS:
new_ticks = (guint *) g_value_get_pointer (value);
if (new_ticks) {
g_free (filter->ticks);
filter->ticks = new_ticks;
}
break;
default:
break;
}
}
static void
play_on_demand_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstPlayOnDemand *filter;
g_return_if_fail (GST_IS_PLAYONDEMAND (object));
filter = GST_PLAYONDEMAND (object);
switch (prop_id) {
case PROP_MUTE:
g_value_set_boolean (value, filter->mute);
break;
case PROP_BUFFER_TIME:
g_value_set_float (value, filter->buffer_time);
break;
case PROP_MAX_PLAYS:
g_value_set_uint (value, filter->max_plays);
break;
case PROP_TICK_RATE:
g_value_set_float (value, filter->tick_rate);
break;
case PROP_TOTAL_TICKS:
g_value_set_uint (value, filter->total_ticks);
break;
case PROP_TICKS:
g_value_set_pointer (value, (gpointer) filter->ticks);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
play_on_demand_finalize (GObject * object)
{
GstPlayOnDemand *filter = GST_PLAYONDEMAND (object);
g_free (filter->ticks);
g_free (filter->plays);
g_free (filter->buffer);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GstPadLinkReturn
play_on_demand_pad_link (GstPad * pad, const GstCaps * caps)
{
const gchar *mimetype;
GstPlayOnDemand *filter;
GstStructure *structure;
g_return_val_if_fail (caps != NULL, GST_PAD_LINK_DELAYED);
g_return_val_if_fail (pad != NULL, GST_PAD_LINK_DELAYED);
filter = GST_PLAYONDEMAND (GST_PAD_PARENT (pad));
structure = gst_caps_get_structure (caps, 0);
mimetype = gst_structure_get_name (structure);
gst_structure_get_int (structure, "rate", &filter->rate);
gst_structure_get_int (structure, "channels", &filter->channels);
if (strcmp (mimetype, "audio/x-raw-int") == 0) {
filter->format = GST_PLAYONDEMAND_FORMAT_INT;
gst_structure_get_int (structure, "width", &filter->width);
} else if (strcmp (mimetype, "audio/x-raw-float") == 0) {
filter->format = GST_PLAYONDEMAND_FORMAT_FLOAT;
}
play_on_demand_resize_buffer (filter);
return gst_pad_try_set_caps (filter->srcpad, caps);
}
inline static void
play_on_demand_add_play_pointer (GstPlayOnDemand * filter, guint pos)
{
register guint i;
if (filter->rate && ((filter->buffer_time * filter->rate) > pos)) {
for (i = 0; i < filter->max_plays; i++) {
if (filter->plays[i] == G_MAXUINT) {
filter->plays[i] = pos;
/* emit a signal to indicate a sample being played */
g_signal_emit (filter, gst_pod_filter_signals[PLAYED_SIGNAL], 0);
break;
}
}
}
}
static void
play_on_demand_loop (GstElement * elem)
{
GstPlayOnDemand *filter = GST_PLAYONDEMAND (elem);
guint num_in, num_out, num_filter;
GstData *in = NULL;
GstBuffer *out = NULL;
static guint last_tick = 0;
g_return_if_fail (filter != NULL);
g_return_if_fail (GST_IS_PLAYONDEMAND (filter));
in = (in == NULL && !filter->eos) ? gst_pad_pull (filter->sinkpad) : NULL;
if (filter->format == GST_PLAYONDEMAND_FORMAT_INT) {
if (filter->width == 16) {
gint16 min = 0xffff;
gint16 max = 0x7fff;
gint16 zero = 0;
#define _TYPE_ gint16
#include "filter.func"
#undef _TYPE_
} else if (filter->width == 8) {
gint8 min = 0xff;
gint8 max = 0x7f;
gint8 zero = 0;
#define _TYPE_ gint8
#include "filter.func"
#undef _TYPE_
}
} else if (filter->format == GST_PLAYONDEMAND_FORMAT_FLOAT) {
gfloat min = -1.0;
gfloat max = 1.0;
gfloat zero = 0.0;
#define _TYPE_ gfloat
#include "filter.func"
#undef _TYPE_
}
}
static void
play_on_demand_set_clock (GstElement * elem, GstClock * clock)
{
GstPlayOnDemand *filter;
g_return_if_fail (elem != NULL);
g_return_if_fail (GST_IS_PLAYONDEMAND (elem));
filter = GST_PLAYONDEMAND (elem);
filter->clock = clock;
}
static void
play_on_demand_play_handler (GstElement * elem)
{
GstPlayOnDemand *filter;
g_return_if_fail (elem != NULL);
g_return_if_fail (GST_IS_PLAYONDEMAND (elem));
filter = GST_PLAYONDEMAND (elem);
play_on_demand_add_play_pointer (filter, 0);
}
static void
play_on_demand_clear_handler (GstElement * elem)
{
GstPlayOnDemand *filter;
register guint i;
g_return_if_fail (elem != NULL);
g_return_if_fail (GST_IS_PLAYONDEMAND (elem));
filter = GST_PLAYONDEMAND (elem);
filter->write = 0;
filter->eos = FALSE;
for (i = 0; i < filter->max_plays; i++)
filter->plays[i] = G_MAXUINT;
for (i = 0; i < filter->buffer_bytes; i++)
filter->buffer[i] = (gchar) 0;
}
static void
play_on_demand_reset_handler (GstElement * elem)
{
GstPlayOnDemand *filter;
register guint i;
play_on_demand_clear_handler (elem);
g_return_if_fail (elem != NULL);
g_return_if_fail (GST_IS_PLAYONDEMAND (elem));
filter = GST_PLAYONDEMAND (elem);
for (i = 0; i <= filter->total_ticks / 32; i++)
filter->ticks[i] = 0;
}
static void
play_on_demand_resize_buffer (GstPlayOnDemand * filter)
{
register guint i;
guint new_size, min_size;
gchar *new_buffer;
/* use a default sample rate of 44100, 1 channel, 1 byte per sample if caps
haven't been set yet */
new_size = (guint) filter->buffer_time;
new_size *= (filter->rate) ? filter->rate : 44100;
new_size *= (filter->channels) ? filter->channels : 1;
if (filter->format && filter->format == GST_PLAYONDEMAND_FORMAT_FLOAT)
new_size *= sizeof (gfloat);
else
new_size *= (filter->width) ? filter->width / 8 : 1;
min_size =
(new_size < filter->buffer_bytes) ? new_size : filter->buffer_bytes;
new_buffer = g_new (gchar, new_size);
for (i = 0; i < min_size; i++)
new_buffer[i] = filter->buffer[i];
for (i = min_size; i < new_size; i++)
new_buffer[i] = (gchar) 0;
g_free (filter->buffer);
filter->buffer = new_buffer;
filter->buffer_bytes = new_size;
}
static gboolean
plugin_init (GstPlugin * plugin)
{
return gst_element_register (plugin, "playondemand",
GST_RANK_NONE, GST_TYPE_PLAYONDEMAND);
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"playondemand",
"Plays a stream at specific times, or when it receives a signal",
plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)

View file

@ -1,97 +0,0 @@
/* -*- c-basic-offset: 2 -*-
* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_PLAYONDEMAND_H__
#define __GST_PLAYONDEMAND_H__
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gst/gst.h>
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_PLAYONDEMAND,GstPlayOnDemandClass))
#define GST_IS_PLAYONDEMAND(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PLAYONDEMAND))
#define GST_IS_PLAYONDEMAND_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PLAYONDEMAND))
typedef struct _GstPlayOnDemand GstPlayOnDemand;
typedef struct _GstPlayOnDemandClass GstPlayOnDemandClass;
typedef enum _GstPlayOnDemandFormat GstPlayOnDemandFormat;
enum _GstPlayOnDemandFormat {
GST_PLAYONDEMAND_FORMAT_INT,
GST_PLAYONDEMAND_FORMAT_FLOAT
};
struct _GstPlayOnDemand {
GstElement element;
GstPad *sinkpad, *srcpad;
GstClock *clock;
/* filter properties */
gboolean mute;
gfloat buffer_time;
guint max_plays;
gfloat tick_rate;
guint total_ticks;
guint32 *ticks;
/* internal buffer info */
gchar *buffer;
guint buffer_bytes;
gboolean eos;
/* play pointers == internal buffer offsets for producing output sound */
guint *plays;
guint write;
/* audio format info (used to calculate buffer_samples) */
GstPlayOnDemandFormat format;
guint rate;
guint channels;
guint width;
};
struct _GstPlayOnDemandClass {
GstElementClass parent_class;
void (*play) (GstElement *elem);
void (*clear) (GstElement *elem);
void (*reset) (GstElement *elem);
void (*played) (GstElement *elem);
void (*stopped) (GstElement *elem);
};
GType gst_play_on_demand_get_type(void);
G_END_DECLS
#endif /* __GST_PLAYONDEMAND_H__ */