From: Paul Brossier Date: Wed, 26 Mar 2008 18:27:53 +0000 (+0100) Subject: src/gstaubiopitch.{c,h}: add first aubiopitch draft X-Git-Tag: 0.10.0.1~12 X-Git-Url: https://git.aubio.org/?a=commitdiff_plain;h=4b2202093b3818b0e1bb4dd5a3f12acfccdf659a;p=gst-aubio.git src/gstaubiopitch.{c,h}: add first aubiopitch draft --- diff --git a/src/Makefile.am b/src/Makefile.am index c1b3248..6d83bb4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 0000000..7eaecd7 --- /dev/null +++ b/src/gstaubiopitch.c @@ -0,0 +1,220 @@ +/* + Copyright (C) 2008 Paul Brossier + + 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 . + +*/ + +/** + * SECTION:element-aubiopitch + * + * + * Detects beats along an audio stream + * Example launch line + * + * + * gst-launch -v -m audiotestsrc ! aubiopitch ! fakesink silent=TRUE + * + * + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "gstaubiopitch.h" + +static const GstElementDetails element_details = +GST_ELEMENT_DETAILS ("Aubio Pitch Analysis", + "Filter/Analyzer/Audio", + "Extract pitch using aubio", + "Paul Brossier "); + +/* 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 index 0000000..3cc5c37 --- /dev/null +++ b/src/gstaubiopitch.h @@ -0,0 +1,81 @@ +/* + + Copyright (C) 2008 Paul Brossier + + 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 . + +*/ + +#ifndef __GST_AUBIO_PITCH_H__ +#define __GST_AUBIO_PITCH_H__ + +#include +#include +#include + +#include + +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__ */ diff --git a/src/plugin.c b/src/plugin.c index d767e07..fbc43e4 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -21,6 +21,7 @@ #include #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,