chromaprint: import Acoustid audio fingerprinting plugin

Imported from https://launchpad.net/gst-chromaprint
This commit is contained in:
Lukáš Lalinský 2011-01-02 19:34:04 +00:00 committed by Tim-Philipp Müller
parent 27354f065d
commit f3c812e062
5 changed files with 440 additions and 0 deletions

View file

@ -732,6 +732,16 @@ AG_GST_CHECK_FEATURE(CELT, [celt], celt, [
AC_SUBST(CELT_LIBS)
])
dnl *** chromaprint ***
translit(dnm, m, l) AM_CONDITIONAL(USE_CHROMAPRINT, true)
AG_GST_CHECK_FEATURE(CHROMAPRINT, [chromaprint], chromaprint, [
PKG_CHECK_MODULES(CHROMAPRINT, libchromaprint, HAVE_CHROMAPRINT="yes", [
HAVE_CHROMAPRINT="no"
])
AC_SUBST(CHROMAPRINT_CFLAGS)
AC_SUBST(CHROMAPRINT_LIBS)
])
dnl *** Cog ***
translit(dnm, m, l) AM_CONDITIONAL(USE_COG, true)
AG_GST_CHECK_FEATURE(COG, [Cog plugin], cog, [
@ -1777,6 +1787,7 @@ AM_CONDITIONAL(USE_APEXSINK, false)
AM_CONDITIONAL(USE_BZ2, false)
AM_CONDITIONAL(USE_CDAUDIO, false)
AM_CONDITIONAL(USE_CELT, false)
AM_CONDITIONAL(USE_CHROMAPRINT, false)
AM_CONDITIONAL(USE_COG, false)
AM_CONDITIONAL(USE_CURL, false)
AM_CONDITIONAL(USE_DC1394, false)
@ -2034,6 +2045,7 @@ ext/apexsink/Makefile
ext/bz2/Makefile
ext/cdaudio/Makefile
ext/celt/Makefile
ext/chromaprint/Makefile
ext/cog/Makefile
ext/curl/Makefile
ext/dc1394/Makefile

View file

@ -58,6 +58,12 @@ else
CELT_DIR=
endif
if USE_CHROMAPRINT
CHROMAPRINT_DIR=chromaprint
else
CHROMAPRINT_DIR=
endif
if USE_COG
COG_DIR=cog
else
@ -397,6 +403,7 @@ SUBDIRS=\
$(BZ2_DIR) \
$(CDAUDIO_DIR) \
$(CELT_DIR) \
$(CHROMAPRINT_DIR) \
$(COG_DIR) \
$(CURL_DIR) \
$(DC1394_DIR) \
@ -456,6 +463,7 @@ DIST_SUBDIRS = \
bz2 \
cdaudio \
celt \
chromaprint \
cog \
curl \
dc1394 \

View file

@ -0,0 +1,14 @@
plugin_LTLIBRARIES = libgstchromaprint.la
libgstchromaprint_la_SOURCES = gstchromaprint.c gstchromaprint.h
libgstchromaprint_la_CFLAGS = $(GST_PLUGINS_BAD_CFLAGS) \
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
$(CHROMAPRINT_CFLAGS)
libgstchromaprint_la_LIBADD = \
$(GST_PLUGINS_BASE_LIBS) -lgstaudio-$(GST_MAJORMINOR) $(GST_LIBS) \
$(CHROMAPRINT_LIBS)
libgstchromaprint_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstchromaprint_la_LIBTOOLFLAGS = --tag=disable-static
noinst_HEADERS = gstchromaprint.h

View file

@ -0,0 +1,322 @@
/* vim:si:et:sw=2:sts=2:ts=8
*
* GStreamer
*
* gstchromaprint.c
*
* Copyright (C) 2006 M. Derezynski
* Copyright (C) 2008 Eric Buehl
* Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
* Copyright (C) 2011 Lukáš Lalinský <lalinsky@gmail.com>
*
* 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.
*/
/**
* SECTION:element-chromaprint
*
* FIXME:Describe chromaprint here.
*
* <refsect2>
* <title>Example launch line</title>
* |[
* gst-launch -v -m fakesrc ! chromaprint ! fakesink silent=TRUE
* filesrc location=<file> ! decodebin ! audioconvert ! chromaprint ! fakesink sync=0 silent=TRUE
* ]|
* </refsect2>
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <gst/gst.h>
#include <chromaprint.h>
#include "gstchromaprint.h"
#define DEFAULT_MAX_DURATION 120
#define PAD_CAPS \
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, 2 ], " \
"endianness = (int) { BYTE_ORDER }, " \
"width = (int) { 16 }, " \
"depth = (int) { 16 }, " \
"signed = (boolean) true"
GST_DEBUG_CATEGORY_STATIC (gst_chromaprint_debug);
#define GST_CAT_DEFAULT gst_chromaprint_debug
enum
{
PROP_0,
PROP_FINGERPRINT,
PROP_MAX_DURATION
};
GST_BOILERPLATE (GstChromaprint, gst_chromaprint, GstElement,
GST_TYPE_AUDIO_FILTER);
static void gst_chromaprint_finalize (GObject * object);
static void gst_chromaprint_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_chromaprint_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static GstFlowReturn gst_chromaprint_transform_ip (GstBaseTransform * trans,
GstBuffer * buf);
static gboolean gst_chromaprint_event (GstBaseTransform * trans,
GstEvent * event);
/* GObject vmethod implementations */
static void
gst_chromaprint_base_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
GstAudioFilterClass *audio_filter_class = (GstAudioFilterClass *) g_class;
GstCaps *caps;
gst_element_class_set_details_simple (element_class,
"Chromaprint",
"Chromaprint fingerprinting element",
"Find an audio fingerprint using the Chromaprint library",
"Lukáš Lalinský <lalinsky@gmail.com>");
caps = gst_caps_from_string (PAD_CAPS);
gst_audio_filter_class_add_pad_templates (audio_filter_class, caps);
gst_caps_unref (caps);
}
static void
gst_chromaprint_class_init (GstChromaprintClass * klass)
{
GObjectClass *gobject_class;
GstBaseTransformClass *gstbasetrans_class;
gobject_class = G_OBJECT_CLASS (klass);
gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
gobject_class->set_property =
GST_DEBUG_FUNCPTR (gst_chromaprint_set_property);
gobject_class->get_property =
GST_DEBUG_FUNCPTR (gst_chromaprint_get_property);
g_object_class_install_property (gobject_class, PROP_FINGERPRINT,
g_param_spec_string ("fingerprint", "Resulting fingerprint",
"Resulting fingerprint", NULL, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_MAX_DURATION,
g_param_spec_uint ("duration", "Duration limit",
"Number of seconds of audio to use for fingerpriting",
0, G_MAXUINT, DEFAULT_MAX_DURATION,
G_PARAM_READABLE | G_PARAM_WRITABLE));
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_chromaprint_finalize);
gstbasetrans_class->transform_ip =
GST_DEBUG_FUNCPTR (gst_chromaprint_transform_ip);
gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_chromaprint_event);
gstbasetrans_class->passthrough_on_same_caps = TRUE;
}
static void
gst_chromaprint_reset (GstChromaprint * chromaprint)
{
if (chromaprint->fingerprint) {
chromaprint_dealloc (chromaprint->fingerprint);
chromaprint->fingerprint = NULL;
}
chromaprint->nsamples = 0;
chromaprint->duration = 0;
chromaprint->record = TRUE;
}
static void
gst_chromaprint_create_fingerprint (GstChromaprint * chromaprint)
{
GstTagList *tags;
if (chromaprint->duration <= 3)
return;
GST_DEBUG ("Generating fingerprint based on %d seconds of audio",
chromaprint->duration);
chromaprint_finish (chromaprint->context);
chromaprint_get_fingerprint (chromaprint->context, &chromaprint->fingerprint);
chromaprint->record = FALSE;
tags = gst_tag_list_new ();
gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE,
GST_TAG_CHROMAPRINT_FINGERPRINT, chromaprint->fingerprint, NULL);
gst_element_found_tags (GST_ELEMENT (chromaprint), tags);
}
static void
gst_chromaprint_init (GstChromaprint * chromaprint,
GstChromaprintClass * gclass)
{
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (chromaprint), TRUE);
chromaprint->context = chromaprint_new (CHROMAPRINT_ALGORITHM_DEFAULT);
chromaprint->fingerprint = NULL;
chromaprint->max_duration = DEFAULT_MAX_DURATION;
gst_chromaprint_reset (chromaprint);
}
static void
gst_chromaprint_finalize (GObject * object)
{
GstChromaprint *chromaprint = GST_CHROMAPRINT (object);
chromaprint->record = FALSE;
if (chromaprint->context) {
chromaprint_free (chromaprint->context);
chromaprint->context = NULL;
}
if (chromaprint->fingerprint) {
chromaprint_dealloc (chromaprint->fingerprint);
chromaprint->fingerprint = NULL;
}
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GstFlowReturn
gst_chromaprint_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
{
GstChromaprint *chromaprint = GST_CHROMAPRINT (trans);
guint nsamples;
gint rate = GST_AUDIO_FILTER (chromaprint)->format.rate;
gint channels = GST_AUDIO_FILTER (chromaprint)->format.channels;
g_return_val_if_fail (rate > 0 && channels > 0, GST_FLOW_NOT_NEGOTIATED);
if (!chromaprint->record)
return GST_FLOW_OK;
nsamples = GST_BUFFER_SIZE (buf) / (channels * 2);
if (!nsamples)
return GST_FLOW_OK;
if (!chromaprint->nsamples) {
chromaprint_start (chromaprint->context, rate, channels);
}
chromaprint->nsamples += nsamples;
chromaprint->duration = chromaprint->nsamples / rate;
chromaprint_feed (chromaprint->context, GST_BUFFER_DATA (buf),
GST_BUFFER_SIZE (buf) / 2);
if (chromaprint->duration >= chromaprint->max_duration
&& !chromaprint->fingerprint) {
gst_chromaprint_create_fingerprint (chromaprint);
}
return GST_FLOW_OK;
}
static gboolean
gst_chromaprint_event (GstBaseTransform * trans, GstEvent * event)
{
GstChromaprint *chromaprint = GST_CHROMAPRINT (trans);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_STOP:
case GST_EVENT_NEWSEGMENT:
GST_DEBUG ("Got %s event, clearing buffer", GST_EVENT_TYPE_NAME (event));
gst_chromaprint_reset (chromaprint);
break;
case GST_EVENT_EOS:
if (!chromaprint->fingerprint) {
gst_chromaprint_create_fingerprint (chromaprint);
}
break;
default:
break;
}
return TRUE;
}
static void
gst_chromaprint_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstChromaprint *chromaprint = GST_CHROMAPRINT (object);
switch (prop_id) {
case PROP_MAX_DURATION:
chromaprint->max_duration = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_chromaprint_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstChromaprint *chromaprint = GST_CHROMAPRINT (object);
switch (prop_id) {
case PROP_FINGERPRINT:
g_value_set_string (value, chromaprint->fingerprint);
break;
case PROP_MAX_DURATION:
g_value_set_uint (value, chromaprint->max_duration);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
plugin_init (GstPlugin * plugin)
{
gboolean ret;
GST_DEBUG_CATEGORY_INIT (gst_chromaprint_debug, "chromaprint",
0, "chromaprint element");
GST_DEBUG ("libchromaprint %s", chromaprint_get_version ());
ret = gst_element_register (plugin, "chromaprint", GST_RANK_NONE,
GST_TYPE_CHROMAPRINT);
if (ret) {
gst_tag_register (GST_TAG_CHROMAPRINT_FINGERPRINT, GST_TAG_FLAG_META,
G_TYPE_STRING, "chromaprint fingerprint", "Chromaprint fingerprint",
NULL);
}
return ret;
}
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"chromaprint",
"Calculate Chromaprint fingerprint from audio files",
plugin_init, VERSION, "LGPL", "GStreamer", "http://gstreamer.net/")

View file

@ -0,0 +1,84 @@
/* vim:si:et:sw=2:sts=2:ts=8
*
* GStreamer
*
* gstchromaprint.h
*
* Copyright (C) 2006 M. Derezynski
* Copyright (C) 2008 Eric Buehl
* Copyright (C) 2008 Sebastian Dröge <slomo@circular-chaos.org>
* Copyright (C) 2011 Lukáš Lalinský <<user@hostname.org>>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_CHROMAPRINT_H__
#define __GST_CHROMAPRINT_H__
#include <gst/gst.h>
#include <gst/base/gstadapter.h>
#include <gst/audio/gstaudiofilter.h>
#include <gst/audio/audio.h>
#include <chromaprint.h>
G_BEGIN_DECLS
#define GST_TYPE_CHROMAPRINT \
(gst_chromaprint_get_type())
#define GST_CHROMAPRINT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CHROMAPRINT,GstChromaprint))
#define GST_CHROMAPRINT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CHROMAPRINT,GstChromaprintClass))
#define GST_IS_CHROMAPRINT(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CHROMAPRINT))
#define GST_IS_CHROMAPRINT_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CHROMAPRINT))
#define GST_TAG_CHROMAPRINT_FINGERPRINT "chromaprint-fingerprint"
typedef struct _GstChromaprint GstChromaprint;
typedef struct _GstChromaprintClass GstChromaprintClass;
/**
* GstChromaprint:
*
* Opaque #GstChromaprint data structure
*/
struct _GstChromaprint
{
GstAudioFilter element;
/*< private > */
ChromaprintContext *context;
char *fingerprint;
gboolean record;
guint64 nsamples;
guint duration;
guint max_duration;
};
struct _GstChromaprintClass
{
GstAudioFilterClass parent_class;
};
GType gst_chromaprint_get_type (void);
G_END_DECLS
#endif /* __GST_CHROMAPRINT_H__ */