Initial revision
authorAndy Wingo <wingo@pobox.com>
Sat, 22 Dec 2001 23:21:55 +0000 (23:21 +0000)
committerAndy Wingo <wingo@pobox.com>
Sat, 22 Dec 2001 23:21:55 +0000 (23:21 +0000)
Original commit message from CVS:
Initial revision

gst/audioscale/.gitignore [new file with mode: 0644]
gst/audioscale/Makefile.am [new file with mode: 0644]
gst/audioscale/gstaudioscale.c [new file with mode: 0644]
gst/audioscale/gstaudioscale.h [new file with mode: 0644]

diff --git a/gst/audioscale/.gitignore b/gst/audioscale/.gitignore
new file mode 100644 (file)
index 0000000..08f5ed3
--- /dev/null
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
diff --git a/gst/audioscale/Makefile.am b/gst/audioscale/Makefile.am
new file mode 100644 (file)
index 0000000..a6cde7a
--- /dev/null
@@ -0,0 +1,12 @@
+
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstaudioscale.la
+
+libgstaudioscale_la_SOURCES = gstaudioscale.c
+libgstaudioscale_la_LIBADD = $(top_builddir)/libs/resample/libresample.la
+libgstaudioscale_la_CFLAGS = -ffast-math $(GST_CFLAGS)
+
+noinst_HEADERS = gstaudioscale.h
+
+
diff --git a/gst/audioscale/gstaudioscale.c b/gst/audioscale/gstaudioscale.c
new file mode 100644 (file)
index 0000000..6f38b7d
--- /dev/null
@@ -0,0 +1,359 @@
+/* Gnome-Streamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#include <string.h>
+#include <math.h>
+
+//#define DEBUG_ENABLED
+#include <gstaudioscale.h>
+#include <libs/audio/gstaudio.h>
+#include <libs/resample/resample.h>
+
+/* elementfactory information */
+static GstElementDetails audioscale_details = {
+  "Audio scaler",
+  "Filter/Audio/Scaler",
+  "Resizes audio",
+  VERSION,
+  "Wim Taymans <wim.taymans@chello.be>",
+  "(C) 2000",
+};
+
+/* Audioscale signals and args */
+enum {
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_FREQUENCY,
+  ARG_FILTERLEN,
+  ARG_METHOD,
+  /* FILL ME */
+};
+
+static GstPadTemplate *
+sink_template (void)
+{
+  static GstPadTemplate *template = NULL;
+
+  if (!template) {
+    template = gst_padtemplate_new ("sink",
+                                   GST_PAD_SINK,
+                                   GST_PAD_ALWAYS,
+                                   gst_caps_new
+                                   ("audioscale_sink",
+                                    "audio/raw", GST_AUDIO_INT_PAD_TEMPLATE_PROPS), NULL);
+  }
+  return template;
+}
+
+static GstPadTemplate *
+src_template (void)
+{
+  static GstPadTemplate *template = NULL;
+
+  if (!template) {
+    template = gst_padtemplate_new ("src",
+                                   GST_PAD_SRC,
+                                   GST_PAD_ALWAYS,
+                                   gst_caps_new
+                                   ("audioscale_src",
+                                    "audio/raw", GST_AUDIO_INT_PAD_TEMPLATE_PROPS), NULL);
+  }
+  return template;
+}
+
+#define GST_TYPE_AUDIOSCALE_METHOD (gst_audioscale_method_get_type())
+static GType
+gst_audioscale_method_get_type (void)
+{
+  static GType audioscale_method_type = 0;
+  static GEnumValue audioscale_methods[] = {
+    { GST_AUDIOSCALE_NEAREST,  "0", "Nearest" },
+    { GST_AUDIOSCALE_BILINEAR, "1", "Bilinear" },
+    { GST_AUDIOSCALE_SINC,     "2", "Sinc" },
+    { 0, NULL, NULL },
+  };
+  if(!audioscale_method_type){
+    audioscale_method_type = g_enum_register_static("GstAudioscaleMethod",
+                   audioscale_methods);
+  }
+  return audioscale_method_type;
+}
+
+static void    gst_audioscale_class_init       (AudioscaleClass *klass);
+static void    gst_audioscale_init             (Audioscale *audioscale);
+
+static void    gst_audioscale_chain            (GstPad *pad, GstBuffer *buf);
+
+static void gst_audioscale_set_property (GObject * object, guint prop_id,
+                                        const GValue * value, GParamSpec * pspec);
+static void gst_audioscale_get_property (GObject * object, guint prop_id,
+                                        GValue * value, GParamSpec * pspec);
+
+static GstElementClass *parent_class = NULL;
+
+//static guint gst_audioscale_signals[LAST_SIGNAL] = { 0 };
+
+GType
+audioscale_get_type (void)
+{
+  static GType audioscale_type = 0;
+
+  if (!audioscale_type) {
+    static const GTypeInfo audioscale_info = {
+      sizeof(AudioscaleClass),      NULL,
+      NULL,
+      (GClassInitFunc)gst_audioscale_class_init,
+      NULL,
+      NULL,
+      sizeof(Audioscale),
+      0,
+      (GInstanceInitFunc)gst_audioscale_init,
+    };
+    audioscale_type = g_type_register_static(GST_TYPE_ELEMENT, "Audioscale", &audioscale_info, 0);
+  }
+  return audioscale_type;
+}
+
+static void
+gst_audioscale_class_init (AudioscaleClass *klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass*)klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FREQUENCY,
+    g_param_spec_int("frequency","frequency","frequency",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILTERLEN,
+       g_param_spec_int ("filter_length", "filter_length", "filter_length",
+               G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));     // CHECKME
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_METHOD,
+       g_param_spec_int ("method", "method", "method",
+               G_MININT, G_MAXINT, 0, G_PARAM_READWRITE));     // CHECKME
+
+  parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+  gobject_class->set_property = gst_audioscale_set_property;
+  gobject_class->get_property = gst_audioscale_get_property;
+
+}
+
+static GstPadNegotiateReturn
+audioscale_negotiate_src (GstPad * pad, GstCaps ** caps, gpointer * data)
+{
+  Audioscale *audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad));
+
+  g_print ("audioscale_negotiate_src\n");
+
+  if (*caps == NULL)
+    return GST_PAD_NEGOTIATE_FAIL;
+
+  *caps = gst_caps_copy_on_write (*caps);
+  gst_caps_set (*caps, "rate", GST_PROPS_INT_RANGE (8000, 48000));
+
+  return gst_pad_negotiate_proxy (pad, audioscale->sinkpad, caps);
+}
+
+static GstPadNegotiateReturn
+audioscale_negotiate_sink (GstPad * pad, GstCaps ** caps, gpointer * data)
+{
+  Audioscale *audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad));
+
+  g_print ("audioscale_negotiate_sink\n");
+
+  if (*caps == NULL)
+    return GST_PAD_NEGOTIATE_FAIL;
+
+  *caps = gst_caps_copy_on_write (*caps);
+  gst_caps_set (*caps, "rate", GST_PROPS_INT (audioscale->targetfrequency));
+
+  return gst_pad_negotiate_proxy (pad, audioscale->srcpad, caps);
+}
+
+static void
+gst_audioscale_newcaps (GstPad * pad, GstCaps * caps)
+{
+  Audioscale *audioscale;
+  resample_t *r;
+
+  audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad));
+  r = audioscale->resample;
+
+  r->i_rate = gst_caps_get_int (caps, "rate");
+  r->channels = gst_caps_get_int (caps, "channels");
+  
+  resample_reinit(r);
+  //g_print("audioscale: unsupported scaling method %d\n", audioscale->method);
+  
+}
+
+static void *
+gst_audioscale_get_buffer (void *priv, unsigned int size)
+{
+  Audioscale * audioscale = priv;
+
+  audioscale->outbuf = gst_buffer_new();
+  GST_BUFFER_SIZE(audioscale->outbuf) = size;
+  GST_BUFFER_DATA(audioscale->outbuf) = g_malloc(size);
+
+  return GST_BUFFER_DATA(audioscale->outbuf);
+}
+
+static void
+gst_audioscale_init (Audioscale *audioscale)
+{
+  resample_t *r;
+
+  audioscale->sinkpad = gst_pad_new_from_template (GST_PADTEMPLATE_GET (sink_template), "sink");
+  gst_pad_set_negotiate_function (audioscale->sinkpad, audioscale_negotiate_sink);
+  gst_element_add_pad(GST_ELEMENT(audioscale),audioscale->sinkpad);
+  gst_pad_set_chain_function(audioscale->sinkpad,gst_audioscale_chain);
+  gst_pad_set_newcaps_function (audioscale->sinkpad, gst_audioscale_newcaps);
+
+  audioscale->srcpad = gst_pad_new_from_template (GST_PADTEMPLATE_GET (src_template), "src");
+  gst_pad_set_negotiate_function (audioscale->srcpad, audioscale_negotiate_src);
+
+  gst_element_add_pad(GST_ELEMENT(audioscale),audioscale->srcpad);
+
+  r = g_new0(resample_t,1);
+  audioscale->resample = r;
+
+  r->priv = audioscale;
+  r->get_buffer = gst_audioscale_get_buffer;
+  r->method = RESAMPLE_SINC;
+  r->channels = 0;
+  r->filter_length = 16;
+  r->i_rate = -1;
+  r->o_rate = -1;
+  //r->verbose = 1;
+
+  resample_init(r);
+}
+
+static void
+gst_audioscale_chain (GstPad *pad, GstBuffer *buf)
+{
+  Audioscale *audioscale;
+  guchar *data;
+  gulong size;
+
+  g_return_if_fail(pad != NULL);
+  g_return_if_fail(GST_IS_PAD(pad));
+  g_return_if_fail(buf != NULL);
+
+  audioscale = GST_AUDIOSCALE (gst_pad_get_parent (pad));
+  data = GST_BUFFER_DATA(buf);
+  size = GST_BUFFER_SIZE(buf);
+
+  GST_DEBUG (0,
+            "gst_audioscale_chain: got buffer of %ld bytes in '%s'\n",
+            size, gst_element_get_name (GST_ELEMENT (audioscale)));
+
+
+  resample_scale (audioscale->resample, data, size);
+
+  gst_pad_push (audioscale->srcpad, audioscale->outbuf);
+
+  gst_buffer_unref (buf);
+}
+
+static void
+gst_audioscale_set_property (GObject * object, guint prop_id,
+                            const GValue * value, GParamSpec * pspec)
+{
+  Audioscale *src;
+  resample_t *r;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail(GST_IS_AUDIOSCALE(object));
+  src = GST_AUDIOSCALE(object);
+  r = src->resample;
+
+  switch (prop_id) {
+    case ARG_FREQUENCY:
+      src->targetfrequency = g_value_get_int (value);
+      r->o_rate = src->targetfrequency;
+      break;
+    case ARG_FILTERLEN:
+      r->filter_length = g_value_get_int (value);
+      g_print ("new filter length %d\n", r->filter_length);
+      break;
+    case ARG_METHOD:
+      r->method = g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_audioscale_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+  Audioscale *src;
+  resample_t *r;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail(GST_IS_AUDIOSCALE(object));
+  src = GST_AUDIOSCALE(object);
+  r = src->resample;
+
+  switch (prop_id) {
+    case ARG_FREQUENCY:
+      g_value_set_int (value, src->targetfrequency);
+      break;
+    case ARG_FILTERLEN:
+      g_value_set_int (value, r->filter_length);
+      break;
+    case ARG_METHOD:
+      g_value_set_int (value, r->method);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+  GstElementFactory *factory;
+
+  /* create an elementfactory for the audioscale element */
+  factory = gst_elementfactory_new ("audioscale", GST_TYPE_AUDIOSCALE, &audioscale_details);
+  g_return_val_if_fail(factory != NULL, FALSE);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+  return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "audioscale",
+  plugin_init
+};
diff --git a/gst/audioscale/gstaudioscale.h b/gst/audioscale/gstaudioscale.h
new file mode 100644 (file)
index 0000000..2017b03
--- /dev/null
@@ -0,0 +1,84 @@
+/* Gnome-Streamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __AUDIOSCALE_H__
+#define __AUDIOSCALE_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+#include <libs/resample/resample.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GST_TYPE_AUDIOSCALE \
+  (audioscale_get_type())
+#define GST_AUDIOSCALE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AUDIOSCALE,Audioscale))
+#define GST_AUDIOSCALE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOSCALE,Audioscale))
+#define GST_IS_AUDIOSCALE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AUDIOSCALE))
+#define GST_IS_AUDIOSCALE_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSCALE))
+
+typedef enum {
+  GST_AUDIOSCALE_NEAREST,
+  GST_AUDIOSCALE_BILINEAR,
+  GST_AUDIOSCALE_SINC,
+} GstAudioScaleMethod;
+
+typedef struct _Audioscale Audioscale;
+typedef struct _AudioscaleClass AudioscaleClass;
+
+struct _Audioscale {
+  GstElement element;
+
+  GstPad *sinkpad,*srcpad;
+
+  // audio state
+  gint format;
+  gint channels;
+  gint frequency;
+  gint targetfrequency;
+
+  resample_t *resample;
+
+  GstBuffer *outbuf;
+};
+
+struct _AudioscaleClass {
+  GstElementClass parent_class;
+};
+
+GType gst_audioscale_get_type(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __AUDIOSCALE_H__ */