diff options
author | Tim-Philipp Müller <tim@centricular.net> | 2012-12-14 14:51:19 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.net> | 2012-12-15 13:37:23 +0000 |
commit | 7ab936fa7eab2cb3d4035e1cd761e3f5384289a9 (patch) | |
tree | fcd2343e0b57321fb7fdd06286d97bcf06d275aa | |
parent | 8b2641805f792fbf51999f881f9feb33f7853609 (diff) |
scaletempo: remove scaletempo plugin, moved to -good
https://bugzilla.gnome.org/show_bug.cgi?id=687262
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | docs/plugins/Makefile.am | 1 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins-docs.sgml | 2 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins-sections.txt | 14 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins.args | 40 | ||||
-rw-r--r-- | docs/plugins/gst-plugins-bad-plugins.hierarchy | 1 | ||||
-rw-r--r-- | docs/plugins/inspect/plugin-scaletempo.xml | 34 | ||||
-rw-r--r-- | gst-plugins-bad.spec.in | 1 | ||||
-rw-r--r-- | gst/scaletempo/Makefile.am | 29 | ||||
-rw-r--r-- | gst/scaletempo/gstscaletempo.c | 808 | ||||
-rw-r--r-- | gst/scaletempo/gstscaletempo.h | 52 | ||||
-rw-r--r-- | gst/scaletempo/gstscaletempoplugin.c | 74 | ||||
-rw-r--r-- | tests/examples/Makefile.am | 4 | ||||
-rw-r--r-- | tests/examples/scaletempo/.gitignore | 1 | ||||
-rw-r--r-- | tests/examples/scaletempo/Makefile.am | 11 | ||||
-rw-r--r-- | tests/examples/scaletempo/demo-gui.c | 1279 | ||||
-rw-r--r-- | tests/examples/scaletempo/demo-gui.h | 60 | ||||
-rw-r--r-- | tests/examples/scaletempo/demo-main.c | 95 | ||||
-rw-r--r-- | tests/examples/scaletempo/demo-player.c | 756 | ||||
-rw-r--r-- | tests/examples/scaletempo/demo-player.h | 71 |
22 files changed, 6 insertions, 3336 deletions
diff --git a/Android.mk b/Android.mk index 1d719b642..bde4c0c36 100644 --- a/Android.mk +++ b/Android.mk @@ -32,7 +32,6 @@ GST_PLUGINS_BAD_BUILT_SOURCES := \ gst/tta/Android.mk \ gst/videosignal/Android.mk \ gst/coloreffects/Android.mk \ - gst/scaletempo/Android.mk \ gst/jpegformat/Android.mk \ gst/freeze/Android.mk \ gst/geometrictransform/Android.mk \ @@ -125,7 +124,6 @@ CONFIGURE_TARGETS += gst-plugins-bad-configure -include $(GST_PLUGINS_BAD_TOP)/gst/tta/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/videosignal/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/coloreffects/Android.mk --include $(GST_PLUGINS_BAD_TOP)/gst/scaletempo/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/jpegformat/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/freeze/Android.mk -include $(GST_PLUGINS_BAD_TOP)/gst/geometrictransform/Android.mk diff --git a/Makefile.am b/Makefile.am index f8baa9327..0a0ca1d80 100644 --- a/Makefile.am +++ b/Makefile.am @@ -55,6 +55,7 @@ CRUFT_FILES = \ $(top_builddir)/gst/mpeg4videoparse/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/qtmux/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/rtpvp8/.libs/*.{so,dll,DLL,dylib} \ + $(top_builddir)/gst/scaletempo/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/selector/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/shapewipe/.libs/*.{so,dll,DLL,dylib} \ $(top_builddir)/gst/valve/.libs/*.{so,dll,DLL,dylib} \ @@ -70,6 +71,7 @@ CRUFT_FILES = \ $(top_builddir)/tests/check/elements/valve \ $(top_builddir)/tests/check/pipelines/metadata \ $(top_builddir)/tests/examples/jack/jack_client \ + $(top_builddir)/tests/examples/scaletempo/scaletempo-demo \ $(top_builddir)/tests/examples/switch/switcher \ $(top_builddir)/tests/icles/output-selector-test \ $(top_builddir)/tests/icles/test-oss4 \ @@ -84,10 +86,12 @@ CRUFT_DIRS = \ $(top_srcdir)/gst/mpeg4videoparse \ $(top_srcdir)/gst/qtmux \ $(top_srcdir)/gst/rtpvp8 \ + $(top_srcdir)/gst/scaletempo \ $(top_srcdir)/gst/selector \ $(top_srcdir)/gst/shapewipe \ $(top_srcdir)/gst/valve \ $(top_srcdir)/gst-libs/gst/baseparse \ + $(top_srcdir)/tests/examples/scaletempo \ $(top_srcdir)/tests/examples/shapewipe \ $(top_srcdir)/tests/examples/switch \ $(top_srcdir)/tests/examples/jack \ diff --git a/configure.ac b/configure.ac index ff49c457b..be2036ad0 100644 --- a/configure.ac +++ b/configure.ac @@ -378,7 +378,6 @@ AG_GST_CHECK_PLUGIN(rawparse) AG_GST_CHECK_PLUGIN(real) AG_GST_CHECK_PLUGIN(removesilence) AG_GST_CHECK_PLUGIN(rtpmux) -AG_GST_CHECK_PLUGIN(scaletempo) AG_GST_CHECK_PLUGIN(sdi) AG_GST_CHECK_PLUGIN(sdp) AG_GST_CHECK_PLUGIN(segmentclip) @@ -2122,7 +2121,6 @@ gst/rawparse/Makefile gst/real/Makefile gst/removesilence/Makefile gst/rtpmux/Makefile -gst/scaletempo/Makefile gst/sdi/Makefile gst/sdp/Makefile gst/segmentclip/Makefile @@ -2182,7 +2180,6 @@ tests/examples/Makefile tests/examples/camerabin2/Makefile tests/examples/directfb/Makefile tests/examples/mxf/Makefile -tests/examples/scaletempo/Makefile tests/examples/opencv/Makefile tests/examples/uvch264/Makefile tests/icles/Makefile diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 5a9e74020..0813ea96a 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -166,7 +166,6 @@ EXTRA_HFILES = \ $(top_srcdir)/gst/rawparse/gstvideoparse.h \ $(top_srcdir)/gst/rtpmux/gstrtpmux.h \ $(top_srcdir)/gst/rtpmux/gstrtpdtmfmux.h \ - $(top_srcdir)/gst/scaletempo/gstscaletempo.h \ $(top_srcdir)/gst/sdp/gstsdpdemux.h \ $(top_srcdir)/gst/speed/gstspeed.h \ $(top_srcdir)/gst/stereo/gststereo.h \ diff --git a/docs/plugins/gst-plugins-bad-plugins-docs.sgml b/docs/plugins/gst-plugins-bad-plugins-docs.sgml index 314c50c15..925e61e79 100644 --- a/docs/plugins/gst-plugins-bad-plugins-docs.sgml +++ b/docs/plugins/gst-plugins-bad-plugins-docs.sgml @@ -75,7 +75,6 @@ <xi:include href="xml/element-rtpdtmfsrc.xml" /> <xi:include href="xml/element-rtpdtmfmux.xml" /> <xi:include href="xml/element-rtpmux.xml" /> - <xi:include href="xml/element-scaletempo.xml" /> <xi:include href="xml/element-shmsink.xml" /> <xi:include href="xml/element-shmsrc.xml" /> <xi:include href="xml/element-sdpdemux.xml" /> @@ -137,7 +136,6 @@ <xi:include href="xml/plugin-rawparse.xml" /> <xi:include href="xml/plugin-rtmp.xml" /> <xi:include href="xml/plugin-rtpmux.xml" /> - <xi:include href="xml/plugin-scaletempo.xml" /> <xi:include href="xml/plugin-sdp.xml" /> <xi:include href="xml/plugin-shm.xml" /> <xi:include href="xml/plugin-soundtouch.xml" /> diff --git a/docs/plugins/gst-plugins-bad-plugins-sections.txt b/docs/plugins/gst-plugins-bad-plugins-sections.txt index 805ff41d2..74ab5792e 100644 --- a/docs/plugins/gst-plugins-bad-plugins-sections.txt +++ b/docs/plugins/gst-plugins-bad-plugins-sections.txt @@ -1239,20 +1239,6 @@ gst_rtp_mux_plugin_init </SECTION> <SECTION> -<FILE>element-scaletempo</FILE> -<TITLE>scaletempo</TITLE> -GstScaletempo -<SUBSECTION Standard> -GstScaletempoClass -GST_IS_SCALETEMPO -GST_IS_SCALETEMPO_CLASS -GST_SCALETEMPO -GST_SCALETEMPO_CLASS -GST_TYPE_SCALETEMPO -gst_scaletempo_get_type -</SECTION> - -<SECTION> <FILE>element-sdlaudiosink</FILE> <TITLE>sdlaudiosink</TITLE> GstSDLAudioSink diff --git a/docs/plugins/gst-plugins-bad-plugins.args b/docs/plugins/gst-plugins-bad-plugins.args index 683ff98f9..58c7c1e70 100644 --- a/docs/plugins/gst-plugins-bad-plugins.args +++ b/docs/plugins/gst-plugins-bad-plugins.args @@ -22324,46 +22324,6 @@ </ARG> <ARG> -<NAME>GstScaletempo::overlap</NAME> -<TYPE>gdouble</TYPE> -<RANGE>[0,1]</RANGE> -<FLAGS>rw</FLAGS> -<NICK>Overlap Length</NICK> -<BLURB>Percentage of stride to overlap.</BLURB> -<DEFAULT>0.2</DEFAULT> -</ARG> - -<ARG> -<NAME>GstScaletempo::rate</NAME> -<TYPE>gdouble</TYPE> -<RANGE>[-2.14748e+09,2.14748e+09]</RANGE> -<FLAGS>r</FLAGS> -<NICK>Playback Rate</NICK> -<BLURB>Current playback rate.</BLURB> -<DEFAULT>1</DEFAULT> -</ARG> - -<ARG> -<NAME>GstScaletempo::search</NAME> -<TYPE>guint</TYPE> -<RANGE><= 500</RANGE> -<FLAGS>rw</FLAGS> -<NICK>Search Length</NICK> -<BLURB>Length in milliseconds to search for best overlap position.</BLURB> -<DEFAULT>14</DEFAULT> -</ARG> - -<ARG> -<NAME>GstScaletempo::stride</NAME> -<TYPE>guint</TYPE> -<RANGE>[1,5000]</RANGE> -<FLAGS>rw</FLAGS> -<NICK>Stride Length</NICK> -<BLURB>Length in milliseconds to output each stride.</BLURB> -<DEFAULT>30</DEFAULT> -</ARG> - -<ARG> <NAME>GstPcapParse::dst-ip</NAME> <TYPE>gchar*</TYPE> <RANGE></RANGE> diff --git a/docs/plugins/gst-plugins-bad-plugins.hierarchy b/docs/plugins/gst-plugins-bad-plugins.hierarchy index 4629078d4..db9e8f505 100644 --- a/docs/plugins/gst-plugins-bad-plugins.hierarchy +++ b/docs/plugins/gst-plugins-bad-plugins.hierarchy @@ -85,7 +85,6 @@ GObject GstDtmfDetect GstRGB2Bayer GstRemoveSilence - GstScaletempo GstVideoFilter GstBurn GstChromaHold diff --git a/docs/plugins/inspect/plugin-scaletempo.xml b/docs/plugins/inspect/plugin-scaletempo.xml deleted file mode 100644 index 8eee247eb..000000000 --- a/docs/plugins/inspect/plugin-scaletempo.xml +++ /dev/null @@ -1,34 +0,0 @@ -<plugin> - <name>scaletempo</name> - <description>Scale audio tempo in sync with playback rate</description> - <filename>../../gst/scaletempo/.libs/libgstscaletempo.so</filename> - <basename>libgstscaletempo.so</basename> - <version>1.1.0.1</version> - <license>LGPL</license> - <source>gst-plugins-bad</source> - <package>GStreamer</package> - <origin>http://gstreamer.freedesktop.org/</origin> - <elements> - <element> - <name>scaletempo</name> - <longname>Scaletempo</longname> - <class>Filter/Effect/Rate</class> - <description>Sync audio tempo with playback rate</description> - <author>Rov Juvano <rovjuvano@users.sourceforge.net></author> - <pads> - <caps> - <name>sink</name> - <direction>sink</direction> - <presence>always</presence> - <details>audio/x-raw, format=(string)F32LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string)S16LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</details> - </caps> - <caps> - <name>src</name> - <direction>source</direction> - <presence>always</presence> - <details>audio/x-raw, format=(string)F32LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]; audio/x-raw, format=(string)S16LE, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ]</details> - </caps> - </pads> - </element> - </elements> -</plugin>
\ No newline at end of file diff --git a/gst-plugins-bad.spec.in b/gst-plugins-bad.spec.in index d6ced9b67..6d0497fc6 100644 --- a/gst-plugins-bad.spec.in +++ b/gst-plugins-bad.spec.in @@ -250,7 +250,6 @@ make ERROR_CFLAGS='' ERROR_CXXFLAGS='' %{_libdir}/gstreamer-%{majorminor}/libgstaccurip.so %{_libdir}/gstreamer-%{majorminor}/libgstfieldanalysis.so %{_libdir}/gstreamer-%{majorminor}/libgstmxf.so -%{_libdir}/gstreamer-%{majorminor}/libgstscaletempo.so %{_libdir}/gstreamer-%{majorminor}/libgstsubenc.so %{_libdir}/libgstbasecamerabinsrc-1.0.so.0.2.0 diff --git a/gst/scaletempo/Makefile.am b/gst/scaletempo/Makefile.am deleted file mode 100644 index 25f02d9fc..000000000 --- a/gst/scaletempo/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -plugin_LTLIBRARIES = libgstscaletempo.la - -# sources used to compile this plug-in -libgstscaletempo_la_SOURCES = gstscaletempoplugin.c gstscaletempo.c - -# flags used to compile this plugin -# add other _CFLAGS and _LIBS as needed -libgstscaletempo_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) -libgstscaletempo_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstaudio-@GST_API_VERSION@ \ - $(GST_LIBS) $(GST_BASE_LIBS) -libgstscaletempo_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstscaletempo_la_LIBTOOLFLAGS = --tag=disable-static - -# headers we need but don't want installed -noinst_HEADERS = gstscaletempo.h - -Android.mk: Makefile.am $(BUILT_SOURCES) - androgenizer \ - -:PROJECT libgstscaletempo -:SHARED libgstscaletempo \ - -:TAGS eng debug \ - -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \ - -:SOURCES $(libgstscaletempo_la_SOURCES) \ - -:CFLAGS $(DEFS) $(DEFAULT_INCLUDES) $(libgstscaletempo_la_CFLAGS) \ - -:LDFLAGS $(libgstscaletempo_la_LDFLAGS) \ - $(libgstscaletempo_la_LIBADD) \ - -ldl \ - -:PASSTHROUGH LOCAL_ARM_MODE:=arm \ - LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \ - > $@ diff --git a/gst/scaletempo/gstscaletempo.c b/gst/scaletempo/gstscaletempo.c deleted file mode 100644 index de58927c6..000000000 --- a/gst/scaletempo/gstscaletempo.c +++ /dev/null @@ -1,808 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -/** - * SECTION:element-scaletempo - * - * Scale tempo while maintaining pitch - * (WSOLA-like technique with cross correlation) - * Inspired by SoundTouch library by Olli Parviainen - * - * Use Sceletempo to apply playback rates without the chipmunk effect. - * - * <refsect2> - * <title>Example pipelines</title> - * <para> - * |[ - * filesrc location=media.ext ! decodebin name=d \ - * d. ! queue ! audioconvert ! audioresample ! scaletempo ! audioconvert ! audioresample ! autoaudiosink \ - * d. ! queue ! videoconvert ! autovideosink - * ]| - * OR - * |[ - * playbin uri=... audio_sink="scaletempo ! audioconvert ! audioresample ! autoaudiosink" - * ]| - * When an application sends a seek event with rate != 1.0, Scaletempo applies - * the rate change by scaling the tempo without scaling the pitch. - * - * Scaletempo works by producing audio in constant sized chunks - * (#GstScaletempo:stride) but consuming chunks proportional to the playback - * rate. - * - * Scaletempo then smooths the output by blending the end of one stride with - * the next (#GstScaletempo:overlap). - * - * Scaletempo smooths the overlap further by searching within the input buffer - * for the best overlap position. Scaletempo uses a statistical cross - * correlation (roughly a dot-product). Scaletempo consumes most of its CPU - * cycles here. One can use the #GstScaletempo:search propery to tune how far - * the algoritm looks. - * </para> - * </refsect2> - */ - -/* - * Note: frame = audio key unit (i.e. one sample for each channel) - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gst/gst.h> -#include <gst/base/gstbasetransform.h> -#include <gst/audio/audio.h> -#include <string.h> /* for memset */ - -#include "gstscaletempo.h" - -GST_DEBUG_CATEGORY_STATIC (gst_scaletempo_debug); -#define GST_CAT_DEFAULT gst_scaletempo_debug - -/* Filter signals and args */ -enum -{ - LAST_SIGNAL -}; - -enum -{ - PROP_0, - PROP_RATE, - PROP_STRIDE, - PROP_OVERLAP, - PROP_SEARCH, -}; - -#define SUPPORTED_CAPS \ -GST_STATIC_CAPS ( \ - GST_AUDIO_CAPS_MAKE (GST_AUDIO_NE (F32)) "; " \ - GST_AUDIO_CAPS_MAKE (GST_AUDIO_NE (S16)) \ -) - -static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - SUPPORTED_CAPS); - -static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - SUPPORTED_CAPS); - -#define DEBUG_INIT(bla) GST_DEBUG_CATEGORY_INIT (gst_scaletempo_debug, "scaletempo", 0, "scaletempo element"); - -#define gst_scaletempo_parent_class parent_class -G_DEFINE_TYPE_WITH_CODE (GstScaletempo, gst_scaletempo, - GST_TYPE_BASE_TRANSFORM, DEBUG_INIT (0)); - -struct _GstScaletempoPrivate -{ - gdouble scale; - /* parameters */ - guint ms_stride; - gdouble percent_overlap; - guint ms_search; - /* caps */ - gboolean use_int; - guint samples_per_frame; /* AKA number of channels */ - guint bytes_per_sample; - guint bytes_per_frame; - guint sample_rate; - /* stride */ - gdouble frames_stride_scaled; - gdouble frames_stride_error; - guint bytes_stride; - gdouble bytes_stride_scaled; - guint bytes_queue_max; - guint bytes_queued; - guint bytes_to_slide; - gint8 *buf_queue; - /* overlap */ - guint samples_overlap; - guint samples_standing; - guint bytes_overlap; - guint bytes_standing; - gpointer buf_overlap; - gpointer table_blend; - void (*output_overlap) (GstScaletempo * scaletempo, gpointer out_buf, - guint bytes_off); - /* best overlap */ - guint frames_search; - gpointer buf_pre_corr; - gpointer table_window; - guint (*best_overlap_offset) (GstScaletempo * scaletempo); - /* gstreamer */ - gint64 segment_start; - GstClockTime latency; - /* threads */ - gboolean reinit_buffers; -}; -#define GST_SCALETEMPO_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_SCALETEMPO, GstScaletempoPrivate)) - - -static guint -best_overlap_offset_float (GstScaletempo * scaletempo) -{ - GstScaletempoPrivate *p = scaletempo->priv; - gfloat *pw, *po, *ppc, *search_start; - gfloat best_corr = G_MININT; - guint best_off = 0; - gint i, off; - - pw = p->table_window; - po = p->buf_overlap; - po += p->samples_per_frame; - ppc = p->buf_pre_corr; - for (i = p->samples_per_frame; i < p->samples_overlap; i++) { - *ppc++ = *pw++ * *po++; - } - - search_start = (gfloat *) p->buf_queue + p->samples_per_frame; - for (off = 0; off < p->frames_search; off++) { - gfloat corr = 0; - gfloat *ps = search_start; - ppc = p->buf_pre_corr; - for (i = p->samples_per_frame; i < p->samples_overlap; i++) { - corr += *ppc++ * *ps++; - } - if (corr > best_corr) { - best_corr = corr; - best_off = off; - } - search_start += p->samples_per_frame; - } - - return best_off * p->bytes_per_frame; -} - -/* buffer padding for loop optimization: sizeof(gint32) * (loop_size - 1) */ -#define UNROLL_PADDING (4*3) -static guint -best_overlap_offset_s16 (GstScaletempo * scaletempo) -{ - GstScaletempoPrivate *p = scaletempo->priv; - gint32 *pw, *ppc; - gint16 *po, *search_start; - gint64 best_corr = G_MININT64; - guint best_off = 0; - guint off; - glong i; - - pw = p->table_window; - po = p->buf_overlap; - po += p->samples_per_frame; - ppc = p->buf_pre_corr; - for (i = p->samples_per_frame; i < p->samples_overlap; i++) { - *ppc++ = (*pw++ * *po++) >> 15; - } - - search_start = (gint16 *) p->buf_queue + p->samples_per_frame; - for (off = 0; off < p->frames_search; off++) { - gint64 corr = 0; - gint16 *ps = search_start; - ppc = p->buf_pre_corr; - ppc += p->samples_overlap - p->samples_per_frame; - ps += p->samples_overlap - p->samples_per_frame; - i = -((glong) p->samples_overlap - (glong) p->samples_per_frame); - do { - corr += ppc[i + 0] * ps[i + 0]; - corr += ppc[i + 1] * ps[i + 1]; - corr += ppc[i + 2] * ps[i + 2]; - corr += ppc[i + 3] * ps[i + 3]; - i += 4; - } while (i < 0); - if (corr > best_corr) { - best_corr = corr; - best_off = off; - } - search_start += p->samples_per_frame; - } - - return best_off * p->bytes_per_frame; -} - -static void -output_overlap_float (GstScaletempo * scaletempo, - gpointer buf_out, guint bytes_off) -{ - GstScaletempoPrivate *p = scaletempo->priv; - gfloat *pout = buf_out; - gfloat *pb = p->table_blend; - gfloat *po = p->buf_overlap; - gfloat *pin = (gfloat *) (p->buf_queue + bytes_off); - gint i; - for (i = 0; i < p->samples_overlap; i++) { - *pout++ = *po - *pb++ * (*po - *pin++); - po++; - } -} - -static void -output_overlap_s16 (GstScaletempo * scaletempo, - gpointer buf_out, guint bytes_off) -{ - GstScaletempoPrivate *p = scaletempo->priv; - gint16 *pout = buf_out; - gint32 *pb = p->table_blend; - gint16 *po = p->buf_overlap; - gint16 *pin = (gint16 *) (p->buf_queue + bytes_off); - gint i; - for (i = 0; i < p->samples_overlap; i++) { - *pout++ = *po - ((*pb++ * (*po - *pin++)) >> 16); - po++; - } -} - -static guint -fill_queue (GstScaletempo * scaletempo, GstBuffer * buf_in, guint offset) -{ - GstScaletempoPrivate *p = scaletempo->priv; - guint bytes_in = gst_buffer_get_size (buf_in) - offset; - guint offset_unchanged = offset; - GstMapInfo map; - - gst_buffer_map (buf_in, &map, GST_MAP_READ); - if (p->bytes_to_slide > 0) { - if (p->bytes_to_slide < p->bytes_queued) { - guint bytes_in_move = p->bytes_queued - p->bytes_to_slide; - memmove (p->buf_queue, p->buf_queue + p->bytes_to_slide, bytes_in_move); - p->bytes_to_slide = 0; - p->bytes_queued = bytes_in_move; - } else { - guint bytes_in_skip; - p->bytes_to_slide -= p->bytes_queued; - bytes_in_skip = MIN (p->bytes_to_slide, bytes_in); - p->bytes_queued = 0; - p->bytes_to_slide -= bytes_in_skip; - offset += bytes_in_skip; - bytes_in -= bytes_in_skip; - } - } - - if (bytes_in > 0) { - guint bytes_in_copy = MIN (p->bytes_queue_max - p->bytes_queued, bytes_in); - memcpy (p->buf_queue + p->bytes_queued, map.data + offset, bytes_in_copy); - p->bytes_queued += bytes_in_copy; - offset += bytes_in_copy; - } - gst_buffer_unmap (buf_in, &map); - - return offset - offset_unchanged; -} - -static void -reinit_buffers (GstScaletempo * scaletempo) -{ - GstScaletempoPrivate *p = scaletempo->priv; - gint i, j; - guint frames_overlap; - guint new_size; - GstClockTime latency; - - guint frames_stride = p->ms_stride * p->sample_rate / 1000.0; - p->bytes_stride = frames_stride * p->bytes_per_frame; - - /* overlap */ - frames_overlap = frames_stride * p->percent_overlap; - if (frames_overlap < 1) { /* if no overlap */ - p->bytes_overlap = 0; - p->bytes_standing = p->bytes_stride; - p->samples_standing = p->bytes_standing / p->bytes_per_sample; - p->output_overlap = NULL; - } else { - guint prev_overlap = p->bytes_overlap; - p->bytes_overlap = frames_overlap * p->bytes_per_frame; - p->samples_overlap = frames_overlap * p->samples_per_frame; - p->bytes_standing = p->bytes_stride - p->bytes_overlap; - p->samples_standing = p->bytes_standing / p->bytes_per_sample; - p->buf_overlap = g_realloc (p->buf_overlap, p->bytes_overlap); - p->table_blend = g_realloc (p->table_blend, p->samples_overlap * 4); /* sizeof (gint32|gfloat) */ - if (p->bytes_overlap > prev_overlap) { - memset ((guint8 *) p->buf_overlap + prev_overlap, 0, - p->bytes_overlap - prev_overlap); - } - if (p->use_int) { - gint32 *pb = p->table_blend; - gint64 blend = 0; - for (i = 0; i < frames_overlap; i++) { - gint32 v = blend / frames_overlap; - for (j = 0; j < p->samples_per_frame; j++) { - *pb++ = v; - } - blend += 65535; /* 2^16 */ - } - p->output_overlap = output_overlap_s16; - } else { - gfloat *pb = p->table_blend; - gfloat t = (gfloat) frames_overlap; - for (i = 0; i < frames_overlap; i++) { - gfloat v = i / t; - for (j = 0; j < p->samples_per_frame; j++) { - *pb++ = v; - } - } - p->output_overlap = output_overlap_float; - } - } - - /* best overlap */ - p->frames_search = - (frames_overlap <= 1) ? 0 : p->ms_search * p->sample_rate / 1000.0; - if (p->frames_search < 1) { /* if no search */ - p->best_overlap_offset = NULL; - } else { - guint bytes_pre_corr = (p->samples_overlap - p->samples_per_frame) * 4; /* sizeof (gint32|gfloat) */ - p->buf_pre_corr = - g_realloc (p->buf_pre_corr, bytes_pre_corr + UNROLL_PADDING); - p->table_window = g_realloc (p->table_window, bytes_pre_corr); - if (p->use_int) { - gint64 t = frames_overlap; - gint32 n = 8589934588LL / (t * t); /* 4 * (2^31 - 1) / t^2 */ - gint32 *pw; - - memset ((guint8 *) p->buf_pre_corr + bytes_pre_corr, 0, UNROLL_PADDING); - pw = p->table_window; - for (i = 1; i < frames_overlap; i++) { - gint32 v = (i * (t - i) * n) >> 15; - for (j = 0; j < p->samples_per_frame; j++) { - *pw++ = v; - } - } - p->best_overlap_offset = best_overlap_offset_s16; - } else { - gfloat *pw = p->table_window; - for (i = 1; i < frames_overlap; i++) { - gfloat v = i * (frames_overlap - i); - for (j = 0; j < p->samples_per_frame; j++) { - *pw++ = v; - } - } - p->best_overlap_offset = best_overlap_offset_float; - } - } - - new_size = - (p->frames_search + frames_stride + frames_overlap) * p->bytes_per_frame; - if (p->bytes_queued > new_size) { - if (p->bytes_to_slide > p->bytes_queued) { - p->bytes_to_slide -= p->bytes_queued; - p->bytes_queued = 0; - } else { - guint new_queued = MIN (p->bytes_queued - p->bytes_to_slide, new_size); - memmove (p->buf_queue, - p->buf_queue + p->bytes_queued - new_queued, new_queued); - p->bytes_to_slide = 0; - p->bytes_queued = new_queued; - } - } - - p->bytes_queue_max = new_size; - p->buf_queue = g_realloc (p->buf_queue, p->bytes_queue_max); - - latency = - gst_util_uint64_scale (p->bytes_queue_max, GST_SECOND, - p->bytes_per_frame * p->sample_rate); - if (p->latency != latency) { - p->latency = latency; - gst_element_post_message (GST_ELEMENT (scaletempo), - gst_message_new_latency (GST_OBJECT (scaletempo))); - } - - p->bytes_stride_scaled = p->bytes_stride * p->scale; - p->frames_stride_scaled = p->bytes_stride_scaled / p->bytes_per_frame; - - GST_DEBUG - ("%.3f scale, %.3f stride_in, %i stride_out, %i standing, %i overlap, %i search, %i queue, %s mode", - p->scale, p->frames_stride_scaled, - (gint) (p->bytes_stride / p->bytes_per_frame), - (gint) (p->bytes_standing / p->bytes_per_frame), - (gint) (p->bytes_overlap / p->bytes_per_frame), p->frames_search, - (gint) (p->bytes_queue_max / p->bytes_per_frame), - (p->use_int ? "s16" : "float")); - - p->reinit_buffers = FALSE; -} - - -/* GstBaseTransform vmethod implementations */ -static GstFlowReturn -gst_scaletempo_transform (GstBaseTransform * trans, - GstBuffer * inbuf, GstBuffer * outbuf) -{ - GstScaletempo *scaletempo = GST_SCALETEMPO (trans); - GstScaletempoPrivate *p = scaletempo->priv; - gint8 *pout; - guint offset_in, bytes_out; - GstMapInfo omap; - GstClockTime timestamp; - - gst_buffer_map (outbuf, &omap, GST_MAP_WRITE); - pout = (gint8 *) omap.data; - offset_in = fill_queue (scaletempo, inbuf, 0); - bytes_out = 0; - while (p->bytes_queued >= p->bytes_queue_max) { - guint bytes_off = 0; - gdouble frames_to_slide; - guint frames_to_stride_whole; - - /* output stride */ - if (p->output_overlap) { - if (p->best_overlap_offset) { - bytes_off = p->best_overlap_offset (scaletempo); - } - p->output_overlap (scaletempo, pout, bytes_off); - } - memcpy (pout + p->bytes_overlap, - p->buf_queue + bytes_off + p->bytes_overlap, p->bytes_standing); - pout += p->bytes_stride; - bytes_out += p->bytes_stride; - - /* input stride */ - memcpy (p->buf_overlap, - p->buf_queue + bytes_off + p->bytes_stride, p->bytes_overlap); - frames_to_slide = p->frames_stride_scaled + p->frames_stride_error; - frames_to_stride_whole = (gint) frames_to_slide; - p->bytes_to_slide = frames_to_stride_whole * p->bytes_per_frame; - p->frames_stride_error = frames_to_slide - frames_to_stride_whole; - - offset_in += fill_queue (scaletempo, inbuf, offset_in); - } - - gst_buffer_unmap (outbuf, &omap); - - timestamp = GST_BUFFER_TIMESTAMP (inbuf) - p->segment_start; - if (timestamp < p->latency) - timestamp = 0; - else - timestamp -= p->latency; - GST_BUFFER_TIMESTAMP (outbuf) = timestamp / p->scale + p->segment_start; - GST_BUFFER_DURATION (outbuf) = - gst_util_uint64_scale (bytes_out, GST_SECOND, - p->bytes_per_frame * p->sample_rate); - gst_buffer_set_size (outbuf, bytes_out); - - return GST_FLOW_OK; -} - -static gboolean -gst_scaletempo_transform_size (GstBaseTransform * trans, - GstPadDirection direction, - GstCaps * caps, gsize size, GstCaps * othercaps, gsize * othersize) -{ - if (direction == GST_PAD_SINK) { - GstScaletempo *scaletempo = GST_SCALETEMPO (trans); - GstScaletempoPrivate *priv = scaletempo->priv; - gint bytes_to_out; - - if (priv->reinit_buffers) - reinit_buffers (scaletempo); - - bytes_to_out = size + priv->bytes_queued - priv->bytes_to_slide; - if (bytes_to_out < (gint) priv->bytes_queue_max) { - *othersize = 0; - } else { - /* while (total_buffered - stride_length * n >= queue_max) n++ */ - *othersize = priv->bytes_stride * ((guint) ( - (bytes_to_out - priv->bytes_queue_max + - /* rounding protection */ priv->bytes_per_frame) - / priv->bytes_stride_scaled) + 1); - } - - return TRUE; - } - return FALSE; -} - -static gboolean -gst_scaletempo_sink_event (GstBaseTransform * trans, GstEvent * event) -{ - if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) { - GstScaletempo *scaletempo = GST_SCALETEMPO (trans); - GstScaletempoPrivate *priv = scaletempo->priv; - GstSegment segment; - - gst_event_copy_segment (event, &segment); - - if (priv->scale != segment.rate) { - if (ABS (segment.rate - 1.0) < 1e-10) { - priv->scale = 1.0; - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (scaletempo), - TRUE); - } else { - gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (scaletempo), - FALSE); - priv->scale = segment.rate; - priv->bytes_stride_scaled = priv->bytes_stride * priv->scale; - priv->frames_stride_scaled = - priv->bytes_stride_scaled / priv->bytes_per_frame; - GST_DEBUG ("%.3f scale, %.3f stride_in, %i stride_out", priv->scale, - priv->frames_stride_scaled, - (gint) (priv->bytes_stride / priv->bytes_per_frame)); - - priv->bytes_to_slide = 0; - } - } - - if (priv->scale != 1.0) { - priv->segment_start = segment.start; - segment.applied_rate = priv->scale; - segment.rate = 1.0; - gst_event_unref (event); - - if (segment.stop != -1) { - segment.stop = (segment.stop - segment.start) / segment.applied_rate + - segment.start; - } - - event = gst_event_new_segment (&segment); - gst_pad_push_event (GST_BASE_TRANSFORM_SRC_PAD (trans), event); - return TRUE; - } - } - return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event); -} - -static gboolean -gst_scaletempo_set_caps (GstBaseTransform * trans, - GstCaps * incaps, GstCaps * outcaps) -{ - GstScaletempo *scaletempo = GST_SCALETEMPO (trans); - GstScaletempoPrivate *priv = scaletempo->priv; - - gint width, bps, nch, rate; - gboolean use_int; - GstAudioInfo info; - - if (!gst_audio_info_from_caps (&info, incaps)) - return FALSE; - - nch = GST_AUDIO_INFO_CHANNELS (&info); - rate = GST_AUDIO_INFO_RATE (&info); - width = GST_AUDIO_INFO_WIDTH (&info); - use_int = GST_AUDIO_INFO_IS_INTEGER (&info); - - bps = width / 8; - - GST_DEBUG ("caps: %" GST_PTR_FORMAT ", %d bps", incaps, bps); - - if (rate != priv->sample_rate - || nch != priv->samples_per_frame - || bps != priv->bytes_per_sample || use_int != priv->use_int) { - priv->sample_rate = rate; - priv->samples_per_frame = nch; - priv->bytes_per_sample = bps; - priv->bytes_per_frame = nch * bps; - priv->use_int = use_int; - priv->reinit_buffers = TRUE; - } - - return TRUE; -} - -static gboolean -gst_scaletempo_query (GstBaseTransform * trans, GstPadDirection direction, - GstQuery * query) -{ - GstScaletempo *scaletempo = GST_SCALETEMPO (trans); - GstScaletempoPrivate *p = scaletempo->priv; - - if (direction == GST_PAD_SRC) { - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_LATENCY:{ - GstPad *peer; - gboolean res; - - if ((peer = gst_pad_get_peer (GST_BASE_TRANSFORM_SINK_PAD (trans)))) { - if ((res = gst_pad_query (peer, query))) { - GstClockTime min, max; - gboolean live; - - gst_query_parse_latency (query, &live, &min, &max); - - GST_DEBUG_OBJECT (scaletempo, "Peer latency: min %" - GST_TIME_FORMAT " max %" GST_TIME_FORMAT, - GST_TIME_ARGS (min), GST_TIME_ARGS (max)); - - /* add our own latency */ - GST_DEBUG_OBJECT (scaletempo, "Our latency: %" GST_TIME_FORMAT, - GST_TIME_ARGS (p->latency)); - min += p->latency; - if (max != GST_CLOCK_TIME_NONE) - max += p->latency; - - GST_DEBUG_OBJECT (scaletempo, "Calculated total latency : min %" - GST_TIME_FORMAT " max %" GST_TIME_FORMAT, - GST_TIME_ARGS (min), GST_TIME_ARGS (max)); - gst_query_set_latency (query, live, min, max); - } - gst_object_unref (peer); - } - - return TRUE; - break; - } - default:{ - return GST_BASE_TRANSFORM_CLASS (parent_class)->query (trans, direction, - query); - break; - } - } - } else { - return GST_BASE_TRANSFORM_CLASS (parent_class)->query (trans, direction, - query); - } -} - -/* GObject vmethod implementations */ -static void -gst_scaletempo_get_property (GObject * object, - guint prop_id, GValue * value, GParamSpec * pspec) -{ - GstScaletempo *scaletempo = GST_SCALETEMPO (object); - GstScaletempoPrivate *priv = scaletempo->priv; - - switch (prop_id) { - case PROP_RATE: - g_value_set_double (value, priv->scale); - break; - case PROP_STRIDE: - g_value_set_uint (value, priv->ms_stride); - break; - case PROP_OVERLAP: - g_value_set_double (value, priv->percent_overlap); - break; - case PROP_SEARCH: - g_value_set_uint (value, priv->ms_search); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_scaletempo_set_property (GObject * object, - guint prop_id, const GValue * value, GParamSpec * pspec) -{ - GstScaletempo *scaletempo = GST_SCALETEMPO (object); - GstScaletempoPrivate *priv = scaletempo->priv; - - switch (prop_id) { - case PROP_STRIDE:{ - guint new_value = g_value_get_uint (value); - if (priv->ms_stride != new_value) { - priv->ms_stride = new_value; - priv->reinit_buffers = TRUE; - } - break; - } - case PROP_OVERLAP:{ - gdouble new_value = g_value_get_double (value); - if (priv->percent_overlap != new_value) { - priv->percent_overlap = new_value; - priv->reinit_buffers = TRUE; - } - break; - } - case PROP_SEARCH:{ - guint new_value = g_value_get_uint (value); - if (priv->ms_search != new_value) { - priv->ms_search = new_value; - priv->reinit_buffers = TRUE; - } - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_scaletempo_class_init (GstScaletempoClass * klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - GstBaseTransformClass *basetransform_class = GST_BASE_TRANSFORM_CLASS (klass); - - g_type_class_add_private (klass, sizeof (GstScaletempoPrivate)); - - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_scaletempo_get_property); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_scaletempo_set_property); - - g_object_class_install_property (gobject_class, PROP_RATE, - g_param_spec_double ("rate", "Playback Rate", "Current playback rate", - G_MININT, G_MAXINT, 1.0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_STRIDE, - g_param_spec_uint ("stride", "Stride Length", - "Length in milliseconds to output each stride", 1, 5000, 30, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_OVERLAP, - g_param_spec_double ("overlap", "Overlap Length", - "Percentage of stride to overlap", 0, 1, .2, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - g_object_class_install_property (gobject_class, PROP_SEARCH, - g_param_spec_uint ("search", "Search Length", - "Length in milliseconds to search for best overlap position", 0, 500, - 14, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); - - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&src_template)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sink_template)); - gst_element_class_set_static_metadata (gstelement_class, "Scaletempo", - "Filter/Effect/Rate", - "Sync audio tempo with playback rate", - "Rov Juvano <rovjuvano@users.sourceforge.net>"); - - basetransform_class->sink_event = - GST_DEBUG_FUNCPTR (gst_scaletempo_sink_event); - basetransform_class->set_caps = GST_DEBUG_FUNCPTR (gst_scaletempo_set_caps); - basetransform_class->transform_size = - GST_DEBUG_FUNCPTR (gst_scaletempo_transform_size); - basetransform_class->transform = GST_DEBUG_FUNCPTR (gst_scaletempo_transform); - basetransform_class->query = GST_DEBUG_FUNCPTR (gst_scaletempo_query); -} - -static void -gst_scaletempo_init (GstScaletempo * scaletempo) -{ - GstScaletempoPrivate *priv; - - scaletempo->priv = priv = GST_SCALETEMPO_GET_PRIVATE (scaletempo); - - /* defaults */ - priv->ms_stride = 30; - priv->percent_overlap = .2; - priv->ms_search = 14; - - /* uninitialized */ - priv->scale = 0; - priv->sample_rate = 0; - priv->frames_stride_error = 0; - priv->bytes_stride = 0; - priv->bytes_queued = 0; - priv->bytes_to_slide = 0; - priv->segment_start = 0; -} diff --git a/gst/scaletempo/gstscaletempo.h b/gst/scaletempo/gstscaletempo.h deleted file mode 100644 index 7adff4308..000000000 --- a/gst/scaletempo/gstscaletempo.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net> - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __GST_SCALETEMPO_H__ -#define __GST_SCALETEMPO_H__ - -#include <gst/gst.h> -#include <gst/base/gstbasetransform.h> - -G_BEGIN_DECLS -#define GST_TYPE_SCALETEMPO (gst_scaletempo_get_type()) -#define GST_SCALETEMPO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_SCALETEMPO, GstScaletempo)) -#define GST_SCALETEMPO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_SCALETEMPO, GstScaletempoClass)) -#define GST_IS_SCALETEMPO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_SCALETEMPO)) -#define GST_IS_SCALETEMPO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_SCALETEMPO)) -typedef struct _GstScaletempo GstScaletempo; -typedef struct _GstScaletempoClass GstScaletempoClass; -typedef struct _GstScaletempoPrivate GstScaletempoPrivate; - -struct _GstScaletempo -{ - GstBaseTransform element; - - GstScaletempoPrivate *priv; -}; - -struct _GstScaletempoClass -{ - GstBaseTransformClass parent_class; -}; - -GType gst_scaletempo_get_type (void); - -G_END_DECLS -#endif /* __GST_SCALETEMPO_H__ */ diff --git a/gst/scaletempo/gstscaletempoplugin.c b/gst/scaletempo/gstscaletempoplugin.c deleted file mode 100644 index e5a62217e..000000000 --- a/gst/scaletempo/gstscaletempoplugin.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <gst/gst.h> -#include "gstscaletempo.h" - -/* entry point to initialize the plug-in - * initialize the plug-in itself - * register the element factories and pad templates - * register the features - * - * exchange the string 'plugin' with your elemnt name - */ - -static gboolean -plugin_init (GstPlugin * plugin) -{ - return gst_element_register (plugin, "scaletempo", GST_RANK_NONE, - GST_TYPE_SCALETEMPO); -} - -/* this is the structure that gstreamer looks for to register plugins - * - * exchange the strings 'plugin' and 'Template plugin' with you plugin name and - * description - */ -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, - scaletempo, "Scale audio tempo in sync with playback rate", - plugin_init, VERSION, "LGPL", "GStreamer", - "http://gstreamer.freedesktop.org/") diff --git a/tests/examples/Makefile.am b/tests/examples/Makefile.am index d166a6605..3db2210e6 100644 --- a/tests/examples/Makefile.am +++ b/tests/examples/Makefile.am @@ -5,7 +5,7 @@ UVCH264_DIR= endif if HAVE_GTK -GTK_EXAMPLES=mxf scaletempo camerabin2 $(UVCH264_DIR) +GTK_EXAMPLES=mxf camerabin2 $(UVCH264_DIR) else GTK_EXAMPLES= endif @@ -19,6 +19,6 @@ endif OPENCV_EXAMPLES=opencv SUBDIRS= $(DIRECTFB_DIR) $(GTK_EXAMPLES) $(OPENCV_EXAMPLES) -DIST_SUBDIRS= camerabin2 directfb mxf scaletempo opencv uvch264 +DIST_SUBDIRS= camerabin2 directfb mxf opencv uvch264 include $(top_srcdir)/common/parallel-subdirs.mak diff --git a/tests/examples/scaletempo/.gitignore b/tests/examples/scaletempo/.gitignore deleted file mode 100644 index 1c56e1447..000000000 --- a/tests/examples/scaletempo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -scaletempo-demo diff --git a/tests/examples/scaletempo/Makefile.am b/tests/examples/scaletempo/Makefile.am deleted file mode 100644 index 9bb25714c..000000000 --- a/tests/examples/scaletempo/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -noinst_PROGRAMS = scaletempo-demo - -# FIXME 0.11: ignore GValueArray warnings for now until this is sorted -ERROR_CFLAGS= - -scaletempo_demo_SOURCES = demo-main.c demo-player.c demo-gui.c -scaletempo_demo_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(GTK_CFLAGS) -scaletempo_demo_LDFLAGS = $(GST_PLUGINS_BASE_LIBS) $(GST_LIBS) $(GTK_LIBS) - -noinst_HEADERS = demo-player.h demo-gui.h - diff --git a/tests/examples/scaletempo/demo-gui.c b/tests/examples/scaletempo/demo-gui.c deleted file mode 100644 index 0339108e7..000000000 --- a/tests/examples/scaletempo/demo-gui.c +++ /dev/null @@ -1,1279 +0,0 @@ -/* demo-gui.c - * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex - * with newer GLib versions (>= 2.31.0) */ -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#include <gst/glib-compat-private.h> -#include <gtk/gtk.h> -#include <glib/gprintf.h> -#include <math.h> -#include "demo-gui.h" - -#undef G_LOG_DOMAIN -#define G_LOG_DOMAIN "demo-gui" - -enum -{ - SIGNAL_ERROR, - SIGNAL_QUITING, - LAST_SIGNAL -}; -static guint demo_gui_signals[LAST_SIGNAL] = { 0 }; - -enum -{ - PROP_0, -}; - -typedef struct _DemoGuiPrivate -{ - DemoPlayer *player; - GList *uris; - GList *now_playing; - gboolean is_playing; - GtkWidget *window; - GtkEntry *rate_entry; - GtkStatusbar *status_bar; - gint position_updater_id; - GtkRange *seek_range; - GtkLabel *amount_played; - GtkLabel *amount_to_play; - GtkAction *play_action; - GtkAction *pause_action; - GtkAction *open_file; - GtkAction *playlist_next; -} DemoGuiPrivate; - -#define DEMO_GUI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEMO_TYPE_GUI, DemoGuiPrivate)) - -/* forward declarations */ -static GValueArray *build_gvalue_array (guint n_values, ...); - -/* Handlers for status bar and seek bar */ -static int -pop_status_bar (gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - GtkStatusbar *sb = - GTK_STATUSBAR (g_value_get_object (g_value_array_get_nth (gvalues, 0))); - guint msg_id = g_value_get_uint (g_value_array_get_nth (gvalues, 1)); - - gtk_statusbar_remove (sb, 0, msg_id); - return FALSE; -} - -#define DEFAULT_STATUS_BAR_TIMEOUT 2 -static void -status_bar_printf (GtkStatusbar * sb, guint seconds, gchar const *format, ...) -{ - va_list args; - gchar msg[80]; - guint msg_id; - - va_start (args, format); - g_vsnprintf (msg, 80, format, args); - va_end (args); - - msg_id = gtk_statusbar_push (sb, 0, msg); - g_timeout_add (2000, pop_status_bar, - build_gvalue_array (2, G_TYPE_OBJECT, sb, G_TYPE_UINT, msg_id)); -} - -#define PRINTF_TIME_FORMAT "u:%02u:%02u" -#define PRINTF_TIME_ARGS(t) \ - (t >= 0) ? (guint) ((t) / (60 * 60)) : 99, \ - (t >= 0) ? (guint) (((t) / (60)) % 60) : 99, \ - (t >= 0) ? (guint) ((t) % 60) : 99 - -static gchar * -demo_gui_seek_bar_format (GtkScale * scale, gdouble value, gpointer data) -{ - return g_strdup_printf ("%" PRINTF_TIME_FORMAT, - PRINTF_TIME_ARGS ((gint64) value)); -} - -static gboolean -update_position (gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - gchar pos_str[16], dur_str[16]; - gint pos = demo_player_get_position (priv->player); - - if (pos > 0) { - gint dur = demo_player_get_duration (priv->player); - - g_snprintf (pos_str, 16, "%" PRINTF_TIME_FORMAT, PRINTF_TIME_ARGS (pos)); - if (dur > 0) { - g_snprintf (dur_str, 16, "-%" PRINTF_TIME_FORMAT, - PRINTF_TIME_ARGS (dur - pos)); - } else { - dur = pos; - g_sprintf (dur_str, "-??:??:??"); - } - if (dur > 0) - gtk_range_set_range (GTK_RANGE (priv->seek_range), 0, (gdouble) dur); - gtk_range_set_value (GTK_RANGE (priv->seek_range), (gdouble) pos); - } else { - g_sprintf (pos_str, "??:??:??"); - g_sprintf (dur_str, "-??:??:??"); - } - gtk_label_set_text (GTK_LABEL (priv->amount_played), pos_str); - gtk_label_set_text (GTK_LABEL (priv->amount_to_play), dur_str); - - return priv->is_playing; -} - - -static gboolean -demo_gui_seek_bar_change (GtkRange * range, - GtkScrollType scroll, gdouble value, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - gint new_second = (gint) value; - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Seeking to %i second", new_second); - demo_player_seek_to (priv->player, new_second); - - return FALSE; -} - - -/* Callbacks for actions */ -static void -demo_gui_do_change_rate (GtkAction * action, gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - DemoGui *gui = g_value_get_object (g_value_array_get_nth (gvalues, 0)); - gdouble scale_amount = - g_value_get_double (g_value_array_get_nth (gvalues, 1)); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Changing rate by %3.2lf", scale_amount); - - demo_player_scale_rate (priv->player, scale_amount); -} - -static void -demo_gui_do_set_rate (GtkAction * action, gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - DemoGui *gui = g_value_get_object (g_value_array_get_nth (gvalues, 0)); - gdouble new_rate = g_value_get_double (g_value_array_get_nth (gvalues, 1)); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Setting rate to %3.2lf", new_rate); - - demo_player_set_rate (priv->player, new_rate); -} - -static gboolean -demo_gui_do_rate_entered (GtkWidget * widget, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - gchar *err = NULL; - const gchar *text = gtk_entry_get_text (GTK_ENTRY (widget)); - double new_rate = g_strtod (text, &err); - - if (*err) { - gtk_widget_error_bell (priv->window); - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Invalid rate: %s", text); - return TRUE; - } - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Setting rate to %3.2lf", new_rate); - - demo_player_set_rate (priv->player, new_rate); - return FALSE; -} - -static void -demo_gui_do_toggle_advanced (GtkAction * action, gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - DemoGui *gui = - DEMO_GUI (g_value_get_object (g_value_array_get_nth (gvalues, 0))); - GtkWidget *stride_ui = - GTK_WIDGET (g_value_get_object (g_value_array_get_nth (gvalues, 1))); - GtkWidget *overlap_ui = - GTK_WIDGET (g_value_get_object (g_value_array_get_nth (gvalues, 2))); - GtkWidget *search_ui = - GTK_WIDGET (g_value_get_object (g_value_array_get_nth (gvalues, 3))); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - gboolean active; - - status_bar_printf (priv->status_bar, 1, "Toggling advanced mode"); - - active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - gtk_widget_set_sensitive (stride_ui, active); - gtk_widget_set_sensitive (overlap_ui, active); - gtk_widget_set_sensitive (search_ui, active); -} - -static void -demo_gui_do_toggle_disabled (GtkAction * action, gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - DemoGui *gui = - DEMO_GUI (g_value_get_object (g_value_array_get_nth (gvalues, 0))); - GtkAction *advanced_action = - GTK_ACTION (g_value_get_object (g_value_array_get_nth (gvalues, 1))); - GtkWidget *advanced_ui = - GTK_WIDGET (g_value_get_object (g_value_array_get_nth (gvalues, 2))); - - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - gboolean active; - - status_bar_printf (priv->status_bar, 1, "Toggling disabled"); - - active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); - gtk_action_set_sensitive (GTK_ACTION (advanced_action), !active); - gtk_widget_set_sensitive (GTK_WIDGET (advanced_ui), !active); - g_object_set (G_OBJECT (priv->player), "disabled", active, NULL); -} - -static void -demo_gui_do_seek (GtkAction * action, gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - DemoGui *gui = - DEMO_GUI (g_value_get_object (g_value_array_get_nth (gvalues, 0))); - gint seconds = g_value_get_int (g_value_array_get_nth (gvalues, 1)); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Requesting seek by %i seconds", seconds); - - demo_player_seek_by (priv->player, seconds); -} - -static void -demo_gui_do_play (GtkAction * action, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - if (priv->is_playing) { - g_signal_emit (gui, demo_gui_signals[SIGNAL_ERROR], 0, "Already playing"); - return; - } - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Requesting playback start"); - - demo_player_play (priv->player); -} - -static void -demo_gui_do_pause (GtkAction * action, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - if (!priv->is_playing) { - g_signal_emit (gui, demo_gui_signals[SIGNAL_ERROR], 0, "Already paused"); - return; - } - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Requesting playback pause"); - - demo_player_pause (priv->player); -} - -static void -demo_gui_do_play_pause (GtkAction * action, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Reqesting playback toggle"); - - if (priv->is_playing) - gtk_action_activate (priv->pause_action); - else - gtk_action_activate (priv->play_action); -} - -static void -demo_gui_do_open_file (GtkAction * action, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - GtkWidget *dialog = gtk_file_chooser_dialog_new ("Open File", - GTK_WINDOW (priv->window), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { - char *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - GError *err = NULL; - - g_list_free (priv->uris); - priv->uris = NULL; - priv->now_playing = NULL; - demo_player_load_uri (priv->player, g_filename_to_uri (filename, NULL, - &err)); - g_free (filename); - } - gtk_widget_destroy (dialog); -} - -static void -demo_gui_do_playlist_prev (GtkAction * action, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - if (priv->now_playing) { - if (priv->now_playing->prev) { - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Playlist previous"); - priv->now_playing = priv->now_playing->prev; - } else { - priv->now_playing = NULL; - gtk_widget_error_bell (priv->window); - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Beginning of playlist"); - return; - } - } else if (priv->uris) { - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Playlist previous: wrap"); - priv->now_playing = g_list_last (priv->uris); - } else { - gtk_action_activate (priv->open_file); - return; - } - - demo_player_load_uri (priv->player, priv->now_playing->data); -} - -static void -demo_gui_do_playlist_next (GtkAction * action, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - if (priv->now_playing) { - if (priv->now_playing->next) { - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Playlist next"); - priv->now_playing = priv->now_playing->next; - } else { - priv->now_playing = NULL; - gtk_widget_error_bell (priv->window); - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "End of playlist"); - return; - } - } else if (priv->uris) { - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Playlist next: wrap"); - priv->now_playing = priv->uris; - } else { - gtk_action_activate (priv->open_file); - return; - } - - demo_player_load_uri (priv->player, priv->now_playing->data); -} - -static void -demo_gui_do_about_dialog (GtkAction * action, gpointer data) -{ - static const gchar *authors[] = - { "Rov Juvano <rovjuvano@users.sourceforge.net>", NULL }; - - gtk_show_about_dialog (NULL, - "program-name", "gst-scaletempo-demo", - "version", VERSION, - "authors", authors, - "license", "This program is free software: you can redistribute it and/or modify\n\ -it under the terms of the GNU General Public License as published by\n\ -the Free Software Foundation, either version 3 of the License, or\n\ -(at your option) any later version.\n\ -\n\ -This program is distributed in the hope that it will be useful,\n\ -but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ -GNU General Public License for more details.\n\ -\n\ -You should have received a copy of the GNU General Public License\n\ -along with this program. If not, see <http://www.gnu.org/licenses/>.", "title", "About gst-scaletempo-demo", NULL); -} - -static void -demo_gui_do_quit (gpointer source, gpointer data) -{ - gtk_main_quit (); - g_signal_emit (DEMO_GUI (data), demo_gui_signals[SIGNAL_QUITING], 0, NULL); -} - -static gboolean -demo_gui_request_set_stride (GtkSpinButton * spinbutton, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - guint new_stride = gtk_spin_button_get_value_as_int (spinbutton); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Reqesting setting stride to %u ms", new_stride); - g_object_set (G_OBJECT (priv->player), "stride", new_stride, NULL); - return TRUE; -} - -static gboolean -demo_gui_request_set_overlap (GtkSpinButton * spinbutton, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - gdouble new_overlap = gtk_spin_button_get_value_as_int (spinbutton); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Requesting setting overlap to %2.0lf%%", new_overlap); - g_object_set (G_OBJECT (priv->player), "overlap", new_overlap / 100.0, NULL); - return TRUE; -} - -static gboolean -demo_gui_request_set_search (GtkSpinButton * spinbutton, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - guint new_search = gtk_spin_button_get_value_as_int (spinbutton); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Requesting setting search to %u ms", new_search); - g_object_set (G_OBJECT (priv->player), "search", new_search, NULL); - return TRUE; -} - - -/* Callbacks from signals */ -static void -demo_gui_rate_changed (DemoPlayer * player, gdouble new_rate, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - gchar e[6]; - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Rate changed to %3.2lf", new_rate); - - g_snprintf (e, 6, "%3.2f", new_rate); - gtk_entry_set_text (GTK_ENTRY (priv->rate_entry), e); -} - -static void -demo_gui_playing_started (DemoPlayer * player, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - priv->is_playing = TRUE; - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Playing started"); - - gtk_action_set_sensitive (priv->play_action, FALSE); - gtk_action_set_sensitive (priv->pause_action, TRUE); - gtk_action_set_visible (priv->play_action, FALSE); - gtk_action_set_visible (priv->pause_action, TRUE); - - if (priv->position_updater_id) { - g_source_remove (priv->position_updater_id); - priv->position_updater_id = 0; - } - update_position (gui); - priv->position_updater_id = g_timeout_add (1000, update_position, gui); -} - -static void -demo_gui_playing_paused (DemoPlayer * player, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - gtk_action_set_sensitive (priv->play_action, TRUE); - gtk_action_set_sensitive (priv->pause_action, FALSE); - gtk_action_set_visible (priv->play_action, TRUE); - gtk_action_set_visible (priv->pause_action, FALSE); - - priv->is_playing = FALSE; - - if (priv->position_updater_id) - g_source_remove (priv->position_updater_id); - priv->position_updater_id = 0; - update_position (gui); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Playing paused"); -} - -static void -demo_gui_playing_ended (DemoPlayer * player, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Playing ended"); - gtk_action_activate (priv->playlist_next); -} - -static void -demo_gui_player_errored (DemoPlayer * player, const gchar * msg, gpointer data) -{ - DemoGui *gui = DEMO_GUI (data); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - status_bar_printf (priv->status_bar, 5, msg); -} - -static void -demo_gui_stride_changed (DemoPlayer * player, GParamSpec * pspec, gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - DemoGui *gui = - DEMO_GUI (g_value_get_object (g_value_array_get_nth (gvalues, 0))); - GtkEntry *entry = - GTK_ENTRY (g_value_get_object (g_value_array_get_nth (gvalues, 1))); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - guint new_stride; - gchar e[6]; - - g_object_get (G_OBJECT (player), "stride", &new_stride, NULL); - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Stride changed to %u", new_stride); - - snprintf (e, 6, "%u", new_stride); - gtk_entry_set_text (entry, e); -} - -static void -demo_gui_overlap_changed (DemoPlayer * player, - GParamSpec * pspec, gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - DemoGui *gui = - DEMO_GUI (g_value_get_object (g_value_array_get_nth (gvalues, 0))); - GtkEntry *entry = - GTK_ENTRY (g_value_get_object (g_value_array_get_nth (gvalues, 1))); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - gdouble new_overlap; - gchar e[6]; - - g_object_get (G_OBJECT (player), "overlap", &new_overlap, NULL); - new_overlap *= 100; - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Overlap changed to %2.0lf%%", new_overlap); - - snprintf (e, 6, "%2.0f", new_overlap); - gtk_entry_set_text (entry, e); -} - -static void -demo_gui_search_changed (DemoPlayer * player, GParamSpec * pspec, gpointer data) -{ - GValueArray *gvalues = (GValueArray *) data; - DemoGui *gui = - DEMO_GUI (g_value_get_object (g_value_array_get_nth (gvalues, 0))); - GtkEntry *entry = - GTK_ENTRY (g_value_get_object (g_value_array_get_nth (gvalues, 1))); - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - guint new_search; - gchar e[6]; - - g_object_get (G_OBJECT (player), "search", &new_search, NULL); - status_bar_printf (priv->status_bar, DEFAULT_STATUS_BAR_TIMEOUT, - "Search changed to %u", new_search); - - snprintf (e, 6, "%u", new_search); - gtk_entry_set_text (entry, e); -} - - -/* method implementations */ -static void -demo_gui_set_player_func (DemoGui * gui, DemoPlayer * player) -{ - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - - if (priv->player) { - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->player), - G_CALLBACK (demo_gui_rate_changed), gui); - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->player), - G_CALLBACK (demo_gui_playing_started), gui); - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->player), - G_CALLBACK (demo_gui_playing_paused), gui); - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->player), - G_CALLBACK (demo_gui_playing_ended), gui); - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->player), - G_CALLBACK (demo_gui_player_errored), gui); - g_object_unref (priv->player); - } - g_object_ref (player); - priv->player = player; - g_signal_connect (G_OBJECT (priv->player), "error", - G_CALLBACK (demo_gui_player_errored), gui); - g_signal_connect (G_OBJECT (priv->player), "rate-changed", - G_CALLBACK (demo_gui_rate_changed), gui); - g_signal_connect (G_OBJECT (priv->player), "playing-started", - G_CALLBACK (demo_gui_playing_started), gui); - g_signal_connect (G_OBJECT (priv->player), "playing-paused", - G_CALLBACK (demo_gui_playing_paused), gui); - g_signal_connect (G_OBJECT (priv->player), "playing-ended", - G_CALLBACK (demo_gui_playing_ended), gui); - priv->is_playing = FALSE; -} - -static void -demo_gui_set_playlist_func (DemoGui * gui, GList * uris) -{ - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - priv->uris = uris; -} - -typedef struct _ActionEntry -{ - GtkAction *action; - GtkWidget *button; - const gchar *accel; - const gchar *name; - const gchar *label; - const gchar *tooltip; - const gchar *stock_id; - GtkAccelGroup *accel_group; - GtkActionGroup *action_group; - GCallback callback; - gpointer data; -} ActionEntry; - -static GValueArray * -build_gvalue_array (guint n_values, ...) -{ - va_list args; - GValueArray *gva; - int i; - - va_start (args, n_values); - gva = g_value_array_new (n_values); - - for (i = 0; i < n_values; i++) { - GType type = va_arg (args, GType); - GValue *gval = g_new0 (GValue, 1); - if (type == G_TYPE_INT) { - gint value = va_arg (args, gint); - g_value_set_int (g_value_init (gval, G_TYPE_INT), value); - } else if (type == G_TYPE_UINT) { - guint value = va_arg (args, guint); - g_value_set_uint (g_value_init (gval, G_TYPE_UINT), value); - } else if (type == G_TYPE_DOUBLE) { - double value = va_arg (args, double); - g_value_set_double (g_value_init (gval, G_TYPE_DOUBLE), value); - } else if (type == G_TYPE_OBJECT) { - GObject *value = va_arg (args, GObject *); - g_value_set_object (g_value_init (gval, G_TYPE_OBJECT), value); - } else { - g_critical ("build_gvalue_array cannot handle type (%s)", - g_type_name (type)); - va_end (args); - return NULL; - } - g_value_array_append (gva, gval); - } - va_end (args); - return gva; -} - -static void -create_action (ActionEntry * p) -{ - p->action = gtk_action_new (p->name, p->label, p->tooltip, p->stock_id); - - gtk_action_group_add_action_with_accel (p->action_group, p->action, p->accel); - gtk_action_set_accel_group (p->action, p->accel_group); - gtk_action_connect_accelerator (p->action); - - p->button = gtk_button_new (); -#if GTK_CHECK_VERSION (2, 16, 0) - gtk_activatable_set_related_action (GTK_ACTIVATABLE (p->button), p->action); -#else - gtk_action_connect_proxy (p->action, p->button); -#endif - gtk_button_set_image (GTK_BUTTON (p->button), - gtk_action_create_icon (p->action, GTK_ICON_SIZE_BUTTON)); - g_signal_connect (G_OBJECT (p->action), "activate", p->callback, p->data); -} - -static void -demo_gui_show_func (DemoGui * gui) -{ - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - GtkWidget *window; - GtkAccelGroup *accel_group; - GtkActionGroup *action_group; - GtkAction *toggle_advanced, *toggle_disabled; - ActionEntry *slower_lg, *slower_sm, *faster_sm, *faster_lg, *normal, - *rewind_lg, *rewind_sm, *forward_sm, *forward_lg, *pause, *play, - *play_pause, *open_file, *playlist_prev, *playlist_next, *quit, *about; - GtkRequisition pause_size; - GtkWidget *rate_entry, *rate_label, *toolbox, *stride_ui, *overlap_ui, - *search_ui, *propbox, *adv_check, *disabled_check, *media_controls, - *amount_played, *amount_to_play, *seek_range, *seek_bar, *status_bar, - *file_menu, *file_menu_item, *media_menu_item, *demo_menu, - *demo_menu_item, *menu_bar, *toplevel_box, *media_menu; - GError *error = NULL; - - gtk_init (NULL, NULL); - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (demo_gui_do_quit), - gui); - - accel_group = gtk_accel_group_new (); - gtk_window_add_accel_group (GTK_WINDOW (window), accel_group); - action_group = gtk_action_group_new ("toolbar"); - - slower_lg = &(ActionEntry) { - NULL, NULL, - "braceleft", "slower-large", - "2x Slower", "half playback rate", - GTK_STOCK_GO_DOWN, accel_group, action_group, - G_CALLBACK (demo_gui_do_change_rate), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_DOUBLE, 0.5) - }; - create_action (slower_lg); - - slower_sm = &(ActionEntry) { - NULL, NULL, - "bracketleft", "slower-small", - "_Slower", "decrease playback rate", - GTK_STOCK_GO_DOWN, accel_group, action_group, - G_CALLBACK (demo_gui_do_change_rate), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_DOUBLE, pow (2, - -1.0 / 12)) - }; - create_action (slower_sm); - - faster_sm = &(ActionEntry) { - NULL, NULL, - "bracketright", "faster-small", - "_Faster", "increase playback rate", - GTK_STOCK_GO_UP, accel_group, action_group, - G_CALLBACK (demo_gui_do_change_rate), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_DOUBLE, pow (2, - 1.0 / 12)) - }; - create_action (faster_sm); - - faster_lg = &(ActionEntry) { - NULL, NULL, - "braceright", "faster-large", - "2X Faster", "double playback rate", - GTK_STOCK_GO_UP, accel_group, action_group, - G_CALLBACK (demo_gui_do_change_rate), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_DOUBLE, 2.0) - }; - create_action (faster_lg); - - normal = &(ActionEntry) { - NULL, NULL, - "backslash", "normal", - "_Normal", "playback normal rate", - GTK_STOCK_CLEAR, accel_group, action_group, - G_CALLBACK (demo_gui_do_set_rate), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_DOUBLE, 1.0) - }; - create_action (normal); - - rewind_lg = &(ActionEntry) { - NULL, NULL, - "<ctrl><shift>Left", "seek-rewind-large", - "Rewind (large)", "seek -30 seconds", - GTK_STOCK_MEDIA_REWIND, accel_group, action_group, - G_CALLBACK (demo_gui_do_seek), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_INT, -30) - }; - create_action (rewind_lg); - - rewind_sm = &(ActionEntry) { - NULL, NULL, - "<ctrl>Left", "seek-rewind-small", - "Rewind", "seek -15 seconds", - GTK_STOCK_MEDIA_REWIND, accel_group, action_group, - G_CALLBACK (demo_gui_do_seek), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_INT, -5) - }; - create_action (rewind_sm); - - forward_sm = &(ActionEntry) { - NULL, NULL, - "<ctrl>Right", "seek-forward-small", - "Forward", "seek +5 seconds", - GTK_STOCK_MEDIA_FORWARD, accel_group, action_group, - G_CALLBACK (demo_gui_do_seek), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_INT, 5) - }; - create_action (forward_sm); - - forward_lg = &(ActionEntry) { - NULL, NULL, - "<ctrl><shift>Right", "seek-forward-large", - "Forward (large)", "seek +30 seconds", - GTK_STOCK_MEDIA_FORWARD, accel_group, action_group, - G_CALLBACK (demo_gui_do_seek), - build_gvalue_array (2, G_TYPE_OBJECT, gui, G_TYPE_INT, 30) - }; - create_action (forward_lg); - - pause = &(ActionEntry) { - NULL, NULL, - "p", "pause", - "Pause", "Pause playback", - GTK_STOCK_MEDIA_PAUSE, accel_group, action_group, - G_CALLBACK (demo_gui_do_pause), gui}; - create_action (pause); - - play = &(ActionEntry) { - NULL, NULL, - "<ctrl>p", "play", - "Play", "Start Playback", - GTK_STOCK_MEDIA_PLAY, accel_group, action_group, - G_CALLBACK (demo_gui_do_play), gui}; - create_action (play); - gtk_widget_size_request (pause->button, &pause_size); - gtk_widget_set_size_request (play->button, pause_size.width, -1); - - play_pause = &(ActionEntry) { - NULL, NULL, - "space", "play-pause", - "Play/Pause", "Toggle playback", - NULL, accel_group, action_group, - G_CALLBACK (demo_gui_do_play_pause), gui}; - create_action (play_pause); - - open_file = &(ActionEntry) { - NULL, NULL, - "<ctrl>o", "open-file", - "Open File", "Open file for playing", - GTK_STOCK_OPEN, accel_group, action_group, - G_CALLBACK (demo_gui_do_open_file), gui}; - create_action (open_file); - - playlist_prev = &(ActionEntry) { - NULL, NULL, - "less", "playlist-previous", - "Previous", "Previous in playlist", - GTK_STOCK_MEDIA_PREVIOUS, accel_group, action_group, - G_CALLBACK (demo_gui_do_playlist_prev), gui}; - create_action (playlist_prev); - - playlist_next = &(ActionEntry) { - NULL, NULL, - "greater", "playlist-next", - "Next", "Next in playlist", - GTK_STOCK_MEDIA_NEXT, accel_group, action_group, - G_CALLBACK (demo_gui_do_playlist_next), gui}; - create_action (playlist_next); - - quit = &(ActionEntry) { - NULL, NULL, - "q", "quit", - "Quit", "Quit demo", - GTK_STOCK_QUIT, accel_group, action_group, - G_CALLBACK (demo_gui_do_quit), gui}; - create_action (quit); - - about = &(ActionEntry) { - NULL, NULL, - "<ctrl>h", "about", - "About", "About gst-scaletemo-demo", - GTK_STOCK_ABOUT, accel_group, action_group, - G_CALLBACK (demo_gui_do_about_dialog), gui}; - create_action (about); - - rate_entry = gtk_entry_new (); - rate_label = gtk_label_new ("Rate:"); - gtk_entry_set_max_length (GTK_ENTRY (rate_entry), 5); - gtk_entry_set_text (GTK_ENTRY (rate_entry), "1.0"); - gtk_entry_set_width_chars (GTK_ENTRY (rate_entry), 5); - g_signal_connect (G_OBJECT (rate_entry), "activate", - G_CALLBACK (demo_gui_do_rate_entered), gui); - - toolbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (toolbox), slower_sm->button, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toolbox), rate_label, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toolbox), rate_entry, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toolbox), faster_sm->button, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toolbox), normal->button, FALSE, FALSE, 2); - - - stride_ui = - gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (60, 1, 1000, 1, - 10, 0)), 0, 0); - overlap_ui = - gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (20, 0, 100, 5, - 10, .00001)), 0, 0); - search_ui = - gtk_spin_button_new (GTK_ADJUSTMENT (gtk_adjustment_new (14, 0, 1000, 1, - 10, 0)), 0, 0); - gtk_widget_set_sensitive (stride_ui, FALSE); - gtk_widget_set_sensitive (overlap_ui, FALSE); - gtk_widget_set_sensitive (search_ui, FALSE); - g_signal_connect (G_OBJECT (stride_ui), "output", - G_CALLBACK (demo_gui_request_set_stride), gui); - g_signal_connect (G_OBJECT (overlap_ui), "output", - G_CALLBACK (demo_gui_request_set_overlap), gui); - g_signal_connect (G_OBJECT (search_ui), "output", - G_CALLBACK (demo_gui_request_set_search), gui); - g_signal_connect (G_OBJECT (priv->player), "notify::stride", - G_CALLBACK (demo_gui_stride_changed), build_gvalue_array (2, - G_TYPE_OBJECT, gui, G_TYPE_OBJECT, stride_ui)); - g_signal_connect (G_OBJECT (priv->player), "notify::overlap", - G_CALLBACK (demo_gui_overlap_changed), build_gvalue_array (2, - G_TYPE_OBJECT, gui, G_TYPE_OBJECT, overlap_ui)); - g_signal_connect (G_OBJECT (priv->player), "notify::search", - G_CALLBACK (demo_gui_search_changed), build_gvalue_array (2, - G_TYPE_OBJECT, gui, G_TYPE_OBJECT, search_ui)); - propbox = gtk_hbox_new (FALSE, 0); - adv_check = gtk_check_button_new (); - gtk_box_pack_start (GTK_BOX (propbox), gtk_label_new ("stride:"), FALSE, - FALSE, 2); - gtk_box_pack_start (GTK_BOX (propbox), stride_ui, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (propbox), gtk_label_new ("overlap:"), FALSE, - FALSE, 2); - gtk_box_pack_start (GTK_BOX (propbox), overlap_ui, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (propbox), gtk_label_new ("search:"), FALSE, - FALSE, 2); - gtk_box_pack_start (GTK_BOX (propbox), search_ui, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (propbox), adv_check, FALSE, FALSE, 2); - - toggle_advanced = - GTK_ACTION (gtk_toggle_action_new ("advanced", "Enable Parameters", - "Toggle advanced controls", 0)); - gtk_action_group_add_action_with_accel (action_group, toggle_advanced, - "<ctrl>a"); - gtk_action_set_accel_group (toggle_advanced, accel_group); - gtk_action_connect_accelerator (toggle_advanced); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (toggle_advanced), FALSE); -#if GTK_CHECK_VERSION (2, 16, 0) - gtk_activatable_set_related_action (GTK_ACTIVATABLE (adv_check), - toggle_advanced); -#else - gtk_action_connect_proxy (toggle_advanced, adv_check); -#endif - g_signal_connect (G_OBJECT (toggle_advanced), "activate", - G_CALLBACK (demo_gui_do_toggle_advanced), build_gvalue_array (4, - G_TYPE_OBJECT, gui, G_TYPE_OBJECT, stride_ui, G_TYPE_OBJECT, - overlap_ui, G_TYPE_OBJECT, search_ui)); - - toggle_disabled = - GTK_ACTION (gtk_toggle_action_new ("disabled", "Disable Scaletempo", - "Toggle disabling scaletempo", 0)); - gtk_action_group_add_action_with_accel (action_group, toggle_disabled, - "<ctrl>d"); - gtk_action_set_accel_group (toggle_disabled, accel_group); - gtk_action_connect_accelerator (toggle_disabled); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (toggle_disabled), FALSE); - disabled_check = gtk_check_button_new (); -#if GTK_CHECK_VERSION (2, 16, 0) - gtk_activatable_set_related_action (GTK_ACTIVATABLE (disabled_check), - toggle_disabled); -#else - gtk_action_connect_proxy (toggle_disabled, disabled_check); -#endif - g_signal_connect (G_OBJECT (toggle_disabled), "activate", - G_CALLBACK (demo_gui_do_toggle_disabled), build_gvalue_array (3, - G_TYPE_OBJECT, gui, G_TYPE_OBJECT, toggle_advanced, G_TYPE_OBJECT, - propbox)); - gtk_box_pack_start (GTK_BOX (toolbox), disabled_check, FALSE, FALSE, 2); - - - media_controls = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (media_controls), playlist_prev->button, FALSE, - FALSE, 2); - gtk_box_pack_start (GTK_BOX (media_controls), rewind_sm->button, FALSE, FALSE, - 2); - gtk_box_pack_start (GTK_BOX (media_controls), play->button, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (media_controls), pause->button, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (media_controls), forward_sm->button, FALSE, - FALSE, 2); - gtk_box_pack_start (GTK_BOX (media_controls), playlist_next->button, FALSE, - FALSE, 2); - - amount_played = gtk_label_new ("?:??:??"); - amount_to_play = gtk_label_new ("-?:??:??"); - gtk_label_set_width_chars (GTK_LABEL (amount_played), 8); - gtk_label_set_width_chars (GTK_LABEL (amount_to_play), 8); - gtk_misc_set_alignment (GTK_MISC (amount_played), 1, 1); - gtk_misc_set_alignment (GTK_MISC (amount_to_play), 0, 1); - seek_range = - gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 5.0, - 30.0, 0.00))); -#if !GTK_CHECK_VERSION (3, 0, 0) - gtk_range_set_update_policy (GTK_RANGE (seek_range), - GTK_UPDATE_DISCONTINUOUS); -#endif - seek_bar = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (seek_bar), amount_played, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (seek_bar), seek_range, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (seek_bar), amount_to_play, FALSE, FALSE, 2); - g_signal_connect (G_OBJECT (seek_range), "format-value", - G_CALLBACK (demo_gui_seek_bar_format), gui); - g_signal_connect (G_OBJECT (seek_range), "change-value", - G_CALLBACK (demo_gui_seek_bar_change), gui); - - status_bar = gtk_statusbar_new (); - - /* Menubar */ - file_menu = gtk_menu_new (); - gtk_menu_set_accel_group (GTK_MENU (file_menu), accel_group); - gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), - gtk_action_create_menu_item (open_file->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), - gtk_action_create_menu_item (about->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (file_menu), - gtk_action_create_menu_item (quit->action)); - file_menu_item = gtk_menu_item_new_with_mnemonic ("_File"); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_menu_item), file_menu); - - media_menu = gtk_menu_new (); - gtk_menu_set_accel_group (GTK_MENU (media_menu), accel_group); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (rewind_lg->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (rewind_sm->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (forward_sm->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (forward_lg->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (play->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (pause->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (play_pause->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (playlist_prev->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (media_menu), - gtk_action_create_menu_item (playlist_next->action)); - media_menu_item = gtk_menu_item_new_with_mnemonic ("_Media"); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (media_menu_item), media_menu); - - demo_menu = gtk_menu_new (); - gtk_menu_set_accel_group (GTK_MENU (demo_menu), accel_group); - gtk_menu_shell_append (GTK_MENU_SHELL (demo_menu), - gtk_action_create_menu_item (faster_lg->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (demo_menu), - gtk_action_create_menu_item (faster_sm->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (demo_menu), - gtk_action_create_menu_item (slower_sm->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (demo_menu), - gtk_action_create_menu_item (slower_lg->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (demo_menu), - gtk_action_create_menu_item (normal->action)); - gtk_menu_shell_append (GTK_MENU_SHELL (demo_menu), - gtk_action_create_menu_item (toggle_disabled)); - gtk_menu_shell_append (GTK_MENU_SHELL (demo_menu), - gtk_action_create_menu_item (toggle_advanced)); - demo_menu_item = gtk_menu_item_new_with_mnemonic ("_Scaletempo"); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (demo_menu_item), demo_menu); - - menu_bar = gtk_menu_bar_new (); - gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), file_menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), media_menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu_bar), demo_menu_item); - - /* Toplevel Window */ - gtk_window_set_title (GTK_WINDOW (window), "Scaletempo Demo"); - toplevel_box = gtk_vbox_new (FALSE, 0); - gtk_container_set_border_width (GTK_CONTAINER (toplevel_box), 3); - gtk_container_add (GTK_CONTAINER (window), toplevel_box); - gtk_box_pack_start (GTK_BOX (toplevel_box), menu_bar, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toplevel_box), media_controls, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toplevel_box), toolbox, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toplevel_box), propbox, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toplevel_box), seek_bar, FALSE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (toplevel_box), status_bar, FALSE, FALSE, 2); - - priv->window = window; - priv->rate_entry = GTK_ENTRY (rate_entry); - priv->status_bar = GTK_STATUSBAR (status_bar); - priv->seek_range = GTK_RANGE (seek_range); - priv->amount_played = GTK_LABEL (amount_played); - priv->amount_to_play = GTK_LABEL (amount_to_play); - priv->play_action = GTK_ACTION (play->action); - priv->pause_action = GTK_ACTION (pause->action); - priv->open_file = GTK_ACTION (open_file->action); - priv->playlist_next = GTK_ACTION (playlist_next->action); - - gtk_action_set_sensitive (priv->pause_action, FALSE); - gtk_action_set_visible (priv->pause_action, FALSE); - - gtk_widget_show_all (window); - gtk_widget_grab_focus (seek_range); - gtk_action_activate (priv->playlist_next); - status_bar_printf (GTK_STATUSBAR (status_bar), 5, - "Welcome to the Scaletempo demo."); - - if (!g_thread_try_new ("name", (GThreadFunc) gtk_main, NULL, &error)) { - g_signal_emit (gui, demo_gui_signals[SIGNAL_ERROR], 0, error->message); - } -} - - -/* Method wrappers */ -void -demo_gui_set_player (DemoGui * gui, DemoPlayer * player) -{ - g_return_if_fail (DEMO_IS_GUI (gui)); - g_return_if_fail (DEMO_IS_PLAYER (player)); - - DEMO_GUI_GET_CLASS (gui)->set_player (gui, player); -} - -void -demo_gui_set_playlist (DemoGui * gui, GList * uris) -{ - g_return_if_fail (DEMO_IS_GUI (gui)); - - DEMO_GUI_GET_CLASS (gui)->set_playlist (gui, uris); -} - -void -demo_gui_show (DemoGui * gui) -{ - g_return_if_fail (DEMO_IS_GUI (gui)); - - DEMO_GUI_GET_CLASS (gui)->show (gui); -} - - - -/* GObject overrides */ -static void -demo_gui_get_property (GObject * object, - guint property_id, GValue * value, GParamSpec * pspec) -{ - //DemoGui *gui = DEMO_GUI (object); - switch (property_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -demo_gui_set_property (GObject * object, - guint property_id, const GValue * value, GParamSpec * pspec) -{ - //DemoGui *gui = DEMO_GUI (object); - switch (property_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - -/* GTypeInfo functions */ -static void -demo_gui_init (GTypeInstance * instance, gpointer klass) -{ - DemoGui *gui = (DemoGui *) instance; - - DemoGuiPrivate *priv = DEMO_GUI_GET_PRIVATE (gui); - priv->player = NULL; - priv->uris = NULL; - priv->now_playing = NULL; - priv->is_playing = FALSE; - priv->window = NULL; - priv->rate_entry = NULL; - priv->position_updater_id = 0; - priv->seek_range = NULL; - priv->amount_played = NULL; - priv->amount_to_play = NULL; -} - -static void -demo_gui_class_init (gpointer klass, gpointer class_data) -{ - DemoGuiClass *gui_class = (DemoGuiClass *) klass; - GObjectClass *as_object_class = G_OBJECT_CLASS (klass); - GType type; - - g_type_class_add_private (klass, sizeof (DemoGuiPrivate)); - - /* DemiPlayer */ - gui_class->set_player = demo_gui_set_player_func; - gui_class->set_playlist = demo_gui_set_playlist_func; - gui_class->show = demo_gui_show_func; - - /* GObject */ - as_object_class->get_property = demo_gui_get_property; - as_object_class->set_property = demo_gui_set_property; - - /* Properties */ - - /* Signals */ - type = G_TYPE_FROM_CLASS (klass); - demo_gui_signals[SIGNAL_ERROR] = g_signal_new ("error", type, - G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); - - demo_gui_signals[SIGNAL_QUITING] = g_signal_new ("quiting", type, - G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, NULL); -} - -GType -demo_gui_get_type (void) -{ - static GType type = 0; - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo info = { - sizeof /* Class */ (DemoGuiClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) demo_gui_class_init, - (GClassFinalizeFunc) NULL, - (gconstpointer) NULL, /* class_data */ - sizeof /* Instance */ (DemoGui), - /* n_preallocs */ 0, - (GInstanceInitFunc) demo_gui_init, - (const GTypeValueTable *) NULL - }; - type = g_type_register_static (G_TYPE_OBJECT, "DemoGui", &info, 0); - } - return type; -} diff --git a/tests/examples/scaletempo/demo-gui.h b/tests/examples/scaletempo/demo-gui.h deleted file mode 100644 index b447d0d8b..000000000 --- a/tests/examples/scaletempo/demo-gui.h +++ /dev/null @@ -1,60 +0,0 @@ -/* demo-gui.h - * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __DEMO_GUI_H_INCLUDED_ -#define __DEMO_GUI_H_INCLUDED_ - -#include <glib-object.h> -#include "demo-player.h" - -G_BEGIN_DECLS - -#define DEMO_TYPE_GUI (demo_gui_get_type()) -#define DEMO_GUI(o) (G_TYPE_CHECK_INSTANCE_CAST((o), DEMO_TYPE_GUI, DemoGui)) -#define DEMO_IS_GUI(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), DEMO_TYPE_GUI)) -#define DEMO_GUI_TYPE(o) (G_TYPE_FROM_INSTANCE (o)) -#define DEMO_GUI_TYPE_NAME(o) (g_type_name (DEMO_GUI_GUI (o))) - -#define DEMO_GUI_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), DEMO_TYPE_GUI, DemoGuiClass)) -#define DEMO_IS_GUI_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), DEMO_TYPE_GUI)) -#define DEMO_GUI_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DEMO_TYPE_GUI, DemoGuiClass)) - -typedef struct _DemoGui DemoGui; -typedef struct _DemoGuiClass DemoGuiClass; - -struct _DemoGui -{ - GObject parent; -}; - -struct _DemoGuiClass -{ - GObjectClass parent; - void (*set_player) (DemoGui *gui, DemoPlayer *player); - void (*set_playlist) (DemoGui *gui, GList *uris); - void (*show) (DemoGui *gui); -}; - -GType demo_gui_get_type (void); - -void demo_gui_set_player (DemoGui *gui, DemoPlayer *player); -void demo_gui_set_playlist (DemoGui *gui, GList *uris); -void demo_gui_show (DemoGui *gui); - -G_END_DECLS - -#endif /* __DEMO_GUI_H_INCLUDED_ */ diff --git a/tests/examples/scaletempo/demo-main.c b/tests/examples/scaletempo/demo-main.c deleted file mode 100644 index 5648bc54e..000000000 --- a/tests/examples/scaletempo/demo-main.c +++ /dev/null @@ -1,95 +0,0 @@ -/* main.c - * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "demo-player.h" -#include "demo-gui.h" - -extern GOptionGroup *gtk_get_option_group (gboolean); -extern GOptionGroup *gst_init_get_option_group (void); - -static void -handle_player_error (DemoPlayer * player, const gchar * msg, gpointer unused) -{ - g_print ("PLAYER ERROR: %s\n", msg); -} - -static void -handle_gui_error (DemoPlayer * player, const gchar * msg, gpointer unused) -{ - g_print ("GUI ERROR: %s\n", msg); -} - -static void -handle_quit (gpointer source, gpointer data) -{ - g_main_loop_quit ((GMainLoop *) data); -} - - -int -main (int argc, char *argv[]) -{ - DemoGui *gui; - DemoPlayer *player; - gchar **uris = NULL; - GOptionContext *ctx; - GError *err = NULL; - GMainLoop *loop; - - const GOptionEntry entries[] = { - {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &uris, - "Special option that collects any remaining arguments for us"}, - {NULL,} - }; - - ctx = g_option_context_new ("uri ..."); - g_option_context_add_group (ctx, gst_init_get_option_group ()); - g_option_context_add_group (ctx, gtk_get_option_group (FALSE)); - g_option_context_add_main_entries (ctx, entries, NULL); - if (!g_option_context_parse (ctx, &argc, &argv, &err)) { - g_print ("Error initializing: %s\n", err->message); - g_error_free (err); - return -1; - } - g_option_context_free (ctx); - - gui = g_object_new (DEMO_TYPE_GUI, NULL); - player = g_object_new (DEMO_TYPE_PLAYER, NULL); - g_signal_connect (player, "error", G_CALLBACK (handle_player_error), NULL); - g_signal_connect (gui, "error", G_CALLBACK (handle_gui_error), NULL); - demo_gui_set_player (gui, player); - - loop = g_main_loop_new (NULL, FALSE); - g_signal_connect (gui, "quiting", G_CALLBACK (handle_quit), loop); - - if (uris != NULL) { - int i, num = g_strv_length (uris); - GList *uri_list = NULL; - for (i = 0; i < num; i++) { - uri_list = g_list_append (uri_list, uris[i]); - } - demo_gui_set_playlist (gui, uri_list); - } - demo_gui_show (gui); - g_main_loop_run (loop); - - return 0; -} diff --git a/tests/examples/scaletempo/demo-player.c b/tests/examples/scaletempo/demo-player.c deleted file mode 100644 index 8d5325ac4..000000000 --- a/tests/examples/scaletempo/demo-player.c +++ /dev/null @@ -1,756 +0,0 @@ -/* demo-player.c - * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "demo-player.h" -#include "gst/gst.h" - -#undef G_LOG_DOMAIN -#define G_LOG_DOMAIN "demo-player" - -enum -{ - SIGNAL_ERROR, - SIGNAL_RATE_CHANGE, - SIGNAL_PLAYING_STARTED, - SIGNAL_PLAYING_PAUSED, - SIGNAL_PLAYING_ENDED, - LAST_SIGNAL -}; -static guint demo_player_signals[LAST_SIGNAL] = { 0 }; - -enum -{ - PROP_0, - PROP_RATE, - PROP_STRIDE, - PROP_OVERLAP, - PROP_SEARCH, - PROP_DISABLED -}; - -typedef struct _DemoPlayerPrivate -{ - gdouble rate; - GstElement *scaletempo; - GstElement *pipeline; - gboolean is_disabled; - GstElement *scaletempo_line; - GstElement *scalerate_line; - gboolean ignore_state_change; -} DemoPlayerPrivate; - -#define DEMO_PLAYER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEMO_TYPE_PLAYER, DemoPlayerPrivate)) - - -static gboolean -no_pipeline (DemoPlayer * player) -{ - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - if (!priv->pipeline) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "No media loaded"); - return TRUE; - } - return FALSE; -} - -static GstPadProbeReturn -demo_player_event_listener (GstPad * pad, GstPadProbeInfo * info, gpointer data) -{ - GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info); - DemoPlayer *player = DEMO_PLAYER (data); - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - - if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) { - const GstSegment *segment; - gdouble new_rate; - - gst_event_parse_segment (event, &segment); - new_rate = segment->rate * segment->applied_rate; - if (priv->rate != new_rate) { - priv->rate = new_rate; - g_signal_emit (player, demo_player_signals[SIGNAL_RATE_CHANGE], 0, - new_rate); - } - } - - return GST_PAD_PROBE_OK; -} - -static void -demo_player_state_changed_cb (GstBus * bus, GstMessage * message, gpointer data) -{ - DemoPlayer *player = DEMO_PLAYER (data); - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - GstState old, new, pending; - - if (GST_ELEMENT (GST_MESSAGE_SRC (message)) != priv->pipeline) - return; - - gst_message_parse_state_changed (message, &old, &new, &pending); - - if (pending == GST_STATE_VOID_PENDING) { - if (priv->ignore_state_change) { - priv->ignore_state_change = FALSE; - } else if (new == GST_STATE_PAUSED) { - g_signal_emit (player, demo_player_signals[SIGNAL_PLAYING_PAUSED], 0); - } else if (new == GST_STATE_PLAYING) { - g_signal_emit (player, demo_player_signals[SIGNAL_PLAYING_STARTED], 0); - } - } -} - -static void -demo_player_eos_cb (GstBus * bus, GstMessage * message, gpointer data) -{ - DemoPlayer *player = DEMO_PLAYER (data); - g_signal_emit (player, demo_player_signals[SIGNAL_PLAYING_ENDED], 0); -} - -#define MAKE_ELEMENT(line, var, type, name) \ - if ( !(var = gst_element_factory_make (type, name) ) ) { \ - g_print ("element could not be created: %s/%s\n", type, name); \ - return; \ - } \ - if (line) gst_bin_add (GST_BIN (line), var); - -#define LINK_ELEMENTS(src, sink) \ - if (!gst_element_link (src, sink)) { \ - g_warning ("Failed to link elements: %s -> %s", \ - GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (sink) ); \ - return; \ - } - -static void -demo_player_build_pipeline (DemoPlayer * player) -{ - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - GstElement *filter, *playbin, *vsink, *audioline, *format, *resample, *asink; - GstPlugin *gconf; - GstBus *bus; - gboolean has_gconf; - const gchar *audiosink_name; - GstPad *ghostpad; - - priv->pipeline = NULL; - if (!priv->scaletempo) { - return; - } - - filter = priv->scaletempo; - - MAKE_ELEMENT (NULL, playbin, "playbin", "playbin"); - gconf = gst_registry_find_plugin (gst_registry_get (), "gconfelements"); - has_gconf = (gconf != NULL); - gst_object_unref (gconf); - - if (has_gconf) { - MAKE_ELEMENT (NULL, vsink, "gconfvideosink", "vsink"); - g_object_set (G_OBJECT (playbin), "video_sink", vsink, NULL); - } - audiosink_name = has_gconf ? "gconfaudiosink" : "autoaudiosink"; - - audioline = gst_bin_new ("audioline"); - gst_bin_add (GST_BIN (audioline), filter); - MAKE_ELEMENT (audioline, format, "audioconvert", "format"); - MAKE_ELEMENT (audioline, resample, "audioresample", "resample"); - MAKE_ELEMENT (audioline, asink, audiosink_name, "audio_sink"); - LINK_ELEMENTS (filter, format); - LINK_ELEMENTS (format, resample); - LINK_ELEMENTS (resample, asink); - - gst_pad_add_probe (gst_element_get_static_pad (asink, "sink"), - GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, - demo_player_event_listener, player, NULL); - - ghostpad = gst_element_get_static_pad (filter, "sink"); - gst_element_add_pad (audioline, gst_ghost_pad_new ("sink", ghostpad)); - gst_object_unref (ghostpad); - g_object_set (G_OBJECT (playbin), "audio-sink", audioline, NULL); - - bus = gst_pipeline_get_bus (GST_PIPELINE (playbin)); - gst_bus_add_signal_watch (bus); - g_signal_connect (bus, "message::state-changed", - G_CALLBACK (demo_player_state_changed_cb), player); - g_signal_connect (bus, "message::eos", G_CALLBACK (demo_player_eos_cb), - player); - gst_object_unref (bus); - - priv->scaletempo = filter; - priv->pipeline = playbin; - - priv->scaletempo_line = audioline; - MAKE_ELEMENT (NULL, priv->scalerate_line, audiosink_name, - "scaling_audio_sink"); - gst_pad_add_probe (gst_element_get_static_pad (priv->scalerate_line, - "sink"), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, - demo_player_event_listener, player, NULL); - g_object_ref (priv->scaletempo_line); - g_object_ref (priv->scalerate_line); -} - - -/* method implementations */ -static void -_set_rate (DemoPlayer * player, gdouble new_rate, gint second) -{ - DemoPlayerPrivate *priv; - gint64 pos; - GstSeekType seek_type; - - - if (new_rate == 0) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Cannot set playback to zero. Pausing instead."); - demo_player_pause (player); - } - - priv = DEMO_PLAYER_GET_PRIVATE (player); - - if (second < 0) { - seek_type = GST_SEEK_TYPE_SET; - if (!gst_element_query_position (priv->pipeline, GST_FORMAT_TIME, &pos)) { - // This should be the default but too many upstream elements seek anyway - pos = GST_CLOCK_TIME_NONE; - seek_type = GST_SEEK_TYPE_NONE; - } - } else { - seek_type = GST_SEEK_TYPE_SET; - pos = second * GST_SECOND; - } - - if (!gst_element_seek (priv->pipeline, new_rate, - GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, - seek_type, pos, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Unable to change playback rate"); - } else { - priv->ignore_state_change = TRUE; - } -} - -static void -demo_player_scale_rate_func (DemoPlayer * player, gdouble scale) -{ - DemoPlayerPrivate *priv; - if (no_pipeline (player)) - return; - - priv = DEMO_PLAYER_GET_PRIVATE (player); - - if (scale != 1.0) { - g_message ("Scaling Rate by: %3.2f", scale); - _set_rate (player, priv->rate * scale, -1); - } -} - -static void -demo_player_set_rate_func (DemoPlayer * player, gdouble new_rate) -{ - DemoPlayerPrivate *priv; - - if (no_pipeline (player)) - return; - - priv = DEMO_PLAYER_GET_PRIVATE (player); - - if (priv->rate != new_rate) { - g_message ("Setting Rate to: %3.2f", new_rate); - _set_rate (player, new_rate, -1); - } -} - -static gboolean -_set_state_and_wait (DemoPlayer * player, - GstState new_state, GstClockTime timeout, const gchar * error_msg) -{ - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - GstStateChangeReturn ret = gst_element_set_state (priv->pipeline, new_state); - if (ret == GST_STATE_CHANGE_ASYNC) { - ret = gst_element_get_state (priv->pipeline, NULL, NULL, timeout); - } - if (ret != GST_STATE_CHANGE_SUCCESS) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, error_msg); - return FALSE; - } - return TRUE; -} - -static void -demo_player_load_uri_func (DemoPlayer * player, gchar * uri) -{ - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - GstState end_state; - gdouble rate; - - if (!priv->pipeline) { - demo_player_build_pipeline (player); - if (!priv->pipeline) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Could not build player"); - return; - } - } - if (!g_str_has_prefix (uri, "file:///")) { - GError *err = NULL; - if (g_path_is_absolute (uri)) { - uri = g_filename_to_uri (uri, NULL, &err); - } else { - gchar *curdir = g_get_current_dir (); - gchar *absolute_path = g_strconcat (curdir, G_DIR_SEPARATOR_S, uri, NULL); - uri = g_filename_to_uri (absolute_path, NULL, &err); - g_free (absolute_path); - g_free (curdir); - } - if (err) { - gchar *msg = g_strconcat ("Could not load uri: ", err->message, NULL); - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, msg); - return; - } - } - - g_message ("Loading URI: %s", uri); - - end_state = - (GST_STATE (priv->pipeline) == - GST_STATE_PLAYING) ? GST_STATE_PLAYING : GST_STATE_PAUSED; - if (!_set_state_and_wait (player, GST_STATE_NULL, 10 * GST_SECOND, - "Unable to load uri")) - return; - - g_object_set (G_OBJECT (priv->pipeline), "uri", uri, NULL); - - rate = priv->rate; - if (rate && rate != 1.0) { - _set_state_and_wait (player, GST_STATE_PAUSED, 10 * GST_SECOND, - "Unable to keep playback rate"); - _set_rate (player, rate, -1); - } - - gst_element_set_state (priv->pipeline, end_state); -} - -static void -demo_player_play_func (DemoPlayer * player) -{ - DemoPlayerPrivate *priv; - GstStateChangeReturn ret; - - if (no_pipeline (player)) - return; - - priv = DEMO_PLAYER_GET_PRIVATE (player); - - if (GST_STATE (priv->pipeline) == GST_STATE_PLAYING) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Already playing"); - return; - } - - g_debug ("Starting to Play"); - ret = gst_element_set_state (priv->pipeline, GST_STATE_PLAYING); - if (ret == GST_STATE_CHANGE_FAILURE) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Unable to start playback"); - return; - } -} - -static void -demo_player_pause_func (DemoPlayer * player) -{ - DemoPlayerPrivate *priv; - GstStateChangeReturn ret; - - if (no_pipeline (player)) - return; - - priv = DEMO_PLAYER_GET_PRIVATE (player); - - if (GST_STATE (priv->pipeline) == GST_STATE_PAUSED) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Already paused"); - return; - } - - g_debug ("Starting to Pause"); - ret = gst_element_set_state (priv->pipeline, GST_STATE_PAUSED); - if (ret == GST_STATE_CHANGE_FAILURE) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Unable to pause playback"); - return; - } -} - -static void -_seek_to (DemoPlayer * player, gint new_second) -{ - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - if (!gst_element_seek (priv->pipeline, priv->rate, - GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, - GST_SEEK_TYPE_SET, new_second * GST_SECOND, - GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, "Seek failed"); - return; - } - - priv->ignore_state_change = TRUE; -} - -static void -demo_player_seek_by_func (DemoPlayer * player, gint seconds) -{ - gint pos; - - if (no_pipeline (player)) - return; - - g_debug ("Seeking by: %i", seconds); - - pos = demo_player_get_position (player); - if (pos < 0) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Seek-by failed: could not determine position"); - return; - } - - _seek_to (player, MAX (0, pos + seconds)); -} - -static void -demo_player_seek_to_func (DemoPlayer * player, gint second) -{ - gint new_second; - - if (no_pipeline (player)) - return; - - g_debug ("Seeking to: %i", second); - - if (second < 0) { - gint dur = demo_player_get_duration (player); - if (dur < 0) { - g_signal_emit (player, demo_player_signals[SIGNAL_ERROR], 0, - "Seek-to failed: could not determine duration"); - return; - } - new_second = MAX (0, dur + second); - } else { - new_second = second; - } - - _seek_to (player, new_second); -} - -static gint -demo_player_get_position_func (DemoPlayer * player) -{ - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - gint64 pos; - - if (!priv->pipeline) - return -1; - - if (!gst_element_query_position (priv->pipeline, GST_FORMAT_TIME, &pos) - || pos < 0) { - return -1; - } - - return (gint) (pos / GST_SECOND); -} - -static gint -demo_player_get_duration_func (DemoPlayer * player) -{ - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - gint64 dur; - - if (!priv->pipeline) - return -1; - - if (!gst_element_query_duration (priv->pipeline, GST_FORMAT_TIME, &dur) - || dur < 0) { - return -1; - } - - return (gint) (dur / GST_SECOND); -} - - -/* Method wrappers */ -void -demo_player_scale_rate (DemoPlayer * player, gdouble scale) -{ - g_return_if_fail (DEMO_IS_PLAYER (player)); - - DEMO_PLAYER_GET_CLASS (player)->scale_rate (player, scale); -} - -void -demo_player_set_rate (DemoPlayer * player, gdouble new_rate) -{ - g_return_if_fail (DEMO_IS_PLAYER (player)); - - DEMO_PLAYER_GET_CLASS (player)->set_rate (player, new_rate); -} - -void -demo_player_load_uri (DemoPlayer * player, gchar * uri) -{ - g_return_if_fail (DEMO_IS_PLAYER (player)); - - DEMO_PLAYER_GET_CLASS (player)->load_uri (player, uri); -} - -void -demo_player_play (DemoPlayer * player) -{ - g_return_if_fail (DEMO_IS_PLAYER (player)); - - DEMO_PLAYER_GET_CLASS (player)->play (player); -} - -void -demo_player_pause (DemoPlayer * player) -{ - g_return_if_fail (DEMO_IS_PLAYER (player)); - - DEMO_PLAYER_GET_CLASS (player)->pause (player); -} - -void -demo_player_seek_by (DemoPlayer * player, gint seconds) -{ - g_return_if_fail (DEMO_IS_PLAYER (player)); - - DEMO_PLAYER_GET_CLASS (player)->seek_by (player, seconds); -} - -void -demo_player_seek_to (DemoPlayer * player, gint second) -{ - g_return_if_fail (DEMO_IS_PLAYER (player)); - - DEMO_PLAYER_GET_CLASS (player)->seek_to (player, second); -} - -gint -demo_player_get_position (DemoPlayer * player) -{ - g_return_val_if_fail (DEMO_IS_PLAYER (player), -1); - - return DEMO_PLAYER_GET_CLASS (player)->get_position (player); -} - -gint -demo_player_get_duration (DemoPlayer * player) -{ - g_return_val_if_fail (DEMO_IS_PLAYER (player), -1); - - return DEMO_PLAYER_GET_CLASS (player)->get_duration (player); -} - -/* GObject overrides */ -static void -demo_player_get_property (GObject * object, - guint property_id, GValue * value, GParamSpec * pspec) -{ - DemoPlayer *player = DEMO_PLAYER (object); - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - switch (property_id) { - case PROP_RATE: - g_value_set_double (value, priv->rate); - break; - case PROP_STRIDE: - g_object_get_property (G_OBJECT (priv->scaletempo), "stride", value); - break; - case PROP_OVERLAP: - g_object_get_property (G_OBJECT (priv->scaletempo), "overlap", value); - break; - case PROP_SEARCH: - g_object_get_property (G_OBJECT (priv->scaletempo), "search", value); - break; - case PROP_DISABLED: - g_value_set_boolean (value, priv->is_disabled); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -demo_player_set_property (GObject * object, - guint property_id, const GValue * value, GParamSpec * pspec) -{ - DemoPlayer *player = DEMO_PLAYER (object); - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - switch (property_id) { - case PROP_STRIDE: - g_object_set_property (G_OBJECT (priv->scaletempo), "stride", value); - break; - case PROP_OVERLAP: - g_object_set_property (G_OBJECT (priv->scaletempo), "overlap", value); - break; - case PROP_SEARCH: - g_object_set_property (G_OBJECT (priv->scaletempo), "search", value); - break; - case PROP_DISABLED:{ - gdouble rate = priv->rate; - gint pos = demo_player_get_position (player); - GstState end_state; - GstElement *new_sink; - - priv->is_disabled = g_value_get_boolean (value); - - g_debug ("Scaletempo: %s", priv->is_disabled ? "disabled" : "enabled"); - - end_state = - (GST_STATE (priv->pipeline) == - GST_STATE_PLAYING) ? GST_STATE_PLAYING : GST_STATE_PAUSED; - if (!_set_state_and_wait (player, GST_STATE_NULL, 10 * GST_SECOND, - "Unable to disable")) - break; - - new_sink = - (priv->is_disabled) ? priv->scalerate_line : priv->scaletempo_line; - g_object_set (G_OBJECT (priv->pipeline), "audio-sink", new_sink, NULL); - - if (pos > 0 || (rate && rate != 1.0)) { - _set_state_and_wait (player, GST_STATE_PAUSED, 10 * GST_SECOND, - "Unable to keep playback position and rate"); - _set_rate (player, rate, pos); - } - - gst_element_set_state (priv->pipeline, end_state); - break; - } - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - - -/* GTypeInfo functions */ -static void -demo_player_init (GTypeInstance * instance, gpointer klass) -{ - DemoPlayer *player = (DemoPlayer *) instance; - DemoPlayerPrivate *priv = DEMO_PLAYER_GET_PRIVATE (player); - priv->scaletempo = gst_element_factory_make ("scaletempo", "scaletempo"); - if (!priv->scaletempo) { - g_error ("Unable to make scaletempo element."); - } - priv->rate = 1.0; - priv->pipeline = NULL; - priv->ignore_state_change = FALSE; - priv->is_disabled = FALSE; -} - -static void -demo_player_class_init (gpointer klass, gpointer class_data) -{ - DemoPlayerClass *player_class = (DemoPlayerClass *) klass; - GObjectClass *as_object_class = G_OBJECT_CLASS (klass); - GType type; - - g_type_class_add_private (klass, sizeof (DemoPlayerPrivate)); - - /* DemoPlayer */ - player_class->scale_rate = demo_player_scale_rate_func; - player_class->set_rate = demo_player_set_rate_func; - player_class->load_uri = demo_player_load_uri_func; - player_class->play = demo_player_play_func; - player_class->pause = demo_player_pause_func; - player_class->seek_by = demo_player_seek_by_func; - player_class->seek_to = demo_player_seek_to_func; - player_class->get_position = demo_player_get_position_func; - player_class->get_duration = demo_player_get_duration_func; - - /* GObject */ - as_object_class->get_property = demo_player_get_property; - as_object_class->set_property = demo_player_set_property; - - /* Properties */ - g_object_class_install_property (as_object_class, PROP_RATE, - g_param_spec_double ("rate", "Rate", "Current playback rate", - -128, 128, 1.0, G_PARAM_READABLE)); - - g_object_class_install_property (as_object_class, PROP_STRIDE, - g_param_spec_uint ("stride", "Stride Length", - "Length in milliseconds to output each stride", 1, 10000, 60, - G_PARAM_READWRITE)); - - g_object_class_install_property (as_object_class, PROP_OVERLAP, - g_param_spec_double ("overlap", "Overlap Length", - "Percentage of stride to overlap", 0, 1, .2, G_PARAM_READWRITE)); - - g_object_class_install_property (as_object_class, PROP_SEARCH, - g_param_spec_uint ("search", "Search Length", - "Length in milliseconds to search for best overlap position", 0, - 10000, 14, G_PARAM_READWRITE)); - - g_object_class_install_property (as_object_class, PROP_DISABLED, - g_param_spec_boolean ("disabled", "disable scaletempo", - "Disable scaletempo and scale bothe tempo and pitch", FALSE, - G_PARAM_READWRITE)); - - /* Signals */ - type = G_TYPE_FROM_CLASS (klass); - demo_player_signals[SIGNAL_ERROR] = g_signal_new ("error", type, - G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); - - demo_player_signals[SIGNAL_RATE_CHANGE] = g_signal_new ("rate-changed", type, - G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__DOUBLE, G_TYPE_NONE, 1, G_TYPE_DOUBLE); - - demo_player_signals[SIGNAL_PLAYING_STARTED] = - g_signal_new ("playing-started", type, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - demo_player_signals[SIGNAL_PLAYING_PAUSED] = - g_signal_new ("playing-paused", type, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - demo_player_signals[SIGNAL_PLAYING_ENDED] = - g_signal_new ("playing-ended", type, G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); -} - -GType -demo_player_get_type (void) -{ - static GType type = 0; - if (G_UNLIKELY (type == 0)) { - static const GTypeInfo info = { - sizeof /* Class */ (DemoPlayerClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) demo_player_class_init, - (GClassFinalizeFunc) NULL, - (gconstpointer) NULL, /* class_data */ - sizeof /* Instance */ (DemoPlayer), - /* n_preallocs */ 0, - (GInstanceInitFunc) demo_player_init, - (const GTypeValueTable *) NULL - }; - type = g_type_register_static (G_TYPE_OBJECT, "DemoPlayer", &info, 0); - } - return type; -} diff --git a/tests/examples/scaletempo/demo-player.h b/tests/examples/scaletempo/demo-player.h deleted file mode 100644 index ff521fc77..000000000 --- a/tests/examples/scaletempo/demo-player.h +++ /dev/null @@ -1,71 +0,0 @@ -/* gui.h - * Copyright (C) 2008 Rov Juvano <rovjuvano@users.sourceforge.net> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __DEMO_PLAYER_H_INCLUDED_ -#define __DEMO_PLAYER_H_INCLUDED_ - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define DEMO_TYPE_PLAYER (demo_player_get_type()) -#define DEMO_PLAYER(o) (G_TYPE_CHECK_INSTANCE_CAST((o), DEMO_TYPE_PLAYER, DemoPlayer)) -#define DEMO_IS_PLAYER(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), DEMO_TYPE_PLAYER)) -#define DEMO_PLAYER_TYPE(o) (G_TYPE_FROM_INSTANCE (o)) -#define DEMO_PLAYER_TYPE_NAME(o) (g_type_name (DEMO_PLAYER_TYPE (o))) - -#define DEMO_PLAYER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), DEMO_TYPE_PLAYER, DemoPlayerClass)) -#define DEMO_IS_PLAYER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), DEMO_TYPE_PLAYER)) -#define DEMO_PLAYER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DEMO_TYPE_PLAYER, DemoPlayerClass)) - -typedef struct _DemoPlayer DemoPlayer; -typedef struct _DemoPlayerClass DemoPlayerClass; - -struct _DemoPlayer -{ - GObject parent; -}; - -struct _DemoPlayerClass -{ - GObjectClass parent; - void (*scale_rate) (DemoPlayer *player, gdouble scale); - void (*set_rate) (DemoPlayer *player, gdouble new_rate); - void (*load_uri) (DemoPlayer *player, gchar *uri); - void (*play) (DemoPlayer *player); - void (*pause) (DemoPlayer *player); - void (*seek_by) (DemoPlayer *player, gint seconds); - void (*seek_to) (DemoPlayer *player, gint seconds); - gint (*get_position) (DemoPlayer *player); - gint (*get_duration) (DemoPlayer *player); -}; - -GType demo_player_get_type (void); - -void demo_player_scale_rate (DemoPlayer *player, gdouble scale); -void demo_player_set_rate (DemoPlayer *player, gdouble new_rate); -void demo_player_load_uri (DemoPlayer *player, gchar *uri); -void demo_player_play (DemoPlayer *player); -void demo_player_pause (DemoPlayer *player); -void demo_player_seek_by (DemoPlayer *player, gint seconds); -void demo_player_seek_to (DemoPlayer *player, gint second); -gint demo_player_get_position (DemoPlayer *player); -gint demo_player_get_duration (DemoPlayer *player); - -G_END_DECLS - -#endif /* __DEMO_PLAYER_H_INCLUDED_ */ |