src/gstaubiopitch.{c,h}: add first aubiopitch draft
authorPaul Brossier <piem@piem.org>
Wed, 26 Mar 2008 18:27:53 +0000 (19:27 +0100)
committerPaul Brossier <piem@piem.org>
Wed, 26 Mar 2008 18:27:53 +0000 (19:27 +0100)
src/Makefile.am
src/gstaubiopitch.c [new file with mode: 0644]
src/gstaubiopitch.h [new file with mode: 0644]
src/plugin.c

index c1b3248..6d83bb4 100644 (file)
@@ -16,6 +16,7 @@ plugin_LTLIBRARIES = libgstaubio.la
 # sources used to compile this plug-in
 libgstaubio_la_SOURCES = \
                gstaubiotempo.c \
+               gstaubiopitch.c \
                plugin.c
 
 # flags used to compile the aubio gst plugin
@@ -25,4 +26,6 @@ libgstaubio_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) $(GSTPB_BASE_LIBS) $(AUBIO_
 libgstaubio_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
 # headers we need but don't want installed
-noinst_HEADERS = gstaubiotempo.h
+noinst_HEADERS = \
+               gstaubiotempo.h \
+               gstaubiopitch.h
diff --git a/src/gstaubiopitch.c b/src/gstaubiopitch.c
new file mode 100644 (file)
index 0000000..7eaecd7
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+    Copyright (C) 2008 Paul Brossier <piem@piem.org>
+
+    This file is part of gst-aubio.
+
+    gst-aubio 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.
+
+    gst-aubio 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 gst-aubio.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+/**
+ * SECTION:element-aubiopitch
+ *
+ * <refsect2>
+ * Detects beats along an audio stream 
+ * <title>Example launch line</title>
+ * <para>
+ * <programlisting>
+ * gst-launch -v -m audiotestsrc ! aubiopitch ! fakesink silent=TRUE
+ * </programlisting>
+ * </para>
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gst/gst.h>
+#include <gst/audio/audio.h>
+
+#include "gstaubiopitch.h"
+
+static const GstElementDetails element_details = 
+GST_ELEMENT_DETAILS ("Aubio Pitch Analysis",
+  "Filter/Analyzer/Audio",
+  "Extract pitch using aubio",
+  "Paul Brossier <piem@aubio.org>");
+
+/* Filter signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum
+{
+  PROP_0,
+  PROP_SILENT
+};
+
+#define ALLOWED_CAPS \
+    "audio/x-raw-float,"                                              \
+    " width=(int)32,"                                                 \
+    " endianness=(int)BYTE_ORDER,"                                    \
+    " rate=(int)44100,"                                             \
+    " channels=(int)[1,MAX]"
+
+GST_BOILERPLATE (GstAubioPitch, gst_aubio_pitch, GstAudioFilter,
+    GST_TYPE_AUDIO_FILTER);
+
+static void gst_aubio_pitch_finalize (GObject * obj);
+static void gst_aubio_pitch_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec);
+static void gst_aubio_pitch_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec);
+
+static GstFlowReturn gst_aubio_pitch_transform_ip (GstBaseTransform * trans, GstBuffer * buf);
+
+/* GObject vmethod implementations */
+static void
+gst_aubio_pitch_base_init (gpointer gclass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
+
+  GstCaps *caps;
+
+  caps = gst_caps_from_string (ALLOWED_CAPS);
+
+  gst_audio_filter_class_add_pad_templates (GST_AUDIO_FILTER_CLASS (gclass),
+        caps);
+
+  gst_caps_unref (caps);
+
+  gst_element_class_set_details (element_class, &element_details);
+
+}
+
+/* initialize the plugin's class */
+static void
+gst_aubio_pitch_class_init (GstAubioPitchClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+  GstBaseTransformClass *trans_class = GST_BASE_TRANSFORM_CLASS (klass);
+  //GstAudioFilterClass *filter_class = GST_AUDIO_FILTER_CLASS (klass);
+
+  //trans_class->stop = GST_DEBUG_FUNCPTR (gst_aubio_pitch_stop);
+  //trans_class->event = GST_DEBUG_FUNCPTR (gst_aubio_pitch_event);
+  trans_class->transform_ip = GST_DEBUG_FUNCPTR (gst_aubio_pitch_transform_ip);
+  trans_class->passthrough_on_same_caps = TRUE;
+
+  gobject_class->finalize = gst_aubio_pitch_finalize;
+  gobject_class->set_property = gst_aubio_pitch_set_property;
+  gobject_class->get_property = gst_aubio_pitch_get_property;
+
+  g_object_class_install_property (gobject_class, PROP_SILENT,
+      g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
+          FALSE, G_PARAM_READWRITE));
+}
+
+static void
+gst_aubio_pitch_init (GstAubioPitch * filter,
+    GstAubioPitchClass * gclass)
+{
+
+  filter->silent = TRUE;
+
+  filter->type_pitch = aubio_pitch_yinfft;
+  filter->mode_pitch = aubio_pitchm_freq;
+
+  filter->buf_size = 2048;
+  filter->hop_size = 256;
+  filter->samplerate = 44100;
+  filter->channels = 1;
+
+  filter->ibuf = new_fvec(filter->hop_size, filter->channels);
+  filter->t = new_aubio_pitchdetection(filter->buf_size, filter->hop_size,
+      filter->channels, filter->samplerate, filter->type_pitch, filter->mode_pitch);
+  aubio_pitchdetection_set_yinthresh(filter->t, 0.7);
+}
+
+static void
+gst_aubio_pitch_finalize (GObject * obj)
+{
+  GstAubioPitch * aubio_pitch = GST_AUBIO_PITCH (obj);
+
+  if (aubio_pitch->t) {
+    del_aubio_pitchdetection(aubio_pitch->t);
+  }
+  if (aubio_pitch->ibuf) {
+    del_fvec(aubio_pitch->ibuf);
+  }
+
+  G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+gst_aubio_pitch_set_property (GObject * object, guint prop_id,
+    const GValue * value, GParamSpec * pspec)
+{
+  GstAubioPitch *filter = GST_AUBIO_PITCH (object);
+
+  switch (prop_id) {
+    case PROP_SILENT:
+      filter->silent = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_aubio_pitch_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
+{
+  GstAubioPitch *filter = GST_AUBIO_PITCH (object);
+
+  switch (prop_id) {
+    case PROP_SILENT:
+      g_value_set_boolean (value, filter->silent);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstFlowReturn
+gst_aubio_pitch_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
+{
+  uint j;
+  GstAubioPitch *filter = GST_AUBIO_PITCH (trans);
+  GstAudioFilter *audiofilter = GST_AUDIO_FILTER(trans);
+
+  gint nsamples = GST_BUFFER_SIZE (buf) / (4 * audiofilter->format.channels);
+
+  /* block loop */
+  for (j = 0; j < nsamples; j++) {
+    /* copy input to ibuf */
+    fvec_write_sample(filter->ibuf, ((smpl_t *) GST_BUFFER_DATA(buf))[j], 0,
+        filter->pos);
+
+    if (filter->pos == filter->hop_size - 1) {
+      smpl_t pitch = aubio_pitchdetection(filter->t, filter->ibuf);
+      gint64 now = GST_BUFFER_TIMESTAMP (buf);
+      // correction of inside buffer time
+      now += GST_FRAMES_TO_CLOCK_TIME(j, audiofilter->format.rate);
+      if (filter->silent == FALSE) {
+        g_print ("pitch: %4.3f \t%" GST_TIME_FORMAT "\n", pitch, GST_TIME_ARGS(now));
+      }
+
+      filter->pos = -1; /* so it will be zero next j loop */
+    }
+    filter->pos++;
+  }
+
+  return GST_FLOW_OK;
+}
diff --git a/src/gstaubiopitch.h b/src/gstaubiopitch.h
new file mode 100644 (file)
index 0000000..3cc5c37
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+    Copyright (C) 2008 Paul Brossier <piem@piem.org>
+
+    This file is part of gst-aubio.
+
+    gst-aubio 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.
+
+    gst-aubio 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 gst-aubio.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef __GST_AUBIO_PITCH_H__
+#define __GST_AUBIO_PITCH_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstbasetransform.h>
+#include <gst/audio/gstaudiofilter.h>
+
+#include <aubio/aubio.h>
+
+G_BEGIN_DECLS
+
+/* #defines don't like whitespacey bits */
+#define GST_TYPE_AUBIO_PITCH \
+  (gst_aubio_pitch_get_type())
+#define GST_AUBIO_PITCH(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_AUBIO_PITCH,GstAubioPitch))
+#define GST_IS_AUBIO_PITCH(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_AUBIO_PITCH))
+#define GST_AUBIO_PITCH_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_AUBIO_PITCH,GstAubioPitchClass))
+#define GST_IS_AUBIO_PITCH_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_AUBIO_PITCH))
+#define GST_AUBIO_PITCH_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_AUBIO_PITCH, GstAubioPitchClass))
+
+typedef struct _GstAubioPitch      GstAubioPitch;
+typedef struct _GstAubioPitchClass GstAubioPitchClass;
+
+struct _GstAubioPitch
+{
+  GstAudioFilter element;
+
+  GstPad *sinkpad, *srcpad;
+
+  gboolean silent;
+
+  aubio_pitchdetection_t * t;
+  fvec_t * ibuf;
+
+  uint buf_size;
+  uint hop_size;
+  uint channels;
+  uint samplerate;
+  uint pos;
+
+  aubio_pitchdetection_type type_pitch;
+  aubio_pitchdetection_mode mode_pitch;
+
+};
+
+struct _GstAubioPitchClass 
+{
+  GstAudioFilterClass parent_class;
+};
+
+GType gst_aubio_pitch_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_AUBIO_PITCH_H__ */
index d767e07..fbc43e4 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <gst/gst.h>
 #include "gstaubiotempo.h"
+#include "gstaubiopitch.h"
 
 #define GST_CAT_DEFAULT gst_aubiotempo_debug
 GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
@@ -32,7 +33,9 @@ plugin_init (GstPlugin * plugin)
       0, "Aubiotempo plugin");
 
   return gst_element_register (plugin, "aubiotempo",
-      GST_RANK_NONE, GST_TYPE_AUBIOTEMPO);
+      GST_RANK_NONE, GST_TYPE_AUBIOTEMPO)
+      && gst_element_register (plugin, "aubiopitch",
+      GST_RANK_NONE, GST_TYPE_AUBIO_PITCH);
 }
 
 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,